簡體   English   中英

嘗試實現 dijkstra 的算法(在我無法完全修復的線程中遇到異常)

[英]Trying to Implement dijkstra's algorithm (Running into Exception in thread that I can't quite fix)

我必須實現 dijkstra 的分配算法,以找到與道路相連的各個城市之間的最短路徑。 每條道路都有固定的成本,每個城市都有固定的停留成本。 任務只是找到第一個和第二個節點之間的最短路徑,最少有 3 個節點,但我寫了我的來找到源和所有節點之間的最短路徑。

通過首先給出城市(節點)的數量,然后是道路(鏈接)的數量來輸入數據。 然后每個城市(節點)都以“#city cost”格式讀取它的成本。 然后將鏈接讀入為“#first_city #second_city cost”。 我將它們存儲在一個二維數組中,其中第一個維度是城市,第二個維度是從每個城市前往其他城市的成本。 我最初在沒有鏈接初始化為 null 的城市之間有成本,但我開始得到我目前正在處理的異常。

以下是我輸入數據的方式:

private Integer num_cities;
private Integer num_roads;

public static void main(String[] args) {

        test p = new test();
        

        p.num_cities = readInt();
        p.num_roads = readInt();

        Integer [][] roads = new Integer[p.num_cities][p.num_roads];

        Integer [] hotel_cost = new Integer[p.num_cities];

        //Reading in Hotel Costs at Each City
        hotel_cost[0] = 0;
        hotel_cost[1] = 0;
        for (Integer i = 2; i < p.num_cities; i++) {
            Integer hotel = readInt() - 1;
            hotel_cost[hotel] = readInt();
        }

        //filling with no connections
        for (Integer i = 1; i < p.num_cities; i++) {
            for (Integer j = 0; j < p.num_roads; j++) {
                roads[i][j] = 0;
            }
        }

        //Reading in Gas Costs on Each Road
        for (Integer i = 0; i < p.num_roads; i++) {
            Integer a = readInt() - 1;
            Integer b = readInt() - 1;
            Integer cost = readInt();
            roads[a][b] = cost;
            roads[b][a] = cost;
        }

        p.dijkstra(roads, hotel_cost, 0);
    
    
    }
}

我當前的 dijkstra function 定義如下:

    public Integer minDistance(Integer cost[], Boolean b[]) {
        Integer min = Integer.MAX_VALUE, index = -1;
        for (Integer x = 0; x < num_cities; x++) {
            if (b[x] == false && cost[x] <= min) {
                min = cost[x];
                index = x;
            }
        }
        return index;
    }


    public void dijkstra(Integer roads[][], Integer hotel_cost[], Integer src) {

        Integer cost[] = new Integer[num_cities];

        Boolean b[] = new Boolean[num_cities];

        for(Integer i = 0; i < num_cities; i++) {
            cost[i] = Integer.MAX_VALUE;
            b[i] = false;
        }

        cost[src] = 0;
        for (Integer count = 0; count < num_cities; count++) {
            Integer u = minDistance(cost, b);
            b[u] = true;
            for (Integer x = 0; x < num_roads; x++) {
                if (!b[x] && (roads[u][x] + hotel_cost[u]) != 0 && cost[u] != Integer.MAX_VALUE && cost[u] + roads[u][x] + hotel_cost[u] < cost[x] ) {
                    cost[x] = cost[u] + roads[u][x] + hotel_cost[x];
                }
            }
        }
        printCostChart(cost, num_cities);
    }

我不斷收到以下異常:

Exception in thread "main" java.lang.NullPointerException
        at cmsc401.dijkstra(cmsc401.java:72)
        at cmsc401.main(cmsc401.java:116)

我當前的測試輸入是:

5 
7 
3 78 
4 87 
5 98 
1 4 98 
5 4 45 
1 5 140 
4 3 87 
2 5 150 
3 5 109 
3 2 73

從第一個節點到第二個節點的旅行成本的正確 output 應該是 388 美元。

我測試了一些東西,主要是為了隔離異常,它似乎在 if 語句的這一部分:

!b[x] && (roads[u][x] + hotel_cost[u]) != 0

如果您想對其進行測試,我可以發布 github 鏈接,但我更願意將其保密以阻止任何復制。

正如我在評論中已經說過的那樣,我不得不猜測,但我認為拆箱 road roads[u][x]的嘗試會引發 NPE。

為什么? 因為你像這樣初始化它:

for (Integer i = 1; i < p.num_cities; i++) {
   for (Integer j = 0; j < p.num_roads; j++) {
      roads[i][j] = 0;
   }
}

正如您所看到的, roads[0][j]可能永遠不會被初始化,所以每當u為 0 時,您都會得到 NPE,因為 road roads[0]中的所有元素仍然是 null。

您有一個循環設置roads[a][b]等(注釋為“//讀取每條道路的 Gas Costs”),但由於ab設置為readInt() - 1; 那些也可能永遠不會是 0 (至少由於缺少代碼我無法分辨)。

TLDR: you might get hard to spot and understand NullPointerExceptions when using primitive wrappers (or arrays of those) like Integer and Boolean in situations where a primitive ( int , boolean etc.) is needed and auto-unboxing tries to convert null to a primitive .

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM