模拟未知路径长度时,邮递员随机选择路径走过,得到长度。
反复重复,多个长度比较,保留最短路径。
该方法在有限时间内可能无法获得最优解。
所得结果为可能的最优解。
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 }
两组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