先週、ダイクストラのアルゴリズムを適用してグラフ内のノード間の最短経路を計算するコードを投稿しました。私はいくつかの改善を行いましたが、まだ立ち往生しています。
クラスがありGraph
ます。Edge
これは、クラスのインスタンスのベクトルと、クラスの要素の別のベクトルの2 つの他のクラスによって構築されますVertex
。carried
すべての頂点には、ソース ノードからの累積距離を保持するためのID と aがあり、すべてのエッジには 2 つの頂点と重みがあります。
クラスGraph
にはメソッドがあります。その名前はshortest
で、2 つの頂点を引数として取ります。1 つ目はグラフのソースで、2 つ目は目的地です。
私のアプローチは、ソース頂点に接続されているエッジを排除しようとし、それらの重みを隣接する頂点に追加してcarried
、フィールドに保存しVertex
、すべての頂点の状況を追跡し続けることです。次に、その上にある最も低い頂点ベースをcarried
新しいソースとして選択し、エッジが 1 つだけになるまで同じ操作を繰り返します。
結果を示すために、5 つの頂点を持つグラフを初期化し、vers[0], vers[1], vers[2], vers[3], vers[4]
これらの頂点を接続する 10 個のエッジが から始まりeds[0], eds[1], ....eds[9]
ます。
宛先頂点はvers[4]
ソース頂点vers[2]
が 4 つのエッジで接続されているため、メソッドを適用すると、shortest
以下のコードに示すように、これらのエッジの 4 つすべてを取り除き、最初のエッジの最後に 6 つのエッジで終わる必要があります。円形。結果は次のとおりです。
Hello, This is a graph
0____1 5
0____3 4
0____4 6
1____3 5
1____4 7
3____4 3
size of edges 6
size of vertices 4
curried vertex_0 9
curried vertex_1 2
curried vertex_2 1
curried vertex_3 8
2 であるソース頂点が表示されず、ソース頂点に接続された 4 つのエッジを削除した後、わずか 6 つのエッジで終わったため、結果はこれまでのところ良好に見えます。さらに、右側、つまりすべての辺の重みを計算する必要があり、下にはcarried
残りの各頂点の重みがあります。
2 回目のラウンドを実行すると、次の結果が得られます。
Hello, This is a graph
0____1 5
0____4 6
1____4 7
size of edges 3
size of vertices 3
curried vertex_0 9
curried vertex_1 2
curried vertex_2 8
ご覧のとおり、3 つのエッジ (これは正しい) と 3 つの頂点 (これも正しい) が残っており、エッジの重みは正しいですが、問題は、carried
各頂点の値が正しくないため、コードが選択されることです。次のラウンドで続行するには間違ったソース。つまり、5, 2, 4
代わりに が必要です9, 2, 8
。
問題がどこにあるかはわかりますが、正しい解決策が得られない理由がわかりません。問題は、コードに示されているアスタリスクの行の間にあると思います。
コードは次のとおりです。
#include<iostream>
#include<vector>
#include <stdlib.h> // for rand()
using namespace std;
class Vertex
{
private:
unsigned int id; // the name of the vertex
unsigned int carried; // the weight a vertex may carry when calculating shortest path
public:
unsigned int get_id(){return id;};
unsigned int get_carried(){return carried;};
void set_id(unsigned int value) {id = value;};
void set_carried(unsigned int value) {carried = value;};
inline bool operator==( const Vertex& ver_1){ return id == ver_1.id;};
Vertex(unsigned int init_val = 0, unsigned int init_carried = 0) :id (init_val), carried(init_carried) // constructor
{}
~Vertex() {}; // destructor
};
class Edge
{
private:
Vertex first_vertex; // a vertex on one side of the edge
Vertex second_vertex; // a vertex on the other side of the edge
unsigned int weight; // the value of the edge ( or its weight )
public:
unsigned int get_weight() {return weight;};
void set_weight(unsigned int value) {weight = value;};
Vertex get_ver_1(){return first_vertex;};
Vertex get_ver_2(){return second_vertex;};
void set_first_vertex(Vertex v1) {first_vertex = v1;};
void set_second_vertex(Vertex v2) {second_vertex = v2;};
Edge(const Vertex& vertex_1 = 0, const Vertex& vertex_2 = 0, unsigned int init_weight = 0)
: first_vertex(vertex_1), second_vertex(vertex_2), weight(init_weight) {}
~Edge() {} ; // destructor
};
class Graph
{
private:
std::vector<Vertex> vertices;
std::vector<Edge> edges;
public:
Graph(vector<Vertex> ver_vector, vector<Edge> edg_vector)
: vertices(ver_vector), edges(edg_vector){}
~Graph() {}
vector<Vertex> get_vertices(){return vertices;}
vector<Edge> get_edges(){return edges;}
void set_vertices(vector<Vertex> vector_value) {vertices = vector_value;}
void set_edges(vector<Edge> vector_ed_value) {edges = vector_ed_value;}
unsigned int shortest(Vertex src, Vertex dis);
};
unsigned int Graph::shortest(Vertex src, Vertex dis) {
vector<Vertex> ver_out;
vector<Edge> track;
for (unsigned int i = 0; i < edges.size();) {
if ((edges[i].get_ver_1() == src) || (edges[i].get_ver_2() == src)) {
track.push_back(edges[i]);
if (edges[i].get_ver_1() == src) {
ver_out.push_back(edges[i].get_ver_2());
ver_out.back().set_carried(edges[i].get_weight());
} else {
ver_out.push_back(edges[i].get_ver_1());
ver_out.back().set_carried(edges[i].get_weight());
}
edges.erase(edges.begin() + i);
} else {
++i; // increment only if not erasing
}
}
for(unsigned int i = 0; i < vertices.size(); ++i)
for(unsigned int iii = 0; iii < ver_out.size(); ++iii) {
if(vertices[i] == ver_out[iii]){vertices[i].set_carried(ver_out[iii].get_carried());};};
for(unsigned int i = 0; i < vertices.size(); ++i)
if(vertices[i] == src) vertices.erase(vertices.begin() + i);
track.clear();
if(!(ver_out[0] == dis)) {src = ver_out[0];}
else {src = ver_out[1];}
for(unsigned int i = 0; i < ver_out.size(); ++i)
if((ver_out[i].get_carried() < src.get_carried()) && (!(ver_out[i] == dis)))
src = ver_out[i];
ver_out.clear();
for(unsigned int round = 0; round < 1 ; ++round) //vertices.size()
{
for(unsigned int k = 0; k < edges.size(); )
{
if((edges[k].get_ver_1() == src) || (edges[k].get_ver_2() == src))
{
track.push_back (edges[k]);
for(unsigned int i = 0; i < vertices.size(); ++i)
{
if(track.back().get_ver_1() == vertices[i]) edges[k].get_ver_1().set_carried(vertices[i].get_carried());
if(track.back().get_ver_2() == vertices[i]) edges[k].get_ver_2().set_carried(vertices[i].get_carried());
}
if(track.back().get_ver_1() == src)
{
ver_out.push_back (track.back().get_ver_2()); //************************************
if(track.back().get_ver_2().get_carried() > (track.back().get_ver_1().get_carried() + track.back().get_weight())) //<===
ver_out.back().set_carried(track.back().get_ver_1().get_carried() + track.back().get_weight());
else ver_out.back().set_carried(track.back().get_ver_2().get_carried());
}
else{
ver_out.push_back (track.back().get_ver_1());
if(track.back().get_ver_1().get_carried() > (track.back().get_ver_2().get_carried() + track.back().get_weight())) // <===
ver_out.back().set_carried(track.back().get_ver_2().get_carried() + track.back().get_weight());
else {ver_out.back().set_carried(track.back().get_ver_1().get_carried());}
}
//*****************************
edges.erase(edges.begin() + k);
}
else{
++k; // increment only if not erasing
}
};
for(unsigned int t = 0; t < vertices.size(); ++t)
if(vertices[t] == src) vertices.erase(vertices.begin() + t);
track.clear();
if(!(ver_out[0] == dis)) {src = ver_out[0];}
else {src = ver_out[1];}
for(unsigned int tt = 0; tt < edges.size(); ++tt)
{
if(ver_out[tt].get_carried() < src.get_carried())
{
src = ver_out[tt];
}
}
ver_out.clear();
}
if(edges[0].get_ver_1() == dis) return edges[0].get_weight() +edges[0].get_ver_2().get_carried();
else return edges[0].get_weight() +edges[0].get_ver_1().get_carried();
}
int main()
{
cout<< "Hello, This is a graph"<< endl;
vector<Vertex> vers(5);
vers[0].set_id(0);
vers[1].set_id(1);
vers[2].set_id(2);
vers[3].set_id(3);
vers[4].set_id(4);
vector<Edge> eds(10);
eds[0].set_first_vertex(vers[0]);
eds[0].set_second_vertex(vers[1]);
eds[0].set_weight(5);
eds[1].set_first_vertex(vers[0]);
eds[1].set_second_vertex(vers[2]);
eds[1].set_weight(9);
eds[2].set_first_vertex(vers[0]);
eds[2].set_second_vertex(vers[3]);
eds[2].set_weight(4);
eds[3].set_first_vertex(vers[0]);
eds[3].set_second_vertex(vers[4]);
eds[3].set_weight(6);
eds[4].set_first_vertex(vers[1]);
eds[4].set_second_vertex(vers[2]);
eds[4].set_weight(2);
eds[5].set_first_vertex(vers[1]);
eds[5].set_second_vertex(vers[3]);
eds[5].set_weight(5);
eds[6].set_first_vertex(vers[1]);
eds[6].set_second_vertex(vers[4]);
eds[6].set_weight(7);
eds[7].set_first_vertex(vers[2]);
eds[7].set_second_vertex(vers[3]);
eds[7].set_weight(1);
eds[8].set_first_vertex(vers[2]);
eds[8].set_second_vertex(vers[4]);
eds[8].set_weight(8);
eds[9].set_first_vertex(vers[3]);
eds[9].set_second_vertex(vers[4]);
eds[9].set_weight(3);
unsigned int path;
Graph graf(vers, eds);
path = graf.shortest(vers[2], vers[4]);
cout<<graf.get_edges()[0].get_ver_1().get_id() <<"____"<<graf.get_edges()[0].get_ver_2().get_id() <<" "<<graf.get_edges()[0].get_weight()<< endl; //test
cout<<graf.get_edges()[1].get_ver_1().get_id() <<"____"<<graf.get_edges()[1].get_ver_2().get_id() <<" "<<graf.get_edges()[1].get_weight()<< endl; //test
cout<<graf.get_edges()[2].get_ver_1().get_id() <<"____"<<graf.get_edges()[2].get_ver_2().get_id() <<" "<<graf.get_edges()[2].get_weight()<< endl; //test
//cout<<graf.get_edges()[3].get_ver_1().get_id() <<"____"<<graf.get_edges()[3].get_ver_2().get_id() <<" "<<graf.get_edges()[3].get_weight()<< endl; //test
//cout<<graf.get_edges()[4].get_ver_1().get_id() <<"____"<<graf.get_edges()[4].get_ver_2().get_id() <<" "<<graf.get_edges()[4].get_weight()<< endl; //test
//cout<<graf.get_edges()[5].get_ver_1().get_id() <<"____"<<graf.get_edges()[5].get_ver_2().get_id() <<" "<<graf.get_edges()[5].get_weight()<< endl; //test
//cout<<graf.get_edges()[6].get_ver_1().get_id() <<"____"<<graf.get_edges()[6].get_ver_2().get_id() <<" "<<graf.get_edges()[6].get_weight()<< endl; //test
//cout<<graf.get_edges()[7].get_ver_1().get_id() <<"____"<<graf.get_edges()[7].get_ver_2().get_id() <<" "<<graf.get_edges()[7].get_weight()<< endl; //test
//cout<<graf.get_edges()[8].get_ver_1().get_id() <<"____"<<graf.get_edges()[8].get_ver_2().get_id() <<" "<<graf.get_edges()[8].get_weight()<< endl; //test
//cout<<graf.get_edges()[9].get_ver_1().get_id() <<"____"<<graf.get_edges()[9].get_ver_2().get_id() <<" "<<graf.get_edges()[9].get_weight()<< endl; //test
cout<<"size of edges "<<graf.get_edges().size()<< endl;
cout<<"size of vertices "<<graf.get_vertices().size()<< endl;
cout<<"curried vertex_0 "<<graf.get_vertices()[0].get_carried()<< endl;
cout<<"curried vertex_1 "<<graf.get_vertices()[1].get_carried()<< endl;
cout<<"curried vertex_2 "<<graf.get_vertices()[2].get_carried()<< endl;
//cout<<"curried vertex_3 "<<graf.get_vertices()[3].get_carried()<< endl;
//cout<< path << endl;
return 0;
}