예제 #1
0
        public static DVRP Parse(string input)
        {
            if (String.IsNullOrWhiteSpace(input))
            {
                throw new ArgumentException(input);
            }

            var instance = new DVRP();
            var lines    = input.Split(new[] { '\n' });

            for (int i = 0; i < lines.Length; i++)
            {
                string[] split = DVRPHelper.SplitText(lines[i]);

                switch (split[0])
                {
                case "VRPTEST":
                    instance.FormatVersionNumber = split[1];
                    break;

                case "COMMENT":
                    instance.Comment += lines[i].Substring(9, lines[i].Length - 9).Trim(new Char[] { ' ', '\r' });    // split[j] + " ";
                    break;

                case "NAME":
                    instance.Name = split[1];
                    break;

                case "NUM_DEPOTS":
                    instance.NumDepots = int.Parse(split[1]);
                    instance.Depots    = new Depot[instance.NumDepots];
                    break;

                case "NUM_CAPACITIES":
                    instance.NumCapacities = int.Parse(split[1]);
                    break;

                case "NUM_VISITS":
                    instance.NumVistis = int.Parse(split[1]);
                    instance.Clients   = new Client[instance.NumVistis];
                    instance.ClientID  = new int[instance.NumVistis];
                    break;

                case "NUM_LOCATIONS":
                    instance.NumLocations = int.Parse(split[1]);
                    instance.Locations    = new Location[instance.NumLocations];
                    break;

                case "NUM_VEHICLES":
                    instance.NumVehicles = int.Parse(split[1]);
                    break;

                case "CAPACITIES":
                    instance.Capacities = int.Parse(split[1]);
                    break;
                //case "DATA_SECTION":

                case "DEPOTS":
                    for (int j = 0; j < instance.NumDepots; j++)
                    {
                        instance.Depots[j]         = new Depot();
                        instance.Depots[j].depotID = int.Parse(lines[++i]);
                    }
                    break;

                case "DEMAND_SECTION":
                    for (int j = 0; j < instance.NumVistis; j++)
                    {
                        instance.Clients[j] = new Client();
                        string[] clientsSplit = DVRPHelper.SplitText(lines[++i]);
                        instance.Clients[j].visitID = int.Parse(clientsSplit[0]);
                        instance.Clients[j].size    = int.Parse(clientsSplit[1]);
                        instance.ClientID[j]        = j;//int.Parse(clientsSplit[0]);
                    }
                    break;

                case "LOCATION_COORD_SECTION":
                    for (int j = 0; j < instance.NumLocations; j++)
                    {
                        instance.Locations[j] = new Location();
                        string[] locationsSplit = DVRPHelper.SplitText(lines[++i]);
                        instance.Locations[j].locationID = int.Parse(locationsSplit[0]);
                        instance.Locations[j].x          = int.Parse(locationsSplit[1]);
                        instance.Locations[j].y          = int.Parse(locationsSplit[2]);
                    }
                    break;

                case "DEPOT_LOCATION_SECTION":
                    for (int j = 0; j < instance.NumDepots; j++)
                    {
                        string[] depotLocationsSplit = DVRPHelper.SplitText(lines[++i]);
                        int      depotId             = int.Parse(depotLocationsSplit[0]);
                        instance.Depots.First(x => x.depotID == depotId).locationID = int.Parse(depotLocationsSplit[1]);
                    }
                    break;

                case "VISIT_LOCATION_SECTION":
                    for (int j = 0; j < instance.NumVistis; j++)
                    {
                        string[] clientsSplit = DVRPHelper.SplitText(lines[++i]);
                        int      visitId      = int.Parse(clientsSplit[0]);
                        instance.Clients.First(x => x.visitID == visitId).locationID = int.Parse(clientsSplit[1]);
                    }
                    break;

                case "DURATION_SECTION":
                    for (int j = 0; j < instance.NumVistis; j++)
                    {
                        string[] clientsSplit = DVRPHelper.SplitText(lines[++i]);
                        int      visitId      = int.Parse(clientsSplit[0]);
                        instance.Clients.First(x => x.visitID == visitId).unld = double.Parse(clientsSplit[1]);
                    }
                    break;

                case "DEPOT_TIME_WINDOW_SECTION":
                    for (int j = 0; j < instance.NumDepots; j++)
                    {
                        string[] depotLocationsSplit = DVRPHelper.SplitText(lines[++i]);
                        int      depotId             = int.Parse(depotLocationsSplit[0]);
                        Depot    d = instance.Depots.First(x => x.depotID == depotId);
                        d.start = double.Parse(depotLocationsSplit[1]);
                        d.end   = double.Parse(depotLocationsSplit[2]);
                    }
                    break;

                //COMMENT: TIMESTEP: 7
                case "TIME_AVAIL_SECTION":
                    for (int j = 0; j < instance.NumVistis; j++)
                    {
                        string[] clientsSplit = DVRPHelper.SplitText(lines[++i]);
                        int      visitId      = int.Parse(clientsSplit[0]);
                        instance.Clients.First(x => x.visitID == visitId).time = double.Parse(clientsSplit[1]);
                    }
                    break;

                case "EOF":
                    break;
                }
            }

            instance.distances = new double[instance.Locations.Length, instance.Locations.Length];
            for (int j = 0; j < instance.Locations.Length; j++)
            {
                for (int k = 0; k < instance.Locations.Length; k++)
                {
                    instance.distances[j, k] = DVRPHelper.Distance(instance.Locations[j], instance.Locations[k]);
                }
            }

            return(instance);
        }
        public void FindCycle(int v, int k, double pathLen, double time, double capacity)
        {
            if (pathLen >= bestPathLen || time > dvrp.Depots[0].end)
            {
                return;
            }
            if (k == depth)
            {
                double distToDepot = DVRPHelper.Distance(act_cycle[act_cycle.Count - 1], act_cycle[0]);
                double timeToDepot = distToDepot / dvrp.Speed;

                if (pathLen + distToDepot < bestPathLen && time + timeToDepot < dvrp.Depots[0].end)
                {
                    bestPathLen = pathLen + distToDepot;
                    act_cycle.Add(dvrp.Locations[dvrp.Depots[0].locationID]);
                    best_cycle = new List <Location>(act_cycle);
                    arrivalTimes.Add(time + timeToDepot);
                    bestArrivalsTimes = new List <double>(arrivalTimes);

                    act_cycle.RemoveAt(act_cycle.Count - 1);
                    arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                }
                return;
            }


            for (int i = 0; i < clientsId.Length; i++)
            {
                if (!used[i])
                {
                    used[i] = true;

                    if (capacity + dvrp.Clients[clientsId[i]].size > 0)
                    {
                        double dist  = dvrp.distances[v, dvrp.Clients[clientsId[i]].locationID];
                        double t     = dist / dvrp.Speed;
                        double tWait = 0;//czas oczekiwania na przyjscie zgłoszenia
                        if (dvrp.Clients[clientsId[i]].time < cutOff * dvrp.Depots[0].end && time < dvrp.Clients[clientsId[i]].time)
                        {
                            tWait = dvrp.Clients[clientsId[i]].time - time;
                        }
                        arrivalTimes.Add(time + t + tWait);
                        act_cycle.Add(dvrp.Locations[dvrp.Clients[clientsId[i]].locationID]);
                        FindCycle(dvrp.Locations[dvrp.Clients[clientsId[i]].locationID].locationID, k + 1, pathLen + dist, time + t + tWait + dvrp.Clients[clientsId[i]].unld, capacity + dvrp.Clients[clientsId[i]].size);
                        act_cycle.RemoveAt(act_cycle.Count - 1);
                        arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                    }
                    else if (capacity + dvrp.Clients[clientsId[i]].size == 0)
                    {
                        double distToClient = dvrp.distances[v, dvrp.Clients[clientsId[i]].locationID];
                        double timeToClient = distToClient / dvrp.Speed;
                        double tWait        = 0;//czas oczekiwania na przyjscie zgłoszenia
                        if (dvrp.Clients[clientsId[i]].time < cutOff * dvrp.Depots[0].end && time < dvrp.Clients[clientsId[i]].time)
                        {
                            tWait = dvrp.Clients[clientsId[i]].time - time;
                        }
                        arrivalTimes.Add(time + timeToClient + tWait);

                        double distToDepot = dvrp.distances[dvrp.Clients[clientsId[i]].locationID, dvrp.Depots[0].locationID];
                        double timeToDepot = distToDepot / dvrp.Speed;
                        arrivalTimes.Add(time + timeToClient + tWait + dvrp.Clients[clientsId[i]].unld + timeToDepot);

                        act_cycle.Add(dvrp.Locations[dvrp.Clients[clientsId[i]].locationID]);
                        act_cycle.Add(dvrp.Locations[dvrp.Depots[0].locationID]);
                        depth++;
                        FindCycle(0, k + 2, pathLen + distToClient + distToDepot, time + timeToClient + tWait + dvrp.Clients[clientsId[i]].unld + timeToDepot, dvrp.Capacities);
                        depth--;
                        act_cycle.RemoveAt(act_cycle.Count - 1);
                        act_cycle.RemoveAt(act_cycle.Count - 1);
                        arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                        arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                    }
                    else
                    {
                        double distCD = 0; // distance from prev client to depot
                        double distDC = 0; //disttance from depot to client
                        if (act_cycle.Count > 0)
                        {
                            distCD = dvrp.distances[act_cycle[act_cycle.Count - 1].locationID, dvrp.Depots[0].locationID];
                        }
                        distDC = dvrp.distances[dvrp.Depots[0].locationID, dvrp.Clients[clientsId[i]].locationID];

                        double tCD = distCD / dvrp.Speed;
                        arrivalTimes.Add(time + tCD);
                        double tDC   = distDC / dvrp.Speed;
                        double tWait = 0;//czas oczekiwania na przyjscie zgłoszenia
                        if (dvrp.Clients[clientsId[i]].time < cutOff * dvrp.Depots[0].end && time < dvrp.Clients[clientsId[i]].time)
                        {
                            tWait = dvrp.Clients[clientsId[i]].time - time;
                        }
                        arrivalTimes.Add(time + tCD + tDC + tWait);

                        act_cycle.Add(dvrp.Locations[dvrp.Depots[0].locationID]);
                        depth++;
                        act_cycle.Add(dvrp.Locations[dvrp.Clients[clientsId[i]].locationID]);

                        FindCycle(dvrp.Clients[clientsId[i]].locationID, k + 2, pathLen + distCD + distDC, time + tCD + tDC + tWait, dvrp.Capacities + dvrp.Clients[clientsId[i]].size);
                        depth--;
                        act_cycle.RemoveAt(act_cycle.Count - 1);
                        act_cycle.RemoveAt(act_cycle.Count - 1);

                        arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                        arrivalTimes.RemoveAt(arrivalTimes.Count - 1);
                    }
                    used[i] = false;
                }
            }
        }