-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ]

, 03 2017 . 18:10 +

19 . NP-, , .


( ), , . .


animation



, .. . :


S . S (i, j), . S1 S2. S1 , (i, j) (j, i). S2 , (i, j). , , . S1 S2 , S.



M. , .. . , .


, , , . . inf1, inf2. inf1.


  1. .
  2. .
  3. M(i, j) , i j, (i, j). , , (i, j)
  4. . , ( )
  5. 2 M1 M2. M1 M i j. k l, inf1 M(k, l) inf1. , (.. (k, l) == (j, i)). M1 , (i, j). (i, j) .
  6. M2 M, (i, j) inf2. , (i, j) ( , (j, i) ).
  7. .1 M1 M2.

, M1 , M2 , (i, j).



, ( , , , , , ). , , .


.


0 1 2 3 4
0 inf 20 18 12 8
1 5 inf 14 7 11
2 12 18 inf 6 11
3 11 17 11 inf 12
4 5 5 5 5 inf

         0        1        2        3        4
0     inf1    20.00    18.00    12.00     8.00
1     5.00     inf1    14.00     7.00    11.00
2    12.00    18.00     inf1     6.00    11.00
3    11.00    17.00    11.00     inf1    12.00
4     5.00     5.00     5.00     5.00     inf1

After subtracting:
         0        1        2        3        4
0     inf1    12.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00    12.00     inf1     0.00     5.00
3     0.00     6.00     0.00     inf1     1.00
4     0.00     0.00     0.00     0.00     inf1

edge (4, 1)
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     2.00     inf1
2     6.00     inf1     0.00     5.00
3     0.00     0.00     inf1     1.00

After subtracting:
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     2.00     inf1
2     6.00     inf1     0.00     5.00
3     0.00     0.00     inf1     1.00

edge (3, 2)
         0        3        4
0     inf1     4.00     0.00
1     0.00     2.00     inf1
2     6.00     inf1     5.00

After subtracting:
         0        3        4
0     inf1     2.00     0.00
1     0.00     0.00     inf1
2     1.00     inf1     0.00

edge (0, 4)
         0        3
1     inf1     0.00
2     1.00     inf1

candidate solution(4 1) (3 2) (0 4) (1 3) (2 0)
cost: 43; record: 1.79769e+308
NEW RECORD
         0        3        4
0     inf1     2.00     0.00
1     0.00     0.00     inf1
2     1.00     inf1     0.00

not edge (0, 4)
         0        3        4
0     inf1     2.00     inf2
1     0.00     0.00     inf1
2     1.00     inf1     0.00

After subtracting:
         0        3        4
0     inf1     0.00     inf2
1     0.00     0.00     inf1
2     1.00     inf1     0.00

limit: 44; record:43
DISCARDING BRANCH
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     2.00     inf1
2     6.00     inf1     0.00     5.00
3     0.00     0.00     inf1     1.00

not edge (3, 2)
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     2.00     inf1
2     6.00     inf1     0.00     5.00
3     0.00     inf2     inf1     1.00

After subtracting:
         0        2        3        4
0     inf1     1.00     4.00     0.00
1     0.00     0.00     2.00     inf1
2     6.00     inf1     0.00     5.00
3     0.00     inf2     inf1     1.00

limit: 44; record:43
DISCARDING BRANCH
         0        1        2        3        4
0     inf1    12.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00    12.00     inf1     0.00     5.00
3     0.00     6.00     0.00     inf1     1.00
4     0.00     0.00     0.00     0.00     inf1

not edge (4, 1)
         0        1        2        3        4
0     inf1    12.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00    12.00     inf1     0.00     5.00
3     0.00     6.00     0.00     inf1     1.00
4     0.00     inf2     0.00     0.00     inf1

After subtracting:
         0        1        2        3        4
0     inf1     6.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00     6.00     inf1     0.00     5.00
3     0.00     0.00     0.00     inf1     1.00
4     0.00     inf2     0.00     0.00     inf1

edge (3, 1)
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     inf1     6.00
2     6.00     inf1     0.00     5.00
4     0.00     0.00     0.00     inf1

After subtracting:
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     inf1     6.00
2     6.00     inf1     0.00     5.00
4     0.00     0.00     0.00     inf1

edge (0, 4)
         0        2        3
1     0.00     9.00     inf1
2     6.00     inf1     0.00
4     inf1     0.00     0.00

After subtracting:
         0        2        3
1     0.00     9.00     inf1
2     6.00     inf1     0.00
4     inf1     0.00     0.00

edge (0, 0)
         2        3
2     inf1     0.00
4     0.00     inf1

candidate solution(3 1) (0 4) (1 0) (2 3) (4 2)
cost: 41; record: 43
NEW RECORD
         0        2        3
1     0.00     9.00     inf1
2     6.00     inf1     0.00
4     inf1     0.00     0.00

not edge (1, 0)
         0        2        3
1     inf2     9.00     inf1
2     6.00     inf1     0.00
4     inf1     0.00     0.00

After subtracting:
         0        2        3
1     inf2     0.00     inf1
2     0.00     inf1     0.00
4     inf1     0.00     0.00

