图的应用:哈密尔顿路径

 1       public List<Integer> getHamiltonianPath(int v) {
 2         // A path starts from v. (i, next[i]) represents an edge in 
 3         // the path. isVisited[i] tracks whether i is currently in the 
 4         // path.
 5         int[] next = new int[getSize()];       
 6         for (int i = 0; i < next.length; i++)
 7           next[i] = -1; // Indicate no subpath from i is found yet
 8         
 9         boolean[] isVisited = new boolean[getSize()]; 
10         
11         // The vertices in the Hamiltionian path are stored in result
12         List<Integer> result = null;
13 
14         // To speed up search, reorder the adjacency list for each 
15         // vertex so that the vertices in the list are in increasing 
16         // order of their degrees
17         for (int i = 0; i < getSize(); i++)
18           reorderNeigborsBasedOnDegree(neighbors.get(i));
19         
20         if (getHamiltonianPath(v, next, isVisited)) {
21           result = new ArrayList<Integer>(); // Create a list for path        
22           int vertex = v; // Starting from v
23           while (vertex != -1) {
24             result.add(vertex); // Add vertex to the result list
25             vertex = next[vertex]; // Get the next vertex in the path
26           }
27         }
28         
29         return result; // return null if no Hamiltionian path is found
30       }
31 
32       /** Reorder the adjacency list in increasing order of degrees */
33       private void reorderNeigborsBasedOnDegree(List<Integer> list) {
34         for (int i = list.size() - 1; i >= 1; i--) {
35           // Find the maximum in the list[0..i]
36           int currentMaxDegree = getDegree(list.get(0));
37           int currentMaxIndex = 0;
38 
39           for (int j = 1; j <= i; j++) {
40             if (currentMaxDegree < getDegree(list.get(j))) { 
41               currentMaxDegree = getDegree(list.get(j));
42               currentMaxIndex = j;
43             }
44           }
45 
46           // Swap list[i] with list[currentMaxIndex] if necessary;
47           if (currentMaxIndex != i) {
48             int temp = list.get(currentMaxIndex);
49             list.set(currentMaxIndex, list.get(i));
50             list.set(i, temp);
51           }
52         }
53       }
54       
55       /** Return true if all elements in array isVisited are true */
56       private boolean allVisited(boolean[] isVisited) {
57         boolean result = true;
58         
59         for (int i = 0; i < getSize(); i++) 
60           result = result && isVisited[i];
61         
62         return result;
63       }
64       
65       /** Search for a Hamiltonian path from v */
66       private boolean getHamiltonianPath(int v, int[] next,
67           boolean[] isVisited) {
68         isVisited[v] = true; // Mark vertex v visited
69 
70         if (allVisited(isVisited)) 
71           return true; // The path now includes all vertices, thus found
72           
73         for (int i = 0; i < neighbors.get(v).size(); i++) {
74           int u = neighbors.get(v).get(i);
75           if (!isVisited[u] && 
76               getHamiltonianPath(u, next, isVisited)) {
77             next[v] = u; // Edge (v, u) is in the path
78             return true; 
79           }
80         }
81 
82         isVisited[v] = false; // Backtrack, v is marked unvisited now
83         return false; // No Hamiltonian path exists from vertex v
84       }

 对于一个给定的网络,确定起点后,如果存在一条路径,最后又回到原出发点,且满足每个顶点只被访问一次的情况下能穿过这个网络,我们就说这个网络存在哈密顿路径。

posted @ 2013-11-22 08:29  soul390  阅读(1031)  评论(0)    收藏  举报