当前位置:  开发笔记 > 编程语言 > 正文

找到两个给定节点之间的路径?

如何解决《找到两个给定节点之间的路径?》经验,为你挑选了3个好方法。

假设我以下面的方式连接节点,我如何得出给定点之间存在的路径数量和路径详细信息?

1,2 //node 1 and 2 are connected
2,3
2,5
4,2
5,11
11,12
6,7
5,6
3,6
6,8
8,10
8,9

找到1到7的路径:

答案:找到2条路径,它们是

1,2,3,6,7
1,2,5,6,7

替代文字

在这里找到的实现很好,我将使用相同的

这是python中上面链接的片段

# a sample graph
graph = {'A': ['B', 'C','E'],
             'B': ['A','C', 'D'],
             'C': ['D'],
             'D': ['C'],
             'E': ['F','D'],
             'F': ['C']}

class MyQUEUE: # just an implementation of a queue

    def __init__(self):
        self.holder = []

    def enqueue(self,val):
        self.holder.append(val)

    def dequeue(self):
        val = None
        try:
            val = self.holder[0]
            if len(self.holder) == 1:
                self.holder = []
            else:
                self.holder = self.holder[1:]   
        except:
            pass

        return val  

    def IsEmpty(self):
        result = False
        if len(self.holder) == 0:
            result = True
        return result


path_queue = MyQUEUE() # now we make a queue


def BFS(graph,start,end,q):

    temp_path = [start]

    q.enqueue(temp_path)

    while q.IsEmpty() == False:
        tmp_path = q.dequeue()
        last_node = tmp_path[len(tmp_path)-1]
        print tmp_path
        if last_node == end:
            print "VALID_PATH : ",tmp_path
        for link_node in graph[last_node]:
            if link_node not in tmp_path:
                #new_path = []
                new_path = tmp_path + [link_node]
                q.enqueue(new_path)

BFS(graph,"A","D",path_queue)

-------------results-------------------
['A']
['A', 'B']
['A', 'C']
['A', 'E']
['A', 'B', 'C']
['A', 'B', 'D']
VALID_PATH :  ['A', 'B', 'D']
['A', 'C', 'D']
VALID_PATH :  ['A', 'C', 'D']
['A', 'E', 'F']
['A', 'E', 'D']
VALID_PATH :  ['A', 'E', 'D']
['A', 'B', 'C', 'D']
VALID_PATH :  ['A', 'B', 'C', 'D']
['A', 'E', 'F', 'C']
['A', 'E', 'F', 'C', 'D']
VALID_PATH :  ['A', 'E', 'F', 'C', 'D']

Konrad Rudol.. 33

广度优先搜索遍历图形,实际上从起始节点查找所有路径.但是,通常,BFS不会保留所有路径.相反,它更新前驱函数π以保存最短路径.您可以轻松修改算法,?(n)这样不仅可以存储一个前任,还可以存储可能的前任列表.

然后在此函数中编码所有可能的路径,并通过递归遍历π,获得所有可能的路径组合.

使用这种表示法的一个好的伪代码可以在Cormen 等人的Introduction to Algorithms中找到.并随后在许多大学的剧本中使用过这个主题.谷歌搜索"BFS伪代码前身π" 在Stack Exchange上取消了这一打击.



1> Konrad Rudol..:

广度优先搜索遍历图形,实际上从起始节点查找所有路径.但是,通常,BFS不会保留所有路径.相反,它更新前驱函数π以保存最短路径.您可以轻松修改算法,?(n)这样不仅可以存储一个前任,还可以存储可能的前任列表.

然后在此函数中编码所有可能的路径,并通过递归遍历π,获得所有可能的路径组合.

使用这种表示法的一个好的伪代码可以在Cormen 等人的Introduction to Algorithms中找到.并随后在许多大学的剧本中使用过这个主题.谷歌搜索"BFS伪代码前身π" 在Stack Exchange上取消了这一打击.



2> ritesh_NITW..:

对于那些不是PYTHON专家的人来说,C++中的代码相同

