前提・実現したいこと
以下の要領を基に優先度付きキューを適切に利用したダイクストラ法のアルゴリズムを実装しようと思っています。
- まず,30個の頂点上のグラフを保持する二次元配列graph[N][N],及び,その隣接リストvList[N],更に,最短経路木を保持する一次元配列path[N] を(大域変数として)用意する.
- グラフG = (V,E) をランダムに生成する.(巻末の付録を参照.)そのグラフを出力する.(これらを関数gen_graph(), print_graph() で行う.)
- 優先度付きキューを初期化する.(これを関数init_heap() で行う.)
- 始点をs = 0,終点をt = 29 として,s からt への(G 上の)最短経路をダイクストラのアルゴリズムで探索する.(これを関数dijkstra() で行う.)
- 到達可能であればpath が示す経路を「始点から順に」出力する.(配列pathは,終点から辿っていかざるをえず,それを順に表示すると逆順になってしまう!スタックか再帰を用いると解決できる.)到達不可能であればその旨を出力する.(グラフはランダム生成なためそういう場合もある.)
発生している問題・エラーメッセージ
push,pop,changeのプログラムは解決できましたが, 到達可能を判定するためのrec_print_pathの表現の仕方が分からず困っています(print_pathにもあるようにvoid関数で実装したいです)。それとlist関数を使ってdijkstra()を実装したいのですが, イテレータで表現してもエラーが出てしまい, 原因が分かりません。イテレーターに慣れていないのとダイクストラ法で図は描けるもののプログラムとなると中々上手くいかないので教えてほしいです。
dijkstra.cpp: 関数 ‘void dijkstra()’ 内: dijkstra.cpp:151:66: エラー: no match for ‘operator[]’ (operand types are ‘int [30][30]’ and ‘std::_List_iterator<to_len>’) if ((*it).len+graph[s][j]<(*it).len) (*it).len=(*it).len+graph[it][j]; ^ dijkstra.cpp:156:40: エラー: no match for ‘operator=’ (operand types are ‘std::_List_iterator<to_len>’ and ‘int’) if ((*it).len<minlen) {minlen=j; it=j;} ^ In file included from /usr/lib/gcc/i686-pc-cygwin/7.4.0/include/c++/list:63:0, from dijkstra.cpp:3: /usr/lib/gcc/i686-pc-cygwin/7.4.0/include/c++/bits/stl_list.h:128:12: 備考: candidate: constexpr std::_List_iterator<to_len>& std::_List_iterator<to_len>::operator=(const std::_List_iterator<to_len>&) struct _List_iterator ^~~~~~~~~~~~~~ /usr/lib/gcc/i686-pc-cygwin/7.4.0/include/c++/bits/stl_list.h:128:12: 備考: 第 1 引数を ‘int’ から ‘const std::_List_iterator<to_len>&’ へ変換する方法が不明です /usr/lib/gcc/i686-pc-cygwin/7.4.0/include/c++/bits/stl_list.h:128:12: 備考: candidate: constexpr std::_List_iterator<to_len>& std::_List_iterator<to_len>::operator=(std::_List_iterator<to_len>&&) /usr/lib/gcc/i686-pc-cygwin/7.4.0/include/c++/bits/stl_list.h:128:12: 備考: 第 1 引数を ‘int’ から ‘std::_List_iterator<to_len>&&’ へ変換する方法が不明です
該当のソースコード
C++
1#include<iostream> 2#include<random> 3using namespace std; 4 5#define N 30 6#define DENSITY 9 7#define MAX_COST 100 8 9struct node { 10 int id; 11 int cost; 12}; 13struct to_len { 14 int to, len; 15}; 16list<to_len> vList[N]; 17 18node node_data[N]; 19int node_idx[N]; 20int heap_size; 21 22void gen_node_data() 23{ 24 mt19937 mt{random_device{}()}; 25 uniform_int_distribution<int> dist(0,MAX_COST); 26 heap_size = 0; 27 28 for (int i=0; i<N; i++) { 29 node_data[i].id = i; 30 node_data[i].cost = dist(mt); 31 heap_size++; 32 33 node_idx[i] = i; 34 } 35} 36 37int left(int i) {return 2*i+1;} 38int right(int i) {return 2*i+2;} 39void swap(node &a, node &b) {node tmp=a; a=b; b=tmp;} 40 41void down_heap(int parent) 42{ 43 if (left(parent)>heap_size-1) return; 44 45 if (left(parent)==heap_size-1) { 46 if (node_data[parent].cost>node_data[left(parent)].cost) { 47 node_idx[node_data[parent].id] = left(parent); 48 node_idx[node_data[left(parent)].id] = parent; 49 swap(node_data[parent],node_data[left(parent)]); 50 down_heap(left(parent)); 51 } 52 } else { 53 if (node_data[left(parent)].cost<=node_data[right(parent)].cost) { 54 if (node_data[parent].cost>node_data[left(parent)].cost) { 55 node_idx[node_data[parent].id] = left(parent); 56 node_idx[node_data[left(parent)].id] = parent; 57 swap(node_data[parent],node_data[left(parent)]); 58 down_heap(left(parent)); 59 } 60 } else { 61 if (node_data[parent].cost>node_data[right(parent)].cost) { 62 node_idx[node_data[parent].id] = right(parent); 63 node_idx[node_data[right(parent)].id] = parent; 64 swap(node_data[parent],node_data[right(parent)]); 65 down_heap(right(parent)); 66 } 67 } 68 } 69} 70void up_heap(int child) 71{ 72 int parent=(child-1)/2; 73 if (child>heap_size-1) return; 74 75 if (child==heap_size-1) { 76 if (node_data[parent].cost<node_data[child].cost) { 77 node_idx[node_data[parent].id] = child; 78 node_idx[node_data[child].id] = parent; 79 swap(node_data[parent],node_data[child]); 80 up_heap(parent); 81 } 82 } else { 83 if (node_data[right(parent)].cost<=node_data[left(parent)].cost) { 84 if (node_data[left(parent)].cost>node_data[parent].cost) { 85 node_idx[node_data[parent].id] = left(parent); 86 node_idx[node_data[left(parent)].id] = parent; 87 swap(node_data[parent],node_data[left(parent)]); 88 up_heap(parent); 89 } 90 } else { 91 if (node_data[right(parent)].cost>node_data[parent].cost) { 92 node_idx[node_data[parent].id] = right(parent); 93 node_idx[node_data[right(parent)].id] = parent; 94 swap(node_data[parent],node_data[right(parent)]); 95 up_heap(parent); 96 } 97 } 98 } 99} 100void make_heap() 101{ 102 for (int i=(N-1)/2; i>=0; i--) { 103 down_heap(i); 104 } 105} 106bool check_rightmost(int i) 107{ 108 int x = i+2; 109 while (x>1) { 110 if (x%2==1) return 0; 111 else x=x/2; 112 } 113 return 1; 114} 115void push(int id, int cost) 116{ 117 for (int i=0; i<N-1; i++) { 118 node_data[i].id=node_data[i+1].id; 119 node_data[i].cost=node_data[i+1].cost; 120 } 121 for (int i=0; i<N-1; i++) { 122 node_idx[node_data[i].id]=node_data[i].id; 123 } 124 node_data[N-1].id=id; 125 node_data[N-1].cost=cost; 126 node_idx[node_data[N-1].id]=node_data[N-1].id; 127} 128 129void pop() 130{ 131 for (int i=0; i<N-1; i++) { 132 node_data[i].id=node_data[i+1].id; 133 node_data[i].cost=node_data[i+1].cost; 134 } 135 for (int i=0; i<N-1; i++) { 136 node_idx[node_data[i].id]=node_data[i].id; 137 } 138 node_idx[node_data[N-1].id]=node_data[N-1].id; 139} 140void change(int id, int cost) 141{ 142 int old; 143 old=node_data[node_idx[id]].cost; 144 node_data[node_idx[id]].cost=cost; 145 if (old>node_data[node_idx[id]].cost) down_heap(node_idx[id]); 146 else up_heap(node_idx[id]); 147} 148void print_path() 149{ 150 if (path[N-1] == -1) 151 cout << "Unreachable!" << endl; 152 else { 153 rec_print_path(N-1); 154 cout << endl; 155 cout << "cost: " << node_data[0].cost << endl; 156 } 157} 158 159void rec_print_path(int vertex) 160{ 161 path[0]=1; 162 for (auto next:graph[vertex]) { 163 if (path[next]==1) continue; 164 rec_print_path(next); 165 } 166} 167int main() 168{ 169 gen_graph(); 170 print_graph(); 171 172 init_heap(); 173 dijkstra(); 174 175 print_path(); 176 177 return 0; 178} 179
試したこと
イテレーターであるため, print_graph()を参考にdijkstra()を作成しました。rec_print_pathではfor(auto ...)を使って順に判定してみました。
補足情報(FW/ツールのバージョンなど)
C++17を利用しています。
回答1件
あなたの回答
tips
プレビュー