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; } } } }
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); }