###### tags: `計算智慧與規劃` `期末專題` # 期末專題 :::success 探討各個產業的收盤價對空汙的影響 **數據:** 類別8個:油店燃氣、鋼鐵、運輸、化學、塑膠、光電、電器、汽車 從類別裡面選(前20名最高年收盤平均價),選出20家公司後每天加總再平均當作那個產業的收盤價 ::: :::info - 用2019其中一個鄉鎮的PM2.5預測出的最佳結果的方式,然後再預測別的縣市是不是也能用這個方式找出最佳解,看看空汙有沒有適合的方法(天擇,初代數量) - 高雄的鄉鎮來做 - (暫定用楠梓當作我們的基準) ::: - [環保署-空汙歷年監測資料](https://airtw.epa.gov.tw/CHT/Query/His_Data.aspx) ### PPT [這](https://docs.google.com/presentation/d/1z6750i8zdF-BxOZcXKrK9a3Wh2R2XLncYRQi5-0Jl_8/edit#slide=id.ge1a8e8ac24_2_630) ## 舊主題 - 有全台灣的 2018~2020 每日每小時的氣象資料 - 選 5 個地區:台北、桃園、彰化、高雄、花東 - 用後 4 個縣市的 pm2.5,去預測臺北的 pm2.5 - 用 GA 找出影響權重 ## 資料處理細節 - 楠梓、鳳山、美濃、仁武 - 寫程式看少哪一天,補上年平均的值 - 年平均的值先計算每一個小時的各個年平均 -> 所以會有24個年平均 - 有問題的格子: # 、 *、DIV/0、空的、NA 刪除 - 步驟 - 5 個縣市裡面,有很多個鄉鎮,針對每一個鄉鎮分開做資料處理 -> 如果鄉鎮有空值或是亂數用鄉鎮的年平均填入 - 算鄉鎮 24 小時各個的年平均 - 掃描整份資料,如果有缺值就填入那個小時的年平均 > 例如 楠梓 2020/4/5 14:00 有缺,填入楠梓2020年 14:00 的年平均 - 正規化 - 資料順序 => 時間, TEMP, CO, NO, NO2, NOx, O3, PM10, SO2, RainFall, RH, PM2.5 ## 新主題 - 單一個鄉鎮的空汙用GA得出權重,再拿權重去計算 ## GA - 語言:C# - 使用學姊程式碼中的 GaRosenbrock_Gbest (會印出最好的答案,和染色體的樣子) ### 基因設定 - 基因:其他每個縣市對台北 pm2.5 影響的權重 - 1 組染色體有 4 個基因 - 編碼:實數 - 限制式 (上下界) : 0 <= w <= 7 ### 步驟 1. 產生初代 : 隨機亂數 - (初代數量)N : 10、100 :+1:、500、1000 - 有空的人去找初代數量要設多少比較適合 2. 算分方式 : - 帶入基因的權重,跟正確答案的pm2.5比較,其差值愈小愈好 隨機取100個訓練集資料 #- 線性內插 :+1: #- fitness sharing - 多做幾次 - 限制式算分 : 先用Special gennetic operators:一開使不產生限制是以外的數值,若是不如預期用Penalty Function:超出限制是用扣分的方式減他的分數 3. 天擇 : ==(1)== - 輪盤 - Tournam ent selection #- Expected-value #- Deterministic sampling #- Remainder stochastic with replacement X #- Remainder Stochastic without replacement 4. 交配用 : Arithmetical Crossover - 交配率 : 0.8 6. 突變 : Gaussian mutation 或 uniform mutation ==(3)== - Gaussian - Uniform - Non-uniform - 突變率 : 0.01 或是不做 :::success 做表格來紀錄各種組合的結果 一組做 10 次 ::: :::warning 問問題 1. 田口正交 - 列出變因 2. 線性內插 3. 怎麼決定結果 (表格) 好壞 4. 突變可以不要嗎 5. shekIM 6. 交配率、突變率怎麼設 ::: ### 期末報告 1. 動機 - 觀察到同一個縣市裡面的測站,PM2.5的走勢有極高的相似度,想看看它有什麼規律可循(?) - 本來想找公用公式,但經討論改變,絕定來探討參數改變造成的影響, 試試看各種方式(組合)來看結果最好的組合是哪一個 3. 探討題目 - 觀察參數改變會對結果造成甚麼影響 5. 預期結果 - 猜測哪一個組合,會不會適合高雄地區的每一個測站 - 天擇:輪盤 交配:Arithmetical Crossover 突變:高斯 - PM2.5變化很細微,如果用uniform可能會破壞(忽視掉)PM2.5的細微變化,所以我們認為用高斯可能會好一些 6. 使用工具 - Libarery GA 基因演算法 - 修改初始化和fitness 8. 收集的資料 - 2018~2019高雄市各個測站監測到的資料(SO2、NO、NO2、PM2.5....) - 截圖網站畫面 9. 前資料處理 - 11. 演算法設計 - 基因設定 - 不變的變數: 執行次數等等 - 要變的變數: 突變、天擇、取多少訓練集 - 設計fitness function 1. 得出權重後,各個權重 * 隨機亂數取的2019年其中幾筆數據資料=分數 2. 第一個步驟重複做5次,選出一個最小的 - 利用24種組合測是最佳的權重 12. 實驗方法 - 用正規畫的資料 14. 實驗結果 - 如果實驗結果不好哪一個效果可能比較好 16. 結論 17. 資料來源 - [歷年空氣監測資料](https://airtw.epa.gov.tw/CHT/Query/His_Data.aspx) ### 簡報 #### 研究動機 - 用其中一個鄉鎮的PM2.5預測出的最佳結果的方式,然後再預測別的縣市 #### 文獻 #### 資料蒐集 - 資料處理 #### 實驗 #### 結果 #### 其它 - 可以做同縣市的鄉鎮預測 ## 程式碼 [GA 程式碼](/NOGHEuLhSeimAARBFAM6Nw) [處理資料程式碼](/oqHdGc9YQO6DvSy6QGhFlw) [計算結果程式碼](/CwSfmvzgRQyn1TT2W0bocg) [推測某年 PM2.5 程式](/PWgzjeD_SreUJ_F9cxK8fA) ### 我們的GA ```csharp= using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using Metaheuristic; // 會印出最好的, 和染色體的樣子 namespace GA_Lib_23fun { class Program_gbest : GA //Rosenbrock Problem Solver Class { int functionNumber; //函數編號 int numDimensions ; //維度數 int ShekelM = 5; int startfunction = 23; //start int numRepetitiveRuns = 10000; //重複執行次數 int numFunctions = 1; //函數的數量=1; > 1 需另存每一函數之Gbest double dimensionsLowerBound; //變數的下限 double dimensionsUpperBound; //變數的上限 double processTime; //使用時間 double[] tempFunctionAllGlobalBestFitness1; double[,] ShekelAijMatrix = new double[4, 10] { { 4, 1, 8, 6, 3, 2, 5, 8, 6, 7 }, { 4, 1, 8, 6, 7, 9, 5, 1, 2, 3.6 }, { 4, 1, 8, 6, 3, 2, 3, 8, 6, 7 }, { 4, 1, 8, 6, 7, 9, 3, 1, 2, 3.6 } }; double[] ShekelCiMatrix = new double[10] { 0.1, 0.2, 0.2, 0.4, 0.4, 0.6, 0.3, 0.7, 0.5, 0.5 }; double[] bestSolutionAverages = new double[24]; //所有Best Solution的平均 double[] bestSolutionSDs = new double[24]; //所有Best Solution的標準差 double[] functionAverageProcessTime = new double[24]; //所有的平均使用時間 double[] functionBestSolutions = new double[24]; //所有Best Solution中最佳的 string functionName; //函數名稱 string[] functionNames = new string[24]; //所有函數名稱 static void Main(string[] args) { Console.WriteLine("Start main function"); Program_gbest ga = new Program_gbest(); //建立Program的實體 ga.tempFunctionAllGlobalBestFitness1 = new double[ga.numRepetitiveRuns]; //將計算後的結果寫入檔案 StreamWriter fileWriter = new StreamWriter("GA-23Function_Gbest4.csv"); fileWriter.WriteLine("Function(Dim), Best, Average, Std, Time(s)"); Stopwatch stopWatch = new Stopwatch(); //建立計時器 Console.WriteLine("Function(Dim), Best, Average, Std, Time(s)"); string[] reader = File.ReadAllLines("C:/Users/rita5/Desktop/鋼鐵/Normailization鳳山_2020.csv"); // 例子: Normailization鳳山_2020.csv int N = reader.Length; // 總共幾筆資料 data = new double[N, 11]; // data大小: N*11 (時間不算) // 資料存進 data for (int i = 0; i < N; i++) { string[] a = reader[i].Split(','); for (int j = 1; j < 12; j++) { data[i, j - 1] = Convert.ToDouble(a[j]); // 注意型態 (double) } } //ga.startfunction 決定要開啟哪個函式 for (int function = ga.startfunction; function < ga.numFunctions + ga.startfunction; function++) { //對於23個function stopWatch.Reset(); //將計算的時間歸零 stopWatch.Start(); //開始計算時間 ga.InitFunction(function + 1); //呼叫初始函數設定變數內容,問題初始化 因為每個函式的維度、上下限皆不同 ga.functionNames[function] = ga.functionName; //紀錄函數名稱 ga.bestSolutionAverages[function] = 0; ga.processTime = 0; double[] tempFunctionAllGlobalBestFitness = new double[ga.numRepetitiveRuns]; //初始化所有gbest的暫存地點 ga.functionBestSolutions[function] = Double.MaxValue; //因為是最小化問題,所以將gbest先設定為最大化 for (int run = 0; run < ga.numRepetitiveRuns; run++) { //每一個function各執行ga.numRepetitiveRuns次 Console.WriteLine(ga.functionName + "第" + (run + 1) + "次執行"); //開始執行GA計算該function的GBestFitness ga.Init(20, ga.numDimensions, ga.dimensionsLowerBound, ga.dimensionsUpperBound, GAOption.EncodingType.Real, GAOption.RepeatableOption.Repeatable); //演算法初始化 ga.SetStrategy(GAOption.Select.Roulette_Wheel, GAOption.Crossover.RealNumber.Alfa_Extension_Arithmetic_X, GAOption.Mutation.RealNumber.Uniform_Variance_Mutation); //選擇、交配、突變的方法設定在此 // (設定初代數目, 交配律, 突變律) ga.Run(10, 0.8, 0.1); //執行結束 tempFunctionAllGlobalBestFitness[run] = ga.GBestFitness; //紀錄每一次的GBestFitness ga.tempFunctionAllGlobalBestFitness1[run] = ga.GBestFitness; //fileWriter.WriteLine(ga.tempFunctionAllGlobalBestFitness1[run]); ga.bestSolutionAverages[function] += ga.GBestFitness; //將每一次的GBestFitness紀錄下來,後面可用來計算10次的平均 if (ga.GBestFitness < ga.functionBestSolutions[function]) { //紀錄最小(最佳)的GBestFitness ga.functionBestSolutions[function] = ga.GBestFitness; } } stopWatch.Stop(); //停止計算時間 ga.processTime = (double)(stopWatch.Elapsed.TotalMilliseconds / 1000); //紀錄每一個function執行10次的總時間 Console.WriteLine("process time: " + ga.processTime); ga.bestSolutionAverages[function] /= ga.numRepetitiveRuns; //計算平均的GBestFitness ga.bestSolutionSDs[function] = sd(tempFunctionAllGlobalBestFitness); //計算10次GBestFitness的標準差 ga.functionAverageProcessTime[function] = ga.processTime / ga.numRepetitiveRuns; //計算執行10次的平均時間 } //寫出內容 for (int function = ga.startfunction; function < ga.numFunctions + ga.startfunction; function++) { Console.WriteLine(ga.functionNames[function] + ", " + ga.functionBestSolutions[function] + ", " + ga.bestSolutionAverages[function] + ", " + ga.bestSolutionSDs[function] + ", " + ga.functionAverageProcessTime[function]); fileWriter.WriteLine(ga.functionNames[function] + "," + ga.functionBestSolutions[function] + "," + ga.bestSolutionAverages[function] + "," + ga.bestSolutionSDs[function] + "," + ga.functionAverageProcessTime[function]); Console.WriteLine(); //*******************寫出最佳解GBest內容***************************** Console.WriteLine("Best solution found: "+ ga.GBest.Length); for (int i = 0; i < ga.GBest.Length; i++) { // Console.Write("{0}, ",ga.GBest[i]); } fileWriter.WriteLine("Best solution found: "); for (int i = 0; i < ga.GBest.Length; i++) { fileWriter.Write("{0},", ga.GBest[i]); } //************************************************** } fileWriter.Close(); //寫入檔案結束 Console.Read(); } public static double sd(double[] fit) { double sum = 0.0; double average; for (int i = 0; i < fit.Length; i++) { sum += fit[i]; } average = sum / fit.Length; sum = 0.0; for (int i = 0; i < fit.Length; i++) { sum += (Math.Pow(fit[i] - average, 2)); } return Math.Pow(sum / fit.Length, 0.5); } // 算分方式 public static double[,] data; public override double Fitness(double[] pos) { double fitness = 0; double total = 0.0; int times = 5; // 總共取幾組資料 if (functionNumber == 1) { //Easom double ePow = -Math.Pow(pos[0] - Math.PI, 2) - Math.Pow(pos[1] - Math.PI, 2); double sum = 0; fitness = -Math.Cos(pos[0]) * Math.Cos(pos[1]) * Math.Pow(Math.E, ePow); /* Circle double ePow = Math.Sqrt(Math.Pow(pos[0], 2) + Math.Pow(pos[1], 2) + Math.Pow(pos[2], 2)); fitness = Math.Abs(ePow-1); */ } else if (functionNumber == 2) { //Shubert double fitness1 = 0, fitness2 = 0; for (int j = 1; j <= 5; j++) { fitness1 = fitness1 + j * Math.Cos((j + 1) * pos[0] + j); fitness2 = fitness2 + j * Math.Cos((j + 1) * pos[1] + j); } fitness = fitness1 * fitness2; } else if (functionNumber == 3 | functionNumber == 10 | functionNumber == 15 | functionNumber == 20) { //Rosenbrock for (int j = 0; j < numDimensions - 1; j++) { fitness = fitness + 100 * Math.Pow(pos[j + 1] - Math.Pow(pos[j], 2), 2) + Math.Pow(pos[j] - 1, 2); } } else if (functionNumber == 4 | functionNumber == 13 | functionNumber == 18 | functionNumber == 23) { //Zakharov double fitness1 = 0, fitness2 = 0; for (int j = 0; j < numDimensions; j++) { fitness1 = fitness1 + Math.Pow(pos[j], 2); fitness2 = fitness2 + 0.5 * (j + 1) * pos[j]; } fitness = fitness1 + Math.Pow(fitness2, 2) + Math.Pow(fitness2, 4); } else if (functionNumber == 5 | functionNumber == 9 | functionNumber == 14 | functionNumber == 19) { //Sphere for (int j = 0; j < numDimensions; j++) { fitness = fitness + Math.Pow(pos[j], 2); } } else if (functionNumber == 6 | functionNumber == 7 | functionNumber == 8) { //Shekel double sum; for (int n = 0; n < ShekelM; n++) { sum = 0; for (int j = 0; j < numDimensions; j++) { sum = sum + Math.Pow(pos[j] - ShekelAijMatrix[j, n], 2); } fitness = fitness + 1 / (sum + ShekelCiMatrix[n]); } fitness = -fitness; } else if (functionNumber == 11 | functionNumber == 16 | functionNumber == 21) { //Rastrigin for (int j = 0; j < numDimensions; j++) { //fitness = fitness + Math.Pow(pos[j], 2) - (10 * Math.Cos(2 * Math.PI * pos[j])) + 10; fitness = fitness + pos[j]; } //fitness = -1.0*fitness; } else if (functionNumber == 0 | functionNumber == 17 | functionNumber == 22) { //Griewank double fitness1 = 0; double fitness2 = 1; for (int j = 0; j < numDimensions; j++) { fitness1 = fitness1 + Math.Pow(pos[j], 2); fitness2 = fitness2 * Math.Cos(pos[j] / Math.Sqrt(j + 1)); } fitness = fitness1 / 4000 - fitness2 + 1; } else if (functionNumber == 24) { Random random = new Random(); for (int time = 0; time < times; time++) { int rd = random.Next(0, data.GetLength(0)); // 亂數 //Console.WriteLine("-----------{0}-----------", rd + 1); double[] tmp = new double[11]; for (int t = 0; t < 11; t++) { tmp[t] = data[rd, t]; } double answer = data[rd, 10]; double fit = 0; for (int t = 0; t < pos.Length; t++) { fit += pos[t] * tmp[t]; } fit = Math.Abs(fit - answer); total += fit; //Console.WriteLine(fit); } fitness = total / times; //Console.WriteLine("best: {0}", fitness); } return fitness; } // 寫function 的地方 public void InitFunction(int number) { switch (number) { //2 numDimensions------------------------------ case (1): //Easom(2) /* this.functionName = "Easom(2)"; this.functionNumber = 1; this.numDimensions = 2; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -10; */ /* this.functionName = "Circle(3)"; this.functionNumber = 1; this.numDimensions = 3; this.dimensionsUpperBound = 5; this.dimensionsLowerBound = -5; */ this.functionName = "Permutation(10)"; this.functionNumber = 1; this.numDimensions = 10; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = 1; break; case (2): //Shubert(2) this.functionName = "Shubert(2)"; this.functionNumber = 2; this.numDimensions = 2; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -10; break; case (3): //Rosenbrock(2) this.functionName = "Rosenbrock(2)"; this.functionNumber = 3; this.numDimensions = 2; this.dimensionsUpperBound = 30; this.dimensionsLowerBound = -30; break; case (4): //Zakharov(2) this.functionName = "Zakharov(2)"; this.functionNumber = 4; this.numDimensions = 2; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -5; break; //3 numDimensions------------------------------ case (5): //De Joung(3) this.functionName = "De Joung(3)"; this.functionNumber = 5; this.numDimensions = 3; this.dimensionsUpperBound = 5.12; this.dimensionsLowerBound = -5.12; break; //4 numDimensions------------------------------ case (6): //Shekel(4,5) this.functionName = "Shekel(4.5)"; this.functionNumber = 6; this.numDimensions = 4; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = 0; this.ShekelM = 5; break; case (7): //Shekel(4,7) this.functionName = "Shekel(4.7)"; this.functionNumber = 7; this.numDimensions = 4; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = 0; this.ShekelM = 7; break; case (8): //Shekel(4,10) this.functionName = "Shekel(4.10)"; this.functionNumber = 8; this.numDimensions = 4; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = 0; //this.dimensionsUpperBound = 10; //this.dimensionsLowerBound = 0; this.ShekelM = 10; break; //10 numDimensions------------------------------ case (9): //Sphere(10) this.functionName = "Sphere(10)"; this.functionNumber = 9; this.numDimensions = 10; this.dimensionsUpperBound = 100; this.dimensionsLowerBound = -100; break; case (10): //Rosenbrock(10) this.functionName = "Rosenbrock(10)"; this.functionNumber = 10; this.numDimensions = 10; this.dimensionsUpperBound = 30; this.dimensionsLowerBound = -30; break; case (11): //Rastrigin(10) this.functionName = "Rastrigin(10)"; this.functionNumber = 11; this.numDimensions = 10; this.dimensionsUpperBound = 5.12; this.dimensionsLowerBound = -5.12; break; case (12): //Griewank(10) this.functionName = "Griewank(10)"; this.functionNumber = 12; this.numDimensions = 10; this.dimensionsUpperBound = 600; this.dimensionsLowerBound = -600; break; case (13): //Zakharov(10) this.functionName = "Zakharov(10)"; this.functionNumber = 13; this.numDimensions = 10; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -5; break; //20 numDimensions------------------------------ case (14): //Sphere(20) this.functionName = "Sphere(20)"; this.functionNumber = 14; this.numDimensions = 20; this.dimensionsUpperBound = 100; this.dimensionsLowerBound = -100; break; case (15): //Rosenbrock(20) this.functionName = "Rosenbrock(20)"; this.functionNumber = 15; this.numDimensions = 20; this.dimensionsUpperBound = 30; this.dimensionsLowerBound = -30; break; case (16): //Rastrigin(20) this.functionName = "Rastrigin(20)"; this.functionNumber = 16; this.numDimensions = 20; this.dimensionsUpperBound = 5.12; this.dimensionsLowerBound = -5.12; break; case (17): //Griewank(20) this.functionName = "Griewank(20)"; this.functionNumber = 17; this.numDimensions = 20; this.dimensionsUpperBound = 600; this.dimensionsLowerBound = -600; break; case (18): //Zakharov(20) this.functionName = "Zakharov(20)"; this.functionNumber = 18; this.numDimensions = 20; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -5; break; //30 numDimensions------------------------------ case (19): //Sphere(30) this.functionName = "Sphere(30)"; this.functionNumber = 19; this.numDimensions = 30; this.dimensionsUpperBound = 100; this.dimensionsLowerBound = -100; break; case (20): //Rosenbrock(30) this.functionName = "Rosenbrock(30)"; this.functionNumber = 20; this.numDimensions = 30; this.dimensionsUpperBound = 30; this.dimensionsLowerBound = -30; break; case (21): //Rastrigin(30) this.functionName = "Rastrigin(30)"; this.functionNumber = 21; this.numDimensions = 30; this.dimensionsUpperBound = 5.12; this.dimensionsLowerBound = -5.12; break; case (22): //Griewank(30) this.functionName = "Griewank(30)"; this.functionNumber = 22; this.numDimensions = 30; this.dimensionsUpperBound = 600; this.dimensionsLowerBound = -600; break; case (23): //Zakharov(30) this.functionName = "Zakharov(30)"; this.functionNumber = 23; this.numDimensions = 30; this.dimensionsUpperBound = 10; this.dimensionsLowerBound = -5; break; case (24): //Our(30) this.functionName = "OurFirst(01)"; this.functionNumber = 24; this.numDimensions = 10; this.dimensionsUpperBound = 7; this.dimensionsLowerBound = 0; break; default: break; } } } } ``` #### 讀檔和Fitness ```csharp= using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; namespace test0621 { class Program { public static double[ , ] data; public static double Fitness(double[] pos) { double total = 0.0; double fitness; int times = 5; // 總共取幾組資料 Random random = new Random(); for (int time = 0; time < times; time++) { int rd = random.Next(0, data.GetLength(0)); // 亂數 Console.WriteLine("-----------{0}-----------", rd+1); double[] tmp = new double[11]; for (int t = 0; t < 11; t++) { tmp[t] = data[rd, t]; } double answer = data[rd, 10]; double fit = 0; for (int t = 0; t < pos.Length; t++) { fit += pos[t] * tmp[t]; } fit = Math.Abs(fit - answer); total += fit; Console.WriteLine(fit); } fitness = total / times; Console.WriteLine("best: {0}", fitness); return fitness; } static void Main(string[] args) { double[] gene = new double[] { 0.01, 0.02, 0.005, 0.06, 0.1, 0.04, 0.0045, 0.081, 0.044, 0.0111}; // 假設一組基因 // 讀檔 // 0 -> 時間 // 1~10 -> 天氣變因 // 11->PM2.5 string[] reader = File.ReadAllLines("Normailization鳳山_2020.csv"); // 例子: Normailization鳳山_2020.csv int N = reader.Length; // 總共幾筆資料 data = new double[N, 11]; // data大小: N*11 (時間不算) // 資料存進 data for (int i=0; i< N; i++) { string[] a = reader[i].Split(','); for (int j=1; j<12; j++) { data[i, j-1] = Convert.ToDouble(a[j]); // 注意型態 (double) } } Console.WriteLine("Read End, totol {0}", N); Fitness(gene); // 把基因拿去算分數 Console.ReadKey(); } } } ``` ### 初始 ```csharp= // 寫function 的地方 public void InitFunction(int number) { switch (number) { case (24): //Our(30) this.functionName = "OurFirst(01)"; this.functionNumber = 24; this.numDimensions = 10; this.dimensionsUpperBound = 7; this.dimensionsLowerBound = 0; break; default: break; } } } } ``` ## 參考資料 [工業生產指數定義](https://statementdog.com/explain/IndustrialIdx.html) [經濟部統計數據指標](https://dmz26.moea.gov.tw/GMWeb/common/CommonQuery.aspx) [縣市重要統計指標](https://statdb.dgbas.gov.tw/pxweb/Dialog/statfile9.asp) [經濟部-批發業營業額](https://dmz26.moea.gov.tw/GA/common/Common.aspx?code=E&no=2) [中華民國統計資訊網](https://www.stat.gov.tw/ct.asp?xItem=37407&CtNode=3564&mp=4) [比賽資料集](https://drive.google.com/drive/folders/17SzCDIIQP3PpfLGJXL0JaYsmDWTSeDkC) [年收盤價](https://www.twse.com.tw/zh/page/trading/exchange/FMNPTK.html) [學姊推薦網站](https://archive.ics.uci.edu/ml/index.php) [個股分類](https://www.cnyes.com/twstock/stock_astock.aspx) ## 題目