limit: 56; record:41
DISCARDING BRANCH
         0        2        3        4
0     inf1    10.00     4.00     0.00
1     0.00     9.00     inf1     6.00
2     6.00     inf1     0.00     5.00
4     0.00     0.00     0.00     inf1

not edge (0, 4)
         0        2        3        4
0     inf1    10.00     4.00     inf2
1     0.00     9.00     inf1     6.00
2     6.00     inf1     0.00     5.00
4     0.00     0.00     0.00     inf1

After subtracting:
         0        2        3        4
0     inf1     6.00     0.00     inf2
1     0.00     9.00     inf1     1.00
2     6.00     inf1     0.00     0.00
4     0.00     0.00     0.00     inf1

limit: 50; record:41
DISCARDING BRANCH
         0        1        2        3        4
0     inf1     6.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00     6.00     inf1     0.00     5.00
3     0.00     0.00     0.00     inf1     1.00
4     0.00     inf2     0.00     0.00     inf1

not edge (3, 1)
         0        1        2        3        4
0     inf1     6.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00     6.00     inf1     0.00     5.00
3     0.00     inf2     0.00     inf1     1.00
4     0.00     inf2     0.00     0.00     inf1

After subtracting:
         0        1        2        3        4
0     inf1     0.00    10.00     4.00     0.00
1     0.00     inf1     9.00     2.00     6.00
2     6.00     0.00     inf1     0.00     5.00
3     0.00     inf2     0.00     inf1     1.00
4     0.00     inf2     0.00     0.00     inf1

limit: 47; record:41
DISCARDING BRANCH
Solution tour:
0 4 2 3 1 0
Tour length:
41


1

.


double LittleSolver::subtractFromMatrix(MatrixD &m) const {
    //    
    double subtractSum = 0;
    //       
    vector minRow(m.size(), DBL_MAX),
        minColumn(m.size(), DBL_MAX);
    //   
    for (size_t i = 0; i < m.size(); ++i) {
        for (size_t j = 0; j < m.size(); ++j)
            //     
            if (m(i, j) < minRow[i])
                minRow[i] = m(i, j);

        for (size_t j = 0; j < m.size(); ++j) {
            //     
            //  ,  
            if (m(i, j) < _infinity) {
                m(i, j) -= minRow[i];
            }
            //        
            if ((m(i, j) < minColumn[j]))
                minColumn[j] = m(i, j);
        }
    }

    //     
    //  ,  
    for (size_t j = 0; j < m.size(); ++j)
        for (size_t i = 0; i < m.size(); ++i)
            if (m(i, j) < _infinity) {
                m(i, j) -= minColumn[j];
            }

    //   
    for (auto i : minRow)
        subtractSum += i;

    for (auto i : minColumn)
        subtractSum += i;

    return subtractSum;
}

2

.


//      
//   
bottomLimit += subtractFromMatrix(matrix);
//     
if (bottomLimit > _record) {
    return;
}

3

.


double LittleSolver::getCoefficient(const MatrixD &m, size_t r, size_t c) {
    double rmin, cmin;
    rmin = cmin = DBL_MAX;
    //    
    for (size_t i = 0; i < m.size(); ++i) {
        if (i != r)
            rmin = std::min(rmin, m(i, c));
        if (i != c)
            cmin = std::min(cmin, m(r, i));
    }

    return rmin + cmin;
}

.


//    
list> zeros;
//   
list coeffList;

//  
double maxCoeff = 0;
//   
for (size_t i = 0; i < matrix.size(); ++i)
    for (size_t j = 0; j < matrix.size(); ++j)
        //   
        if (!matrix(i, j)) {
            //    
            zeros.emplace_back(i, j);
            //      
            coeffList.push_back(getCoefficient(matrix, i, j));
            //   
            maxCoeff = std::max(maxCoeff, coeffList.back());
        }

4

.


{ //   
    auto zIter = zeros.begin();
    auto cIter = coeffList.begin();
    while (zIter != zeros.end()) {
        if (*cIter != maxCoeff) {
            //    ,    
            zIter = zeros.erase(zIter);
            cIter = coeffList.erase(cIter);
        }
        else {
            ++zIter;
            ++cIter;
        }
    }
}

return zeros;

5

, .


auto edge = zeros.front();
//  
auto newMatrix(matrix);
//      ,   
newMatrix.removeRowColumn(edge.first, edge.second);
//  iter   
auto newPath(path);
newPath.emplace_back(matrix.rowIndex(edge.first),
                     matrix.columnIndex(edge.second));
//      
addInfinity(newMatrix);
//  ,   edge
handleMatrix(newMatrix, newPath, bottomLimit);

6

, .


//   ,    edge
//     
newMatrix = matrix;
//     iter
newMatrix(edge.first, edge.second) = _infinity + 1;
//  ,    edge
handleMatrix(newMatrix, path, bottomLimit);


, , .


. .


.


compare


9 . 13 .


.


time



Qt . . .


"Tour length".


, .


gui


, . .. , , - , .



, , , .


->

Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/332208/

:  

: [1] []
 

:
: 

: ( )

:

  URL