随机数法“解”中国邮递员问题

模拟未知路径长度时,邮递员随机选择路径走过,得到长度。

反复重复,多个长度比较,保留最短路径。

该方法在有限时间内可能无法获得最优解。

所得结果为可能的最优解。

 

  1 // 实践是检验真理的唯一标准
  2 
  3 #include <bits/stdc++.h>
  4 
  5 #define MAXCOUNT 210000000
  6 #define MAXCIRCLE 210000000
  7 
  8 using namespace std;
  9 
 10 void Find()
 11 {
 12     srand((int)time(0));
 13 
 14     cout << "输入点数 边数" << endl;
 15     int pointNum, lineNum;
 16     cin >> pointNum >> lineNum;
 17 
 18     int **arr = new int*[pointNum];
 19     for (int i = 0; i < pointNum; i++)
 20         arr[i]=new int[pointNum]();
 21 
 22     bool **hasLined = new bool*[pointNum];
 23     for (int i = 0; i < pointNum; i++)
 24         hasLined[i]=new bool[pointNum]();
 25 
 26     for (int i = 0; i < pointNum; i++)
 27         for (int j = 0; j < pointNum; j++)
 28             if (i == j)
 29                 arr[i][j] = 0;
 30             else
 31                 arr[i][j] = MAXCOUNT;
 32 
 33     cout << "输入点 点 权重" << endl;
 34     for (int i = 0; i < lineNum; i++)
 35     {
 36         int x, y, heavy;
 37         cin >> x >> y >> heavy;
 38         if (x-- > pointNum || y-- > pointNum)
 39         {
 40             cout << "越界" << endl;
 41             return;
 42         }
 43         if (x == y)
 44         {
 45             cout << "输入有误" << endl;
 46             return;
 47         }
 48         arr[x][y] = arr[y][x] = heavy;
 49         arr[x][x]++;
 50         arr[y][y]++;
 51     }
 52 
 53     for (int i = 0; i < pointNum; i++)
 54         if (!arr[i][i])
 55         {
 56             cout << "有孤立点" << endl;
 57             return;
 58         }
 59 
 60     int minPathLen = MAXCOUNT;
 61     string minPath;
 62 
 63     for (int circle = 0 ; circle < MAXCIRCLE; circle++)
 64     {
 65         int pathLen = 0;
 66         string path = "";
 67         int nowPoint = rand() % pointNum;
 68         int lastPoint = nowPoint;
 69         int firstPoint = nowPoint;
 70         bool *hasPassed = new bool[pointNum];
 71         for (int i = 0; i < pointNum; i++)
 72             hasPassed[i] = false;
 73         int passNum = 0;
 74         for (int i = 0; i < pointNum; i++)
 75             for (int j = 0; j < pointNum; j++)
 76                 if (arr[i][j] != MAXCOUNT)
 77                     hasLined[i][j] = false;
 78                 else
 79                     hasLined[i][j] = true;
 80 
 81         while (1)
 82         {
 83             path += nowPoint + '1';
 84             if (path.size() > pointNum * (pointNum + 1) / 2)
 85                 break;
 86 
 87             if ((lastPoint != nowPoint) && (!hasLined[lastPoint][nowPoint]))
 88             {
 89                 hasLined[lastPoint][nowPoint] = true;
 90                 hasLined[nowPoint][lastPoint] = true;
 91                 passNum++;
 92             }
 93 
 94             if (passNum == lineNum && firstPoint == nowPoint)
 95             {
 96                 if (pathLen < minPathLen)
 97                 {
 98                     minPath = path;
 99                     minPathLen = pathLen;
100                 }
101                 break;
102             }
103 
104 //            if (!hasPassed[nowPoint])
105 //            {
106 //                hasPassed[nowPoint] = true;
107 //                passNum++;
108 //            }
109 //
110 //            if (passNum == pointNum && firstPoint == nowPoint)
111 //            {
112 //                if (pathLen < minPathLen)
113 //                {
114 //                    minPath = path;
115 //                    minPathLen = pathLen;
116 //                }
117 //                break;
118 //            }
119 
120             int nextPoint = rand() % arr[nowPoint][nowPoint];
121             for (int i = 0; i < pointNum; i++)
122             {
123                 if (nowPoint != i && arr[nowPoint][i] != MAXCOUNT)
124                     if (!nextPoint--)
125                     {
126                         pathLen += arr[nowPoint][i];
127                         lastPoint = nowPoint;
128                         nowPoint = i;
129                     }
130             }
131         }
132 
133     }
134     cout << "可能最优路径:" << minPath << "  对应长度:" << minPathLen << endl;
135 }
136 
137 int main()
138 {
139     Find();
140     return 0;
141 }
View Code

 

 

两组input样例

6 9
1 2 3
1 6 4
2 6 8
2 3 5
3 6 14
3 4 5
4 5 9
3 5 10
5 6 6

9 11
1 2 2
1 9 1
9 8 2
2 8 6
2 3 1
3 4 1
8 7 4
4 7 5
4 5 2
5 6 3
6 7 2
View Code

 

posted @ 2020-05-01 17:41  KamishiroShinchi  阅读(386)  评论(1)    收藏  举报