Algorithm 在长度在给定用户定义范围内的加权无向图中找到一个简单圈
已编辑-12/03/12太平洋标准时间凌晨1:05 我编辑了我的代码如下。但是,我仍然无法让它返回任何路径 同样,这段代码是要计算一条路径,由用户指定起始顶点和距离。程序将返回与指定数据匹配的所有适当路径 以下是我目前的代码:Algorithm 在长度在给定用户定义范围内的加权无向图中找到一个简单圈,algorithm,graph,routes,depth-first-search,Algorithm,Graph,Routes,Depth First Search,已编辑-12/03/12太平洋标准时间凌晨1:05 我编辑了我的代码如下。但是,我仍然无法让它返回任何路径 同样,这段代码是要计算一条路径,由用户指定起始顶点和距离。程序将返回与指定数据匹配的所有适当路径 以下是我目前的代码: vector<vector<Vertex>> Graph::FindPaths(Graph &g, int startingIntersection, float distanceInMiles) { /* A vector whic
vector<vector<Vertex>> Graph::FindPaths(Graph &g, int startingIntersection, float distanceInMiles)
{
/* A vector which contains vectors which will contain all of the suitable found paths. */
vector<vector<Vertex>> paths;
/* Create an empty set to store the visited nodes. */
unordered_set<int> visited;
/* Vector which will be used to the hold the current path. */
vector<Vertex> CurrentPathList;
/* Will be used to store the currerntVertex being examined. */
Vertex currentVertex;
/* Will be used to store the next vertex ID to be evaluated. */
int nextVertex;
/* Will be used to determine the location of the start ID of a vertex within the VertexList. */
int start;
/* Stack containing the current paths. */
stack<Vertex> currentPaths;
/* CurrentPathDistance will be used to determine the currernt distance of the path. */
float currentPathDistance = 0;
/* The startingIntersection location must be found within the VertexList. This is because there is
* no guarantee that the VertexList will hold sequential data.
*
* For example, the user inputs a startingIntersection of 73. The Vertex for intersection #73 may
* be located at the 20th position of the VertexList (i.e. VertexList[20]). */
start = g.FindStartingIntersection(g, startingIntersection);
/* Push the startingIntersection onto the stack. */
currentPaths.push(g.VertexList[start]);
/* Continue to iterate through the stack until it is empty. Once it is empty we have exhaused all
* possible paths. */
while(!currentPaths.empty())
{
/* Assign the top value of the stack to the currentVertex. */
currentVertex = currentPaths.top();
/* Pop the top element off of the stack. */
currentPaths.pop();
/* Check to see if we are back to the startingIntersection. As a note, if we are just starting, it will
* put the startingIntersection into the paths. */
if(currentVertex.id == startingIntersection)
{
/* Add currentVertex to a list. */
CurrentPathList.push_back(currentVertex);
/* Find the current path distance. */
currentPathDistance = FindPathDistance(g, CurrentPathList);
/* Check the currentPathDistance. If it is within +/- 1 mile of the specified distance, then place
* it into the vector of possible paths. */
if((currentPathDistance + 1 >= distanceInMiles) && (currentPathDistance - 1 <= distanceInMiles))
{
paths.push_back(CurrentPathList);
}
}
else /* The ending vertex was not the user specified starting vertex. */
{
/* Remove all elements from the stack. */
while(!currentPaths.empty())
{
currentPaths.pop();
}
}
nextVertex = FindUnvisitedNeighbor(g, currentVertex, visited);
// repeat while current has unvisited neighbors
while(nextVertex != -1)
{
/* Find the new starting vertex. */
start = g.FindStartingIntersection(g, nextVertex);
/* Push the startingIntersection onto the stack. */
currentPaths.push(g.VertexList[start]);
/* Push the next vertex into the visted list. */
visited.insert(nextVertex);
nextVertex = FindUnvisitedNeighbor(g, currentVertex, visited);
}
}
/* Return the vector of paths that meet the criteria specified by the user. */
return paths;
深度优先是好的。你必须在
* path too long (bad)
* vertex already visited (bad)
* starting vertex visited (found a solution)
要检测这些条件,必须跟踪到目前为止访问的边/顶点
深度firs漫游看起来像这样(完全未选中)伪代码不管怎么说,你应该明白这一点
edge
pair of node
length
node
list of edge
arrow // incoming edge, node
pair of edge, node
path
list of arrow
check_node(arrow) // incoming edge, node
current_path.push(arrow)
if length(current_path) > limit
// abort too long
current_path.pop(arrow)
return
if length(current_path) > 0 && current_path.first.node == current_path.last,node
// found solution
solutions.push(current_path) // store the found solution and continue search
current_path.pop(arrow)
return
if node in current_path
// abort cycle
current_path.pop(arrow)
return
for each edge in node
// go deeper
check(arrow(edge, edge.other_node))
current_path.pop(arrow)
return
main
path current_path
list of path solutions // will hold all possible solutions after the check
make_graph
check_node(NULL, graph.start)
for each solution in solutions // print 0 .. n solutions
print solution
这似乎是一个基本的算法问题,而不是特定于实现的问题,因此我为算法提供了详细的高级伪代码,而不是实际代码。另外,我不知道C++。如果任何语法/逻辑不清楚,请告诉我,我可以进一步澄清。它本质上执行DFS,但在找到值时不会停止:它继续搜索,并报告该值的所有路径(满足给定的距离标准)
// Input: List path, Graph G
// Output: Integer weight
FindPathWeight ( path, G ):
Integer weight = 0;
for each ( Vertex v in path ):
if ( v is the end of the path ): break
Consider the next vertex in the list, u
Find the edge v——u in the graph, call it e
Get the weight of e, w
weight = weight + w
return weight
//EndFindPathWeight
// Input: Vertex v, Graph G, Set visited
// Output: Vertex u (or null, if there are none)
FindUnvisitedNeighbor ( v, G, visited ):
for each ( Edge v——u in G.EdgeList ):
if ( u in visited ): continue
// u is the first unvisited neighbor
return u
return null
//EndFindUnvisitedNeighbor
二,建议:一,。删除上面的代码段。它们与你的问题无关,而且你的问题很长。2.将标题改为“在长度在给定范围内的加权无向图中找到一个简单循环”,请澄清。这个图满足三角形不等式吗?谢谢你的输入!我已经按照你的建议编辑了问题和标题。不幸的是,我不知道你所说的“三角不等式”是什么意思=(所以我要说的是,它不是,因为我在课堂上没有听说过这个词。你忘了回答我的问题。这张图满足三角形不等式吗?如果它是真实世界的地图,它满足。我认为他不应该假设三角形不等式成立。想象一下一座山附近有三条路。其中两条路连接起来,从一个角度绕着山走一边的A点到另一边的B点,每段2英里。从A点到B点翻山是4.4英里。感谢这个算法!我要试一试。大家好,我已经尽了最大努力实现这个算法。但是,我现在很难弄清楚如何通过这个没有监听的邻居我用我已经完成的代码编辑了我的原始文章。@克里斯托弗你需要<代码> SETTHECTON/CODEC>来跟踪访问的节点。C++似乎有一个内置的<代码> unOrdEdset set <代码>,这是一个完美的集合:它是一个哈希集,所以你可以检查它是否包含一个元素非常快。ly,in
O(1)
current
在我的伪代码中是一个顶点,但看起来您可能在那里使用了不同的数据结构。路径
是一组顶点列表。我将添加两个额外的函数来查找权重和邻域。@Christopher另外,因为您的current
是一个向量,所以您使用的是indexi
但你从未实际增加它。我认为这根本不需要是一个向量……谢谢你的帮助!现在就开始工作=)是的,这就是我需要做的。但是,我需要它来不断寻找解决方案(如果存在多个)满足距离标准。它会搜索所有解决方案。我在伪代码中添加了一些注释(intendation表示一个块)
// Input: List path, Graph G
// Output: Integer weight
FindPathWeight ( path, G ):
Integer weight = 0;
for each ( Vertex v in path ):
if ( v is the end of the path ): break
Consider the next vertex in the list, u
Find the edge v——u in the graph, call it e
Get the weight of e, w
weight = weight + w
return weight
//EndFindPathWeight
// Input: Vertex v, Graph G, Set visited
// Output: Vertex u (or null, if there are none)
FindUnvisitedNeighbor ( v, G, visited ):
for each ( Edge v——u in G.EdgeList ):
if ( u in visited ): continue
// u is the first unvisited neighbor
return u
return null
//EndFindUnvisitedNeighbor