[英]Dijkstra adjacency list
我遇到了將 Dijkstras 算法的偽代碼轉換為實際代碼的問題。 我得到了鄰接列表,例如“位置 - 相鄰位置 - 到位置的距離”,一個節點的示例:AAA AAC 180 AAD 242 AAH 40。我的任務是讀取按照所述鄰接列表組織的文件,並計算最短的從一個節點到另一個節點的路徑。 這是 Dijkstra 偽代碼:
void dijkstra( Vertex s )
{
for each Vertex v
{
v.dist = INFINITY;
v.known = false;
}
s.dist = 0;
while( there is an unknown distance vertex )
{
Vertex v = smallest unknown distance vertex;
v.known = true;
for each Vertex w adjacent to v
if( !w.known )
{
DistType cvw = cost of edge from v to w;
if( v.dist + cvw < w.dist )
{
// Update w
decrease( w.dist to v.dist + cvw );
w.path = v;
}
}
}
}
我最麻煩的是“對於與 v 相鄰的每個頂點 w”這是我的非工作代碼:
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
public class Dijkstra {
public static boolean isInteger(String s) {
return isInteger(s, 10);
}
public static boolean isInteger(String s, int radix) {
if (s.isEmpty())
return false;
for (int i = 0; i < s.length(); i++) {
if (i == 0 && s.charAt(i) == '-') {
if (s.length() == 1)
return false;
else
continue;
}
if (Character.digit(s.charAt(i), radix) < 0)
return false;
}
return true;
}
public static void dijkstra(Vertex[] a, Vertex s, int lineCount) {
int i = 0;
while (i < (lineCount)) // each Vertex v
{
a[i].dist = Integer.MAX_VALUE;
a[i].known = false;
i++;
}
s.dist = 0;
int min = Integer.MAX_VALUE; //
while (!(a[0].known == true && a[1].known == true && a[2].known == true && a[3].known == true
&& a[4].known == true && a[5].known == true && a[6].known == true && a[7].known == true
&& a[8].known == true && a[9].known == true && a[10].known == true && a[11].known == true
&& a[12].known == true)) {
System.out.println("here");
for (int b = 0; b < lineCount; b++) {
if (a[b].dist < min && a[b].known == false) {
min = a[b].dist;
}
}
int c = 0;
while (c < lineCount) {
if (a[c].dist == min && a[c].known == false) {
break;
}
c++;
}
System.out.println(min);
a[c].known = true;
int adjSize = a[c].adj.size();
int current = 0;
System.out.println(adjSize);
while (current < adjSize - 1) {
String currentAdjacent = (String) a[c].adj.get(current);
int p = 0;
while (p < lineCount) {
if (a[p].name.equals(currentAdjacent)) {
if (!a[p].known) {
String cvwString = (String) a[c].distance.get(current);
int cvw = Integer.parseInt(cvwString);
System.out.println(" This is cvw" + cvw);
System.out.println("Here2");
if (a[c].dist + cvw < a[p].dist) {
a[p].dist = a[c].dist + cvw;
a[p].path = a[c];
}
}
}
p++;
}
current++;
}
}
}
public static class Vertex {
public List adj; // Adjacency list
public List distance;
public boolean known;
public int dist; // DistType is probably int
public Vertex path;
public String name;
// Other fields and methods as needed
}
public static void printPath(Vertex v) {
if (v.path != null) {
printPath(v.path);
System.out.print(" to ");
}
System.out.print(v);
}
public static void main(String[] args) throws IOException {
int lineCounter = 0;
BufferedReader br = new BufferedReader(new FileReader("airport.txt"));
try {
StringBuilder sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
sb.append(System.lineSeparator());
line = br.readLine();
lineCounter = lineCounter + 1;
}
Vertex[] arr = new Vertex[lineCounter];
for (int i = 0; i < lineCounter; i++) {
arr[i] = new Vertex();
arr[i].adj = new LinkedList<String>();
arr[i].distance = new LinkedList<Integer>();
}
;
//
int arrayCounter = 0;
String everything = sb.toString();
String[] lines = everything.split("\\s*\\r?\\n\\s*");
for (String line1 : lines) {
arr[arrayCounter] = new Vertex();
arr[arrayCounter].adj = new LinkedList<String>();
arr[arrayCounter].distance = new LinkedList<Integer>();
String[] result = line1.split("\\s+");
for (int x = 0; x < result.length; x++) {
if (x == 0) {
arr[arrayCounter].name = result[0];
continue;
} else if (isInteger(result[x])) {
arr[arrayCounter].distance.add(result[x]);
continue;
} else {
arr[arrayCounter].adj.add(result[x]);
continue;
}
}
arrayCounter++;
}
for (int i = 0; i < 12; i++) {
System.out.println(arr[i].name);
}
System.out.println(lineCounter);
dijkstra(arr, arr[3], lineCounter - 1);
printPath(arr[11]);
} finally {
br.close();
}
}
}
使用我的頂點類,我首先使用一系列 while 循環,遍歷存儲在鏈接列表中的鄰接字符串,同時比較哪個頂點與鄰接列表字符串等效。 有沒有更好的方法來使用我的 Vertex 類對“每個與 v 相鄰的頂點 w”進行編碼? 並為我可能犯下的凌亂代碼和任何其他風格的罪行道歉。 謝謝!
為了解決這個問題,你需要一堆“節點”對象,存儲在一個 HashMap 中,以源位置為鍵。
在節點中,您需要一組對相鄰“節點”對象的引用(或至少是它們的“鍵”,以便您可以針對它編寫邏輯。“節點”還需要知道它與每個“相鄰”節點的位置和距離. 想想 Lundon Underground Tube Maps - 每個車站至少連接一個其他車站。通常是兩個或更多。因此,地鐵站的相鄰節點是您可以從該車站直接到達的下一站。
一旦你有了那個數據結構,你就可以使用遞歸例程來遍歷每個單獨的節點。 然后它應該遍歷每個子節點(也稱為相鄰節點),並通過將此數據存儲在 HashMap 中並在遞歸(或“走”圖)時使用當前累積距離來跟蹤從初始(源)節點到當前節點的距離”。在遞歸時,此跟蹤信息應該是您的方法簽名的一部分。您還需要跟蹤您在遞歸時所采用的當前路徑,以避免循環循環(這將最終具有諷刺意味的是導致 StackOverflowError)。您可以通過使用 HashSet 來做到這一點。這個 Set 應該跟蹤源和當前節點的位置作為入口鍵。如果你在遞歸過程中看到它,那么你已經看到了它,所以不要繼續處理。
我不會為您編寫解決方案的代碼,因為我懷疑您在理解答案的過程中會提出更具體的問題,這些問題很可能在其他地方得到解答。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.