예제 #1
0
        private void deleteTree(SStep root, bool processEvents = false)
        {
            if (root == null)
            {
                return;
            }
            SStep step = root;
            SStep parent;

            while (true) //forever
            {
                if (processEvents)
                {
                    ;//QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
                }
                if (step.plNode != null)
                {
                    // We have left child node - going inside it
                    step = step.plNode;
                    step.pNode.plNode = null;
                    continue;
                }
                else if (step.prNode != null)
                {
                    // We have right child node - going inside it
                    step = step.prNode;
                    step.pNode.prNode = null;
                    continue;
                }
                else
                {
                    // We have no child nodes. Deleting the current one.
                    parent = step.pNode;
                    //delete step;
                    if (parent != null)
                    {
                        // Going back to the parent node.
                        step = parent;
                    }
                    else
                    {
                        // We came back to the root node. Finishing.
                        root = null;
                        break;
                    }
                }
            }
        }
예제 #2
0
        public SStep solve(int numCities, double[][] task)
        {
            if (numCities < 3)
            {
                return(null);
            }

            //QMutexLocker locker(&mutex);
            cleanup();
            canceled = false;
            //locker.unlock();

            nCities = numCities;

            SStep step = new SStep();

            step.matrix = task;// clone(task);
            // We need to distinguish the values forbidden by the user
            // from the values forbidden by the algorithm.
            // So we replace user's infinities by the maximum available double value.
            normalize(step.matrix);
#if DEBUG
            //qDebug() << step->matrix;
#endif // DEBUG
            step.price = align(step.matrix);
            root       = step;

            SStep  left, right;
            int    nRow, nCol;
            bool   firstStep = true;
            double check     = double.PositiveInfinity;// INFINITY;
            total = 0;
            while (route.Count < nCities)
            {
                step.alts = findCandidate(step.matrix, out nRow, out nCol);

                while (hasSubCycles(nRow, nCol))
                {
#if DEBUG
                    //qDebug() << "Forbidden: (" << nRow << ";" << nCol << ")";
#endif // DEBUG
                    step.matrix[nRow][nCol] = double.PositiveInfinity;// INFINITY;
                    step.price += align(step.matrix);
                    step.alts   = findCandidate(step.matrix, out nRow, out nCol);
                }

#if DEBUG
                //qDebug() /*<< step->matrix*/ << "Selected: (" << nRow << ";" << nCol << ")";
                //qDebug() << "Alternate:" << step->alts;
                //qDebug() << "Step price:" << step->price << endl;
#endif // DEBUG

                //locker.relock();
                if ((nRow == -1) || (nCol == -1) || canceled)
                {
                    if (canceled && cc)
                    {
                        cleanup();
                    }
                    return(null);
                }
                //locker.unlock();

                // Route with (nRow,nCol) path
                right        = new SStep();
                right.pNode  = step;
                right.matrix = clone(step.matrix);
                for (int k = 0; k < nCities; k++)
                {
                    if (k != nCol)
                    {
                        right.matrix[nRow][k] = double.PositiveInfinity;
                    }
                    if (k != nRow)
                    {
                        right.matrix[k][nCol] = double.PositiveInfinity;
                    }
                }
                right.price = step.price + align(right.matrix);
                // Forbid the selected route to exclude its reuse in next steps.
                right.matrix[nCol][nRow] = double.PositiveInfinity;
                right.matrix[nRow][nCol] = double.PositiveInfinity;

                // Route without (nRow,nCol) path
                left                    = new SStep();
                left.pNode              = step;
                left.matrix             = clone(step.matrix);
                left.matrix[nRow][nCol] = double.PositiveInfinity;
                left.price              = step.price + align(left.matrix);

                step.candidate.nRow = nRow;
                step.candidate.nCol = nCol;
                step.plNode         = left;
                step.prNode         = right;

                // This matrix is not used anymore. Restoring infinities back.
                denormalize(step.matrix);

                if (right.price <= left.price)
                {
                    // Route with (nRow,nCol) path is cheaper
                    step.next   = SStep.NextStep.RightBranch;
                    step        = right;
                    route[nRow] = nCol;
                    //emit routePartFound(route.size());
                    if (firstStep)
                    {
                        check     = left.price;
                        firstStep = false;
                    }
                }
                else
                {
                    // Route without (nRow,nCol) path is cheaper
                    step.next = SStep.NextStep.LeftBranch;
                    step      = left;
                    //QCoreApplication::processEvents();
                    if (firstStep)
                    {
                        check     = right.price;
                        firstStep = false;
                    }
                }
                total++;
            }

            mayNotBeOptimal = (check < step.price);

            return(root);
        }