예제 #1
0
        /// <summary>
        /// Solves a partial problem.
        /// </summary>
        /// <param name="partProblem">DVRP partial problem to solve.</param>
        /// <param name="timeout">Timeout for computations.</param>
        /// <returns>Solution of the given problem.</returns>
        public DvrpSolution Solve(DvrpPartialProblem partProblem, TimeSpan timeout)
        {
            var resultCarsRoutes = new List <int> [_dvrpProblem.VehicleCount];

            for (var i = 0; i < _dvrpProblem.VehicleCount; i++)
            {
                resultCarsRoutes[i] = new List <int>();
            }
            var min = partProblem.ApproximateResult;

            var n   = _dvrpProblem.Requests.Length;
            var max = new int[n];

            max[0] = -1;
            var part = partProblem.SetBegin;

            _timer.Reset();
            _timer.Start();
            // let's check all the partitions
            for (ulong i = 0; IsLowerSet(part, partProblem.SetEnd); ++i)
            {
                if (_timer.Elapsed.TotalSeconds >= timeout.TotalSeconds)
                {
                    State = UCCTaskSolver.TaskSolver.TaskSolverState.Timeout;
                    break;
                }
                for (var j = 1; j < n; ++j)
                {
                    if (max[j - 1] < part[j - 1])
                    {
                        max[j] = part[j - 1];
                    }
                    else
                    {
                        max[j] = max[j - 1];
                    }
                }
                var p = n - 1;
                while (part[p] == max[p] + 1)
                {
                    part[p] = 0;
                    p       = p - 1;
                }
                part[p] = part[p] + 1;

                var breaking     = false;
                var cap          = new List <int>();
                var listOfRoutes = new List <List <int> >();
                for (var j = 0; j < part.Length; ++j)
                {
                    if (listOfRoutes.Count == part[j])
                    {
                        // With this version of algorthm we assume that one car can do only one ride
                        if (listOfRoutes.Count == _dvrpProblem.VehicleCount)
                        {
                            breaking = true;
                            break;
                        }
                        listOfRoutes.Add(new List <int>
                        {
                            j
                        });
                        cap.Add(_dvrpProblem.Requests[j].Demand);
                    }
                    else
                    {
                        listOfRoutes[part[j]].Add(j);
                        cap[part[j]] += (_dvrpProblem.Requests[j].Demand);
                        // The road has to be served in one ride
                        if (cap[part[j]] >= -_dvrpProblem.VehicleCapacity)
                        {
                            continue;
                        }
                        breaking = true;
                        var tmp = Math.Max(max[j], part[j]);
                        for (var k = j + 1; k < part.Length; k++)
                        {
                            part[k] = ++tmp;
                        }
                        break;
                    }
                }
                // if any of partitions doesn't fulfil the requirements
                if (breaking)
                {
                    continue;
                }
                double distance   = 0;
                var    carsRoutes = new List <int> [_dvrpProblem.VehicleCount];
                for (var j = 0; j < listOfRoutes.Count; ++j)
                {
                    distance += _tspSolver.Solve(listOfRoutes[j], min, out carsRoutes[j]);
                    if (distance < min)
                    {
                        continue;
                    }
                    int k = 0;
                    for (int l = 0; l <= j; l++)
                    {
                        k = Math.Max(listOfRoutes[l][listOfRoutes[l].Count - 1], k);
                    }

                    var tmp = Math.Max(max[k], part[k]);
                    for (k += 1; k < part.Length; k++)
                    {
                        part[k] = ++tmp;
                    }
                    break;
                }
                if (min <= distance)
                {
                    continue;
                }

                min = distance;
                for (var j = 0; j < _dvrpProblem.VehicleCount; j++)
                {
                    if (carsRoutes[j] == null)
                    {
                        resultCarsRoutes[j] = new List <int>();
                    }
                    else
                    {
                        resultCarsRoutes[j] = new List <int>(carsRoutes[j]);
                    }
                }
            }
            var routes = new int[_dvrpProblem.VehicleCount][];

            for (var i = 0; i < routes.Length; i++)
            {
                routes[i] = resultCarsRoutes[i].ToArray();
            }
            _timer.Stop();
            return(new DvrpSolution(min, routes));
        }
