예제 #1
0
            /// <summary>
            /// Constructor.
            /// </summary>
            /// <param name="solver">The root class.</param>
            public TspSolver(DvrpSolver solver)
            {
                _distances      = solver._distances;
                _depotDistances = solver._depotDistances;
                _dvrpProblem    = solver._dvrpProblem;

                _visited = new bool[_dvrpProblem.Requests.Length];
            }
예제 #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>
 /// Solve a partial problem with a given timeout.
 /// </summary>
 /// <param name="partialData">Binary serialized DVRP partial problem data.</param>
 /// <param name="timeout">Maximum time for computations.</param>
 /// <returns>Binary serialized solution.</returns>
 public override byte[] Solve(byte[] partialData, TimeSpan timeout)
 {
     try
     {
         DvrpPartialProblem problem;
         using (var memoryStream = new MemoryStream(partialData))
         {
             problem = (DvrpPartialProblem) _formatter.Deserialize(memoryStream);
         }
         var solver = new DvrpSolver(_dvrpProblem);
         using (var memoryStream = new MemoryStream())
         {
             _formatter.Serialize(memoryStream, solver.Solve(problem, timeout));
             State = solver.State;
             return memoryStream.ToArray();
         }
     }
     catch (Exception ex)
     {
         Exception = ex;
         State = TaskSolverState.Error;
         return null;
     }
 }
예제 #5
0
파일: DvrpSolver.cs 프로젝트: progala2/DVRP
            /// <summary>
            /// Constructor.
            /// </summary>
            /// <param name="solver">The root class.</param>
            public TspSolver(DvrpSolver solver)
            {
                _distances = solver._distances;
                _depotDistances = solver._depotDistances;
                _dvrpProblem = solver._dvrpProblem;

                _visited = new bool[_dvrpProblem.Requests.Length];
            }