大家好,星期五快乐。我正在完成这项工作,其中涉及实现图形数据结构以及邻接表和矩阵。它还要求确定是否可以一次绘制图形(我通过确定图形是欧拉还是半欧拉来完成此操作)。 我遇到的问题是,仅当图形为半欧拉(它具有2个奇数度的节点)时,我的打印路径的算法才有效。如果我在所有顶点均具有偶数度的图形中进行尝试,它将在图形中打印出一个不包含所有边的循环。该程序应采用命令行参数,该参数是包含用于构建图形的数据的文件的名称。
每个文件如下所示:
5 6
1 2
2 3
3 1
2 4
4 5
5 2
第一个数字是顶点数,第二个数字是边数。然后其余的线是边缘。例如,在上面的文件中,有5个顶点和6条边,并且在顶点1和2之间有一条边,依此类推。我的程序可以构建图形并将其正确打印出来,但是路径出现问题。
我已经实现了这样的类:
#include<vector>
#include<iostream>
#include<stack>
#include<list>
using namespace std;
class Graph{
private:
int num_vertices;
int num_edges;
vector<list<int> > adj_list;
vector<vector<int> > adj_matrix;
public:
void insertVertex_adjList(int to_insert);
void insertVertex(int to_insert);
void insertVertex_adjMatrix(int to_insert);
void insertEdge(int x,int y);
void insertEdge_adjList(int x, int y);
void insertEdge_adjMatrix(int x, int y);
void removeEdge(int x, int y);
void removeEdge_adjList(int x, int y);
void removeEdge_adjMatrix(int x, int y);
Graph():num_vertices(0),num_edges(0){
adj_matrix.push_back(vector<int>(1,0));
};
void print_AdjList();
void print_AdjMatrix();
int getNumEdges(){return num_edges;}
int getNumVertices(){return num_vertices;}
bool has_eularian_path();
bool has_eularian_circuit();
void find_eularian_path();
bool eulerian_path_helper(Graph &G, int u, stack<int> &s);
int number_of_adjacent(list<int> A){return A.size()-1;}
bool is_bridge(int x, int y);
};
Graph TesterHelper(int argc, char *argv[]);
这就是我寻找路径所涉及的函数的样子:
bool Graph::eulerian_path_helper(Graph &G, int u, stack<int> &s){
s.push(u);
if(adj_list[u-1].size()-1 == 0) return true;
else{
for(list<int>::iterator i = ++adj_list[u-1].begin(); i != adj_list[u-1].end();i++){
G.removeEdge(u,*i);
if(G.eulerian_path_helper(G,*i,s) == true) return true;
else{
G.insertEdge(u,*i);
}
}
s.pop();
return false;
}
}
void Graph::find_eularian_path(){
Graph G = *this; //to not mess with original graph.
stack<int> s;
int current = *adj_list[0].begin();
if(G.has_eularian_circuit() == true) current = *adj_list[0].begin();
else if(G.has_eularian_circuit()== false && G.has_eularian_path()==true){
int current_size = adj_list[current].size() - 1;
int odds = 0;
for(int i =0; odds < 1; i++){
current_size = adj_list[i].size()-1;
if(current_size % 2 != 0) odds++;
current = *adj_list[i].begin();
}
}
else{
cout << "Graph has no Euliarian Path";
return;
}
eulerian_path_helper(G,current,s);
while (!s.empty())
{
cout << ' ' << s.top();
s.pop();
}
cout << endl;
return;
}
Graph TesterHelper(int argc, char *argv[]){
Graph to_return;
fstream file;
switch(argc){
case 1:
cout << "No file specified.";
return to_return;
case 2:
file.open(argv[1]);
if(file.is_open()==false){
cout << "Invalid file name or error opening.";
return to_return;
}
break;
}
int n, m, a;
file >> n;
file >> m;
for(int i = 0; i < m;i++){
file >> n;
file >> a;
to_return.insertEdge(n,a);
}
to_return.print_AdjList();
cout << endl;
to_return.print_AdjMatrix();
cout << endl;
if(to_return.has_eularian_circuit() == true){
cout << "Graph is Eularian and can be drawn in one stroke starting from any vertex.";
}
else if(to_return.has_eularian_circuit() == false && to_return.has_eularian_path() == true ){
cout << "Graph is semi-Eularian and can be drawn in one stroke starting at any of the 2 vertices with odd degree.";
}
if(to_return.has_eularian_circuit() == false && to_return.has_eularian_path() == false){
cout << "Graph can not be drawn in a single stroke.";
}
return to_return;
}
最后main看起来像这样:
#include<iostream>
#include"Graph_Adjacency_List.h"
using namespace std;
int main(int argc, char *argv[]){
Graph test = TesterHelper(argc,argv);
test.find_eularian_path();
}
如果我运行的程序带有一个构建带有2个奇数度顶点的图形的文件,则一切正常。
例如,此文件:
5 7
1 2
2 3
3 1
2 4
4 5
5 2
5 3
我得到以下正确的输出:
:: ./a.out graph1.data
1->2->3
2->1->3->4->5
3->2->1->5
4->2->5
5->4->2->3
0 0 0 0 0 0
0 0 1 1 0 0
0 1 0 1 1 1
0 1 1 0 0 1
0 0 1 0 0 1
0 0 1 1 1 0
Graph is semi-Eularian and can be drawn in one stroke starting at any of the 2 vertices with odd degree.
5 2 4 5 3 1 2 3
但是使用所有顶点都为偶数的文件运行该文件将失败。
5 6
1 2
1 3
2 3
2 4
2 5
4 5
这样打印不完整的路径:
:: ./a.out graph2.data
1->2->3
2->1->3->4->5
3->1->2
4->2->5
5->2->4
0 0 0 0 0 0
0 0 1 1 0 0
0 1 0 1 1 1
0 1 1 0 0 0
0 0 1 0 0 1
0 0 1 0 1 0
Graph is Eularian and can be drawn in one stroke starting from any vertex.
1 3 2 1
对于冗长的帖子,我感到抱歉,但是我认为,如果其中不包含上面所有的信息,那将不是一个完整的例子。如果有人能提供解决方法的见解,我将不胜感激。预先谢谢你!