2015-05-11 49 views
0

我的Dijkstra的實現有一個奇怪的問題...我有2個算法,一個用於鄰接矩陣,第二個用於鄰接列表。它們幾乎完全相同,只有通過這些結構傳遞的數字纔有所不同。Dijkstra的算法 - 鄰接矩陣和列表

我將矩陣中的數字保存在稱爲weightmat的簡單二維矩陣中。 列表中的數字保存在名爲nbhlist的列表數組中。 列表由名爲ListNode的結構組成。

struct ListNode{  
     int number;    
     int weight;   
     ListNode* next;    
     ListNode(){       
      number = weight = 0; 
      next = 0; 
     } 
    }; 

而且一些一般性的變量:頂點(頂點數量),邊(邊數),則vstart(起始頂點的數量)。 Dijkstra算法的

現在代碼矩陣:

typedef vector<vector<pair<int, float> > > Graph; 
struct Compare{ 
    int operator() (const pair<int,float>& p1, const pair<int,float>& p2) 
    { 
     return p1.second > p2.second; 
    } 
}; 

vector<float> d(vertex); 
vector<int> parent(vertex); 

for (int i = 0; i < vertex; i++){ 
    d[i] = numeric_limits<float>::max(); 
    parent[i] = -1; 
} 

priority_queue<pair<int, float>, vector<pair<int, float> >, Compare> MatQueue; 

d[vstart] = 0; 
MatQueue.push(make_pair(vstart, d[vstart])); 
while (!MatQueue.empty()){ 
    int u = MatQueue.top().first; 
    if (u == vertex - 1) break; 
    MatQueue.pop(); 
    for (int i = 0; i < vertex; i++){ 
     if (weightmat[u][i] != 0){ 
      int v = i; 
      float w = weightmat[u][i]; 
      //cout << "U " << u << "Number " << i << " Weight " << weightmat[u][i] << endl; 
      if (d[v]> d[u] + w){ 
       d[v] = d[u] + w; 
       parent[v] = u; 
       MatQueue.push(make_pair(v, d[v])); 
      } 
     } 
    } 
} 

vector<int> path; 
path.clear(); 
int p = vertex - 1; 
path.push_back(vertex - 1); 
while (p != vstart) 
{ 
    p = parent[p]; 
    path.push_back(p); 
} 
for (int i = path.size()-1; i >=0; i--){ 
    cout << path[i] << "->"; 
} 

這是我的名單Dijkstra算法的代碼:

typedef vector<vector<pair<int, float> > > Graph; 

    struct Compare{ 
     int operator() (const pair<int, float>& p1, const pair<int, float>& p2) 
     { 
      return p1.second > p2.second; 
     } 
    }; 

    vector<float> d(vertex); 
    vector<int> parent(vertex); 

    for (int i = 0; i < vertex; i++){ 
     d[i] = numeric_limits<float>::max(); 
     parent[i] = -1; 
    } 

    priority_queue<pair<int, float>, vector<pair<int, float> >, Compare> MatQueue; 

    d[vstart] = 0; 
    MatQueue.push(make_pair(vstart, d[vstart])); 

    ListNode* hand = new ListNode; 

    while (!MatQueue.empty()){ 
     int u = MatQueue.top().first; 
     if (u == vertex - 1) break; 
     MatQueue.pop(); 
     hand = NbhList[u]; 
     while (hand){ 
      int v = hand->number; 
      float w = hand->weight; 
      //cout << "U " << u << "Number " << v << " Weight " << w << endl; 
      hand = hand->next; 
      if (d[v] > d[u] + w){ 
       d[v] = d[u] + w; 
       parent[v] = u; 
       MatQueue.push(make_pair(v, d[v])); 
      } 
     } 
    } 


    vector<int> path; 
    path.clear(); 
    int p = (vertex-1); 
    path.push_back(p); 
    while (p != vstart) 
    { 
     p = parent[p]; 
     path.push_back(p); 
    } 
    cout << endl << endl; 
    for (int i = path.size() - 1; i >= 0; i--){ 
     cout << path[i] << "->"; 
    } 

正如我所說的,他們幾乎是相同的。唯一的區別:

MatQueue.pop(); 
     hand = NbhList[u]; 
     while (hand){ 
      int v = hand->number; 
      float w = hand->weight; 
      //cout << "U " << u << "Number " << v << " Weight " << w << endl; 
      hand = hand->next; 
      if (d[v] > d[u] + w){ 
       d[v] = d[u] + w; 
       parent[v] = u; 
       MatQueue.push(make_pair(v, d[v])); 
      } 
     } 

和:

​​

我的問題是 - 他們給我有時不同的輸出,我不知道爲什麼。 你能幫我找到我的問題嗎?

+0

我懷疑問題在於你如何構建你的鄰居列表。 – molbdnilo

+0

如果你的算法幾乎是相同的,唯一的區別是你的圖形的表示(矩陣vs adj列表),也許它可以幫助你爲你的圖形表示使用一個接口,然後只使用一個算法版本。這樣,您可以進行測試,以確保表示法用於獲取/設置頂點和邊緣的相同方式等。 – gilleain

+0

那麼,哪一個給出正確的答案,如果有的話? – IVlad

回答

2

一個可能的錯誤是,在你的ListNode結構:

struct ListNode{  
     int number;    
     int weight;   
     ListNode* next;    
     ListNode(){       
      number = weight = 0; 
      next = 0; 
     } 
    }; 

weightint,但你的權重是根據你的代碼的其餘部分,這可能會導致不必要的截斷float秒。

+0

不,這不是一個問題。目前我試圖找到哪些結構給我錯誤的輸出。差異僅出現在超過10個頂點和大約100%的圖形密度上,因此很難找到。 – DzikiChrzan

+0

好吧,現在我非常確定我有矩陣問題。 – DzikiChrzan

+0

@EDIT NO!現在我真的不知道該怎麼做...有時矩陣算法給了我正確的路徑,有時列出算法 – DzikiChrzan