0%

algorithm-path

路径相关的算法

Path.javaview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
package dsa.algorithm.da109_path;

public class Path {
/**
* 最短路径问题之Dijkstra算法(贪心算法)
*/
public static int dijkstra(int[][] graph) {
int n = graph.length;
int s = 0;
int t = n - 1;

int[] dist = new int[n];
for (int i = 0; i < n; i++) {
dist[i] = Integer.MAX_VALUE;
}
dist[s] = 0;

boolean[] used = new boolean[n];

while (true) {
int i = -1;
for (int j = 0; j < n; j++) {
if (!used[j] && (i == -1 || dist[j] < dist[i])) {
i = j;
}
}

if (i == -1) {
break;
} else {
used[i] = true;
}

for (int j = 0; j < n; j++) {
if (graph[i][j] == Integer.MAX_VALUE) {
// 无通路,跳过
continue;
}

// 更新从i到达j点时k到j的最短距离
if (dist[i] + graph[i][j] < dist[j]) {
dist[j] = dist[i] + graph[i][j];
}
}
}

return dist[t];
}

/**
* 最短路径问题之Floyd算法(动态规划)
*/
public static int floyd(int[][] graph) {
int n = graph.length;
int s = 0;
int t = n - 1;

int[][] dists = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j) {
dists[i][j] = 0;
} else {
dists[i][j] = graph[i][j];
}
}
}

for (int k = 0; k < n; k++) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (dists[i][k] == Integer.MAX_VALUE || dists[k][j] == Integer.MAX_VALUE) {
// 无通路,跳过
continue;
}

if (dists[i][k] + dists[k][j] < dists[i][j]) {
dists[i][j] = dists[i][k] + dists[k][j];
}
}
}
}

return dists[s][t];
}

/**
* 旅行商问题(回溯算法)
*/
public static int[] tps(int[][] graph) {

int n = graph.length;

int[] path = new int[n + 1];
int[] minCost = { Integer.MAX_VALUE };

boolean[] visited = new boolean[n];
int[] trail = new int[n];

int start = 0;

visited[start] = true;
trail[0] = start;
path[n] = start;

dfs(graph, start, 0, minCost, 1, n, visited, trail, path);

// int val = 0;
// for (int i = 0; i < ans.length - 1; i++) {
// val += graph[ans[i]][ans[i + 1]];
// }
// System.out.println(val);
// System.out.println(minCost[0]);
// System.out.println(val == minCost[0]);

return path;
}

/**
*
* @param graph
* @param v 当前顶点序号
* @param curCost 到达当前顶点时的开销
* @param minCost 回到起点时的最小开销
* @param k 当前是第几个顶点(从1开始数)
* @param n 总共有多少个顶点
* @param visited 记录结点的访问状态
* @param trail 记录结点的前进轨迹
* @param path 记录最终的结果路径
*/
private static void dfs(int[][] graph, int v, int curCost, int[] minCost, int k, int n, boolean[] visited,
int[] trail, int[] path) {
// 当前开销已经比最小值大了,需要进行剪枝
if (curCost > minCost[0]) {
return;
}

if (k == n) {
int start = 0;
if (curCost + graph[v][start] < minCost[0]) {
minCost[0] = curCost + graph[v][start];

int index = 0;
for (int t : trail) {
path[index++] = t;
}
}

return;
}

for (int i = 0; i < n; i++) {
if (!visited[i]) {
trail[k] = i;

visited[i] = true;
dfs(graph, i, curCost + graph[v][i], minCost, k + 1, n, visited, trail, path);
visited[i] = false; // 回溯时撤销选择
}
}
}

public static void main(String[] args) {

}
}
只想买包辣条