private void getlowerbound(object sender, EventArgs e) { totalDistance = 0; Station[] ss = new Station[totalStation]; //從0開始出發每次都找最短距離作為他的下一站 stations.CopyTo(ss, 0); Array.Sort(ss); Station[] Sequence = new Station[totalStation]; int j = 0; for (int i = totalStation - 1; i > -1; i--) { Sequence[j] = ss[i]; j++; } double period = 0; //利用distancematrix除以車速即可得到現在的時間 double cost = 0.0; period += (startTOvertex[Sequence[0].StationID] / speed); //抵達第一站的時間 totalDistance += startTOvertex[Sequence[0].StationID]; //抵達第一站的距離 int a = 0; Truck truck = new Truck(truckcapacity, truckcapacity / 2); int[] temp = new int[totalStation]; while (period <= timehorizon && a < totalStation - 1) { if (Sequence[a].Declinebymin < 0) { temp[a] = truck.PickupDelivery(truckcapacity / 2); cost += HoldingShortageSurplus(period, Sequence[a].StationID, temp[a], ref truck); } else if (Sequence[a].Surplusbymin > 0) { temp[a] = truck.PickupDelivery(-truckcapacity / 2); cost += HoldingShortageSurplus(period, Sequence[a].StationID, temp[a], ref truck); } period += distanceMatrix[Sequence[a].StationID, Sequence[a + 1].StationID] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a].StationID, Sequence[a + 1].StationID]; a++; } if (totalDistance >= speed * timehorizon) { totalDistance -= distanceMatrix[Sequence[a - 1].StationID, Sequence[a].StationID]; } //因為上面最後一次部會做所以... if (Sequence[a].Declinebymin < 0 && period <= timehorizon) { temp[a] = truck.PickupDelivery(truckcapacity / 2); cost += HoldingShortageSurplus(period, Sequence[a].StationID, temp[a], ref truck); } else if (Sequence[a].Surplusbymin > 0 && period <= timehorizon) { temp[a] = truck.PickupDelivery(-truckcapacity / 2); cost += HoldingShortageSurplus(period, Sequence[a].StationID, temp[a], ref truck); } else { a--; } //全部跑完要回去depot if (a == totalStation - 1) { totalDistance += startTOvertex[Sequence[a].StationID]; } else { //沒有跑完的車站繼續算成本 for (int b = a; b < totalStation - 1; b++) { cost += HoldingShortageSurplus(timehorizon, Sequence[b].StationID, 0, ref truck); } } int totalpnd = 0; richTextBox.Text = "routing path is depot "; for (int i = 0; i < a + 1; i++) { richTextBox.Text += (Sequence[i].StationID + " "); } richTextBox.Text += ("\n " + "pickup and delivery amount : "); for (int i = 0; i <= a; i++) { richTextBox.Text += (temp[i] + " "); totalpnd += Math.Abs(temp[i]); } richTextBox.Text += ("\n" + "********performance********"); richTextBox.Text += ("\n" + "total unsatisfied amount is :" + cost); richTextBox.Text += ("\n" + "total distance is :" + totalDistance); richTextBox.Text += ("\n" + "total pickup & delivery: " + totalpnd); }
private void NBS(object sender, EventArgs e) { totalDistance = 0; Station[] ss = new Station[stations.Length]; stations.CopyTo(ss, 0); Array.Sort(ss); //找出不需要用送的站點作為補給站之用 List <Station> supplyStation = new List <Station>(); Priority_Queue.SimplePriorityQueue <Station> pq = new Priority_Queue.SimplePriorityQueue <Station>(); for (int i = 0; i < ss.Length; i++) { if (ss[i].Rate != 0) { pq.Enqueue(ss[i], 1); } if (ss[i].Rate == 0) { supplyStation.Add(ss[i]); } } int[] Sequence = new int[totalStation]; for (int i = 0; i < Sequence.Length; i++) { Sequence[i] = -1; } //確定第一站為最需要先被服務的並且直接先決定卡車上的貨物數量 //直接先決定到的時間點剛好為最需要被服務的剛好缺的時點 int[] temp = new int[totalStation]; double time = 0; double cost = 0; Truck truck = null; for (int k = ss.Length - 1; k > -1; k--) { if (ss[k].Rate != 0) { if (ss[k].Rate < 0) //rate < 0 => need to delivery { truck = new Truck(truckcapacity, truckcapacity); temp[0] = truckcapacity / 2; //cost = HoldingShortageSurplus(time, Sequence[0], truck.PickupDelivery(14)); } else if (ss[k].Rate > 0) { truck = new Truck(truckcapacity, 0); temp[0] = -truckcapacity / 2; //cost = HoldingShortageSurplus(time, Sequence[0], truck.PickupDelivery(-14)); } time = startTOvertex[ss[k].StationID] / speed; Sequence[0] = ss[k].StationID; temp[0] = truck.PickupDelivery(temp[0]); cost += HoldingShortageSurplus(time, Sequence[0], temp[0], ref truck); break; } } Station s = null; //開始建構解 int a = 1; bool flag = false; double min = double.MaxValue; double m = 0; int selected = -1; while (time <= timehorizon && a < totalStation) { while (pq.Count != 0) { s = pq.Max(); pq.Remove(s); flag = false; //s = pq.Dequeue(); if (Sequence.Contains(s.StationID) == false) { Sequence[a] = s.StationID; break; } if (pq.Count == 0) { if (supplyStation.Count != 0) { s = supplyStation.Max(); supplyStation.Remove(s); } break; } } min = double.MaxValue; //下一站是需要貨物的可是你卻沒有貨ㄌ if (s.Declinebymin < 0) { //find truck lack of goods if (truck.CurrentGoods == 0 && supplyStation.Count != 0) { min = double.MaxValue; //find the nearest supply station for (int i = 0; i < supplyStation.Count; i++) { m = distanceMatrix[Sequence[a - 1], supplyStation.ElementAt(i).StationID]; if (min > m) { min = m; selected = i; } } temp[a] = truck.SupplyTruck(supplyStation.ElementAt(selected)); flag = true; Sequence[a] = supplyStation.ElementAt(selected).StationID; supplyStation.RemoveAt(selected); if (a != stations.Length - 1) { Sequence[a + 1] = s.StationID; } } if (flag == true) { time += distanceMatrix[Sequence[a - 1], Sequence[a]] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a - 1], Sequence[a]]; if (a != stations.Length - 1) { time += distanceMatrix[Sequence[a], Sequence[a + 1]] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a], Sequence[a + 1]]; temp[a + 1] = truck.PickupDelivery(truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a + 1], temp[a + 1], ref truck); } a += 2; } else { temp[a] = truck.PickupDelivery(truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a], temp[a], ref truck); } } else { //find truck full of goods if (truck.CurrentSpace == 0 && supplyStation.Count != 0) { //find the nearest supply station min = double.MaxValue; for (int i = 0; i < supplyStation.Count; i++) { m = distanceMatrix[Sequence[a - 1], supplyStation.ElementAt(i).StationID]; if (min > m) { min = m; selected = i; } } temp[a] = truck.SupplyTruck(supplyStation.ElementAt(selected)); flag = true; Sequence[a] = supplyStation.ElementAt(selected).StationID; supplyStation.RemoveAt(selected); if (a != stations.Length - 1) { Sequence[a + 1] = s.StationID; } } if (flag == true) { time += distanceMatrix[Sequence[a - 1], Sequence[a]] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a - 1], Sequence[a]]; if (a != stations.Length - 1) { time += distanceMatrix[Sequence[a], Sequence[a + 1]] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a], Sequence[a + 1]]; temp[a + 1] = truck.PickupDelivery(-truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a + 1], temp[a + 1], ref truck); } a += 2; } else { temp[a] = truck.PickupDelivery(-truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a], temp[a], ref truck); } } if (flag == false) { time += distanceMatrix[Sequence[a - 1], Sequence[a]] / speed;//到下一站的時間點 totalDistance += distanceMatrix[Sequence[a - 1], Sequence[a]]; a++; } } if (a >= totalStation) { a = totalStation - 1; } //因為上面最後一次部會做所以... if (flag == false && stations[Sequence[a - 1]].Declinebymin < 0 && time <= timehorizon) { temp[a - 1] = truck.PickupDelivery(truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a - 1], temp[a - 1], ref truck); } else if (flag == false && stations[Sequence[a - 1]].Surplusbymin > 0 && time <= timehorizon) { temp[a - 1] = truck.PickupDelivery(-truckcapacity / 2); cost += HoldingShortageSurplus(time, Sequence[a - 1], temp[a - 1], ref truck); } else { a--; } //全部跑完要回去depot if (a == totalStation - 1) { totalDistance += startTOvertex[Sequence[a]]; } else { //沒有跑完的車站繼續算成本 for (int b = 0; b < pq.Count; b++) { cost += HoldingShortageSurplus(timehorizon, pq.ElementAt(b).StationID, 0, ref truck); } } richTextBox.Text = "routing path is depot "; for (int i = 0; i < a + 1; i++) { richTextBox.Text += (Sequence[i] + " "); } double totalPandD = 0; richTextBox.Text += "\n" + "pickup & delivery amount: "; for (int i = 0; i < temp.Length; i++) { richTextBox.Text += temp[i].ToString() + " "; totalPandD += Math.Abs(temp[i]); } richTextBox.Text += "\n" + "********performance********"; richTextBox.Text += "\n" + "unsatisfied amount :" + cost; richTextBox.Text += ("\n" + "total distance is " + totalDistance); richTextBox.Text += "\n" + "Total pickup & delivery : " + totalPandD; }
private void openfile(object sender, EventArgs e) { dataGridView.Rows.Clear(); dataGridView.Columns.Clear(); if (openFileDialog.ShowDialog() == DialogResult.OK) { StreamReader sr = new StreamReader(openFileDialog.FileName); totalStation = Convert.ToInt32(sr.ReadLine().ToString()); timehorizon = Convert.ToDouble(sr.ReadLine()); txbtimehorizon.Text = timehorizon.ToString(); truckcapacity = Convert.ToInt32(sr.ReadLine()); txbcapacity.Text = truckcapacity.ToString(); speed = Convert.ToDouble(sr.ReadLine()); txbspeed.Text = speed.ToString(); initialGoods = sr.ReadLine().Split(','); string[] capacity = sr.ReadLine().Split(','); string[] rate = sr.ReadLine().Split(','); string[] distance = sr.ReadLine().Split(','); string[] startTOother = sr.ReadLine().Split(','); stations = new Station[totalStation]; distanceMatrix = new double[totalStation, totalStation]; startTOvertex = new double[totalStation]; for (int i = 0; i < stations.Length; i++) { stations[i] = new Station(Convert.ToInt32(capacity[i]), Convert.ToInt32(initialGoods[i]), i, Convert.ToDouble(rate[i])); } //for benchmark // stations[1].currentGoods = 40;stations[1].currentSpace = 0; int c = 0; //目前仍不知道倉儲的位子 for (int i = 0; i < totalStation; i++) { for (int j = 0; j < totalStation; j++) { distanceMatrix[i, j] = Convert.ToDouble(distance[c]); c++; } } //加入從depot到其他vertex的距離 for (int i = 0; i < totalStation; i++) { startTOvertex[i] = Convert.ToDouble(startTOother[i]); } PandD = new int[totalStation]; BestRouting = new int[totalStation]; sr.Close(); if (checkBox.Checked == true) { for (int k = 0; k < totalStation; k++) { dataGridView.Columns.Add("station" + stations[k].StationID.ToString(), "station" + stations[k].StationID.ToString()); dataGridView.Columns[k].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; dataGridView.Columns[k].HeaderCell.ValueType = typeof(string); dataGridView.Columns[k].HeaderCell.Value = "station" + stations[k].StationID.ToString(); } dataGridView.Rows.Add(); dataGridView.Rows[0].HeaderCell.ValueType = typeof(string); dataGridView.Rows[0].HeaderCell.Value = "cost"; } } }