예제 #2
0
파일: DvrpSolver.cs 프로젝트: progala2/DVRP
        /// <summary>
        /// Solves a partial problem.
        /// </summary>
        /// <param name="partProblem">DVRP partial problem to solve.</param>
        /// <param name="timeout">Timeout for computations.</param>
        /// <returns>Solution of the given problem.</returns>
        public DvrpSolution Solve(DvrpPartialProblem partProblem, TimeSpan timeout)
        {
            var resultCarsRoutes = new List<int>[_dvrpProblem.VehicleCount];
            for (var i = 0; i < _dvrpProblem.VehicleCount; i++)
            {
                resultCarsRoutes[i] = new List<int>();
            }
            var min = partProblem.ApproximateResult;

            var n = _dvrpProblem.Requests.Length;
            var max = new int[n];
            max[0] = -1;
            var part = partProblem.SetBegin;

            _timer.Reset();
            _timer.Start();
            // let's check all the partitions
            for (ulong i = 0; IsLowerSet(part, partProblem.SetEnd); ++i)
            {
                if (_timer.Elapsed.TotalSeconds >= timeout.TotalSeconds)
                {
                    State = UCCTaskSolver.TaskSolver.TaskSolverState.Timeout;
                    break;
                }
                for (var j = 1; j < n; ++j)
                {
                    if (max[j - 1] < part[j - 1])
                        max[j] = part[j - 1];
                    else
                        max[j] = max[j - 1];
                }
                var p = n - 1;
                while (part[p] == max[p] + 1)
                {
                    part[p] = 0;
                    p = p - 1;
                }
                part[p] = part[p] + 1;

                var breaking = false;
                var cap = new List<int>();
                var listOfRoutes = new List<List<int>>();
                for (var j = 0; j < part.Length; ++j)
                {
                    if (listOfRoutes.Count == part[j])
                    {
                        // With this version of algorthm we assume that one car can do only one ride
                        if (listOfRoutes.Count == _dvrpProblem.VehicleCount)
                        {
                            breaking = true;
                            break;
                        }
                        listOfRoutes.Add(new List<int>
                        {
                            j
                        });
                        cap.Add(_dvrpProblem.Requests[j].Demand);
                    }
                    else
                    {
                        listOfRoutes[part[j]].Add(j);
                        cap[part[j]] += (_dvrpProblem.Requests[j].Demand);
                        // The road has to be served in one ride
                        if (cap[part[j]] >= -_dvrpProblem.VehicleCapacity) continue;
                        breaking = true;
                        var tmp = Math.Max(max[j], part[j]);
                        for (var k = j + 1; k < part.Length; k++)
                        {
                            part[k] = ++tmp;
                        }
                        break;
                    }
                }
                // if any of partitions doesn't fulfil the requirements
                if (breaking)
                    continue;
                double distance = 0;
                var carsRoutes = new List<int>[_dvrpProblem.VehicleCount];
                for (var j = 0; j < listOfRoutes.Count; ++j)
                {
                    distance += _tspSolver.Solve(listOfRoutes[j], min, out carsRoutes[j]);
                    if (distance < min) continue;
                    int k = 0;
                    for (int l = 0; l <= j; l++)
                    {
                        k = Math.Max(listOfRoutes[l][listOfRoutes[l].Count - 1], k);
                    }

                    var tmp = Math.Max(max[k], part[k]);
                    for (k += 1; k < part.Length; k++)
                    {
                        part[k] = ++tmp;
                    }
                    break;
                }
                if (min <= distance) continue;

                min = distance;
                for (var j = 0; j < _dvrpProblem.VehicleCount; j++)
                {
                    if (carsRoutes[j] == null)
                        resultCarsRoutes[j] = new List<int>();
                    else
                        resultCarsRoutes[j] = new List<int>(carsRoutes[j]);
                }
            }
            var routes = new int[_dvrpProblem.VehicleCount][];
            for (var i = 0; i < routes.Length; i++)
            {
                routes[i] = resultCarsRoutes[i].ToArray();
            }
            _timer.Stop();
            return new DvrpSolution(min, routes);
        }