Пример #1
0
        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);
        }
Пример #2
0
        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;
        }
Пример #3
0
        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";
                }
            }
        }