示例#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
        /// <summary>
        /// Divide the problem into partial problems.
        /// </summary>
        /// <param name="dvrpProblem">The problem instance to divide.</param>
        /// <param name="numberOfParts">How many parts to divide into.</param>
        /// <returns>Output partial problems.</returns>
        public DvrpPartialProblem[] Divide(DvrpProblem dvrpProblem, int numberOfParts)
        {
            // we generate all the partitions
            // set {{0 0 0 0 0}} represents {{0 1 2 3 4}}
            // set {{0 1 2 3 4}} represents {{0}{1}{2}{3}{4}}
            // set {{0 1 2 1 2}} represents {{0}{1 3}{2 4}}
            // part - current partition
            // max[i] = Max{max[i-1], part[i-1]}
            // max[0] = -1
            // example:
            // 0 0 0
            // 0 0 1
            // 0 1 0
            // 0 1 1
            // 0 1 2

            if (numberOfParts < 1)
            {
                throw new ArgumentOutOfRangeException("numberOfParts");
            }
            var n    = dvrpProblem.Requests.Length;
            var part = new int[n];

            var max                   = new int[n];
            var maxNumberofSets       = TriangularMethodBellNumber(n);
            var numberOfSetsForThread = maxNumberofSets / (ulong)numberOfParts;
            var result                = new DvrpPartialProblem[numberOfParts];
            var solver                = new DvrpSolver(dvrpProblem);
            var approximateResult     = solver.SolveApproximately();

            for (var i = n - 2; i > -1; --i)
            {
                part[i] = 0;
            }
            part[n - 1] = max[0] = -1;
            var   partLast = (int[])part.Clone();
            ulong j        = 0;
            var   k        = 0;

            do
            {
                // checking if max[i] == Max{max[i-1], part[i-1]}
                for (var i = 1; i < n; ++i)
                {
                    if (max[i - 1] < part[i - 1])
                    {
                        max[i] = part[i - 1];
                    }
                    else
                    {
                        max[i] = max[i - 1];
                    }
                }
                // we check if the last elements of the set are in their current maximum
                // for example
                // 01200345 p = 7
                // 01200340 p = 6
                // 01200300 p = 5
                // 01200000 p = 4
                // and now we can increment element for after following loop
                // 01201000
                var p = n - 1;
                while (part[p] == max[p] + 1)
                {
                    part[p] = 0;
                    p       = p - 1;
                }

                #region optimalization

                // now it is (n^2) insted of (B*n)
                if (p <= n - 2 && p > 1 && CheckZeros(part, p, n))
                {
                    var tmp = CalculateCombinations(max[p], p, n);
                    if (tmp > numberOfSetsForThread - j - 1)
                    {
                        part[p] = part[p] + 1;
                        ++j;
                    }
                    else
                    {
                        part[p] = max[p] + 1;
                        for (var i = p + 1; i < n; i++)
                        {
                            part[i] = part[i - 1] + 1;
                        }
                        j += tmp;
                    }
                }
                else if (p == n - 1 && part[p] == 0)
                {
                    var tmp = (int)Math.Min(numberOfSetsForThread - j, (double)max[p] + 1);

                    part[p] = tmp;
                    j      += (ulong)part[p];
                }
                else
                {
                    part[p] = part[p] + 1;
                    ++j;
                }

                #endregion

                if (j == numberOfSetsForThread)
                {
                    result[k] = new DvrpPartialProblem(partLast, approximateResult, j, part);
                    partLast  = (int[])part.Clone();
                    ++k;
                    j = 0;
                    if (k == numberOfParts - 1)
                    {
                        break;
                    }
                }

                // ReSharper disable once LoopVariableIsNeverChangedInsideLoop
            } while (part[n - 1] != n - 1);
            for (var i = 0; i < n; i++)
            {
                part[i] = i;
            }
            result[k] = new DvrpPartialProblem(partLast, approximateResult,
                                               maxNumberofSets - (ulong)k * numberOfSetsForThread, part);
            return(result);
        }
