QList<SStep::SCandidate> CTSPSolver::findCandidate(const TMatrix &matrix, int &nRow, int &nCol) const { nRow = -1; nCol = -1; QList<SStep::SCandidate> alts; SStep::SCandidate cand; double h = -1; double sum; for (int r = 0; r < nCities; r++) for (int c = 0; c < nCities; c++) if (matrix.at(r).at(c) == 0) { sum = findMinInRow(r,matrix,c) + findMinInCol(c,matrix,r); if (sum > h) { h = sum; nRow = r; nCol = c; alts.clear(); } else if ((sum == h) && !hasSubCycles(r,c)) { cand.nRow = r; cand.nCol = c; alts.append(cand); } } return alts; }
// matrix: The cost matrix to align // Returns a lower bound for the cost matrix double CTSPSolver::align(TMatrix &matrix) { double r = 0; double min; // Do row subtraction from the matrix with the min row value per row for (int k = 0; k < nCities; k++) { min = findMinInRow(k, matrix); if (min > 0) { r += min; if (min < MAX_DOUBLE) { subRow(matrix, k, min); } } } // Do col subtraction from the matrix with the min col value per col for (int k = 0; k < nCities; k++) { min = findMinInCol(k, matrix); if (min > 0) { r += min; if (min < MAX_DOUBLE) { subCol(matrix, k, min); } } } return (r != MAX_DOUBLE) ? r : INFINITY; }
// Using the cost matrix provided configure nRow and nCol to locate the canidate that maximises // the difference between the inclusion and exclusion branch. We return a vector of alternative // canidate paths std::vector<SStep::SCandidate> CTSPSolver::findCandidate(const TMatrix &matrix, int &nRow, int &nCol) const { nRow = -1; nCol = -1; std::vector<SStep::SCandidate> alts; double bestMax = -1.0; #pragma omp parallel num_threads(numThreads) { // Our best difference so far double h = -1; double sum; int localRow = 0, localCol = 0; SStep::SCandidate cand; // For each row and col check for canidate paths. Because we have performed aligns to the // cost matrix we are only concerned with 0 values #pragma omp for for (int r = 0; r < nCities; r++) { for (int c = 0; c < nCities; c++) { if (matrix.at(r).at(c) == 0) { // Find the cost change for the exclusion branch by selecting this nRow, nCol sum = findMinInRow(r, matrix, c) + findMinInCol(c, matrix, r); // If the difference is greater then we want to choose this path. if (sum > h) { h = sum; localRow = r; localCol = c; // Alternativly we are finding paths of equal difference and will store these. The // optimum soulution could use one of these paths rather than the one we have selected. } else if ((sum == h) && !hasSubCycles(r ,c)) { cand.nRow = r; cand.nCol = c; } } } } #pragma omp critical { if(bestMax < h) { nRow = localRow; nCol = localCol; bestMax = h; } } } return alts; }
double CTSPSolver::align(TMatrix &matrix) { double r = 0; double min; for (int k = 0; k < nCities; k++) { min = findMinInRow(k,matrix); if (min > 0) { r += min; if (min < MAX_DOUBLE) subRow(matrix,k,min); } } for (int k = 0; k < nCities; k++) { min = findMinInCol(k,matrix); if (min > 0) { r += min; if (min < MAX_DOUBLE) subCol(matrix,k,min); } } return (r != MAX_DOUBLE) ? r : INFINITY; }