//@Author :Ritesh Kumar Gupta
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
vector >GRAPH(100);
inline void print_path(vectorpath)
{
    cout<<"[ ";
    for(int i=0;ipath)
{
    for(int i=0;ipath;
    path.push_back(source);
    queue >q;
    q.push(path);

    while(!q.empty())
    {
        path=q.front();
        q.pop();

        int last_nodeof_path=path[path.size()-1];
        if(last_nodeof_path==target)
        {
            cout<<"The Required path is:: ";
            print_path(path);
        }
        else
        {
            print_path(path);
        }

        for(int i=0;inew_path(path.begin(),path.end());
                new_path.push_back(GRAPH[last_nodeof_path][i]);
                q.push(new_path);
            }
        }




    }
    return 1;
}
int main()
{
    //freopen("out.txt","w",stdout);
    int T,N,M,u,v,source,target;
    scanf("%d",&T);
    while(T--)
    {
        printf("Enter Total Nodes & Total Edges\n");
        scanf("%d%d",&N,&M);
        for(int i=1;i<=M;++i)
        {
            scanf("%d%d",&u,&v);
            GRAPH[u].push_back(v);
        }
        printf("(Source, target)\n");
        scanf("%d%d",&source,&target);
        findpaths(source,target,N,M);
    }
    //system("pause");
    return 0;
}

/*
Input::
1
6 11
1 2 
1 3
1 5
2 1
2 3
2 4
3 4
4 3
5 6
5 4
6 3
1 4

output:
[ 1 ]
[ 1 2 ]
[ 1 3 ]
[ 1 5 ]
[ 1 2 3 ]
The Required path is:: [ 1 2 4 ]
The Required path is:: [ 1 3 4 ]
[ 1 5 6 ]
The Required path is:: [ 1 5 4 ]
The Required path is:: [ 1 2 3 4 ]
[ 1 2 4 3 ]
[ 1 5 6 3 ]
[ 1 5 4 3 ]
The Required path is:: [ 1 5 6 3 4 ]


*/



3> Marc..:

Dijkstra的算法更适用于加权路径,听起来海报想要找到所有路径,而不仅仅是最短路径.

对于这个应用程序,我将构建一个图形(您的应用程序听起来不需要被定向)并使用您最喜欢的搜索方法.听起来你想要所有的路径,而不仅仅是猜测最短路径,所以使用你选择的简单递归算法.

唯一的问题是图形是否可以是循环的.

通过连接:

1,2

1,3

2,3

2,4

在寻找1-> 4的路径时,您可以使用1 - > 2 - > 3 - > 1的循环.

在那种情况下,然后我将堆栈作为遍历节点.这是一个列表,其中包含该图表的步骤和生成的堆栈(抱歉格式化 - 没有表格选项):

当前节点(可能的下一个节点减去我们来自哪里)[stack]

    1(2,3)[1]

    2(3,4)[1,2]

    3(1)[1,2,3]

    1(2,3)[1,2,3,1] //错误 - 堆栈上的重复数字 - 检测到循环

    3()[1,2,3] //后退到节点3并从堆栈中弹出1.没有更多的节点可以从这里探索

    2(4)[1,2] //后退到节点2并从堆栈中弹出1.

    4()[1,2,4] //找到目标节点 - 记录路径的堆栈.没有更多的节点可以从这里探索

    2()[1,2] //后退到节点2并从堆栈中弹出4.没有更多的节点可以从这里探索

    1(3)[1] //后退到节点1并从堆栈中弹出2.

    3(2)[1,3]

    2(1,4)[1,3,2]

    1(2,3)[1,3,2,1] //错误 - 堆栈上的重复数字 - 检测到循环

    2(4)[1,3,2] //后退到节点2并从堆栈弹出1

    4()[1,3,2,4]找到目标节点 - 记录路径的堆栈.没有更多的节点可以从这里探索

    2()[1,3,2] //后退到节点2并从堆栈中弹出4.没有更多的节点

    3()[1,3] //后退到节点3并从堆栈中弹出2.没有更多的节点

    1()[1] //后退到节点1并从堆栈中弹出3.没有更多的节点

    完成了[1,2,4]和[1,3,2,4]的2条记录路径

推荐阅读
个性2402852463
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有