示例#3
0
        /// <summary>
        /// Divide the problem into partial problems.
        /// </summary>
        /// <param name="dvrpProblem">The problem instance to divide.</param>
        /// <param name="numberOfParts">How many parts to divide into.</param>
        /// <returns>Output partial problems.</returns>
        public DvrpPartialProblem[] Divide(DvrpProblem dvrpProblem, int numberOfParts)
        {
            // we generate all the partitions
            // set {{0 0 0 0 0}} represents {{0 1 2 3 4}}
            // set {{0 1 2 3 4}} represents {{0}{1}{2}{3}{4}}
            // set {{0 1 2 1 2}} represents {{0}{1 3}{2 4}}
            // part - current partition
            // max[i] = Max{max[i-1], part[i-1]}
            // max[0] = -1
            // example:
            // 0 0 0
            // 0 0 1
            // 0 1 0
            // 0 1 1
            // 0 1 2

            if (numberOfParts < 1)
                throw new ArgumentOutOfRangeException("numberOfParts");
            var n = dvrpProblem.Requests.Length;
            var part = new int[n];

            var max = new int[n];
            var maxNumberofSets = TriangularMethodBellNumber(n);
            var numberOfSetsForThread = maxNumberofSets/(ulong) numberOfParts;
            var result = new DvrpPartialProblem[numberOfParts];
            var solver = new DvrpSolver(dvrpProblem);
            var approximateResult = solver.SolveApproximately();

            for (var i = n - 2; i > -1; --i)
                part[i] = 0;
            part[n - 1] = max[0] = -1;
            var partLast = (int[]) part.Clone();
            ulong j = 0;
            var k = 0;
            do
            {
                // checking if max[i] == Max{max[i-1], part[i-1]}
                for (var i = 1; i < n; ++i)
                {
                    if (max[i - 1] < part[i - 1])
                        max[i] = part[i - 1];
                    else
                        max[i] = max[i - 1];
                }
                // we check if the last elements of the set are in their current maximum
                // for example
                // 01200345 p = 7
                // 01200340 p = 6
                // 01200300 p = 5
                // 01200000 p = 4
                // and now we can increment element for after following loop
                // 01201000
                var p = n - 1;
                while (part[p] == max[p] + 1)
                {
                    part[p] = 0;
                    p = p - 1;
                }

                #region optimalization

                // now it is (n^2) insted of (B*n)
                if (p <= n - 2 && p > 1 && CheckZeros(part, p, n))
                {
                    var tmp = CalculateCombinations(max[p], p, n);
                    if (tmp > numberOfSetsForThread - j - 1)
                    {
                        part[p] = part[p] + 1;
                        ++j;
                    }
                    else
                    {
                        part[p] = max[p] + 1;
                        for (var i = p + 1; i < n; i++)
                        {
                            part[i] = part[i - 1] + 1;
                        }
                        j += tmp;
                    }
                }
                else if (p == n - 1 && part[p] == 0)
                {
                    var tmp = (int) Math.Min(numberOfSetsForThread - j, (double) max[p] + 1);

                    part[p] = tmp;
                    j += (ulong) part[p];
                }
                else
                {
                    part[p] = part[p] + 1;
                    ++j;
                }

                #endregion

                if (j == numberOfSetsForThread)
                {
                    result[k] = new DvrpPartialProblem(partLast, approximateResult, j, part);
                    partLast = (int[]) part.Clone();
                    ++k;
                    j = 0;
                    if (k == numberOfParts - 1)
                    {
                        break;
                    }
                }

                // ReSharper disable once LoopVariableIsNeverChangedInsideLoop
            } while (part[n - 1] != n - 1);
            for (var i = 0; i < n; i++)
            {
                part[i] = i;
            }
            result[k] = new DvrpPartialProblem(partLast, approximateResult,
                maxNumberofSets - (ulong) k*numberOfSetsForThread, part);
            return result;
        }
示例#4
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);
        }