zoukankan      html  css  js  c++  java
  • python 回溯法 子集树模板 系列 —— 8、图的遍历

    问题

    一个图:
    A --> B
    A --> C
    B --> C
    B --> D
    B --> E
    C --> A
    C --> D
    D --> C
    E --> F
    F --> C
    F --> D

    从图中的一个节点E出发,不重复地经过所有其它节点后,回到出发节点E,称为一条路径。请找出所有可能的路径。

    分析

    将这个图可视化如下:

    本问题涉及到图,那首先要考虑图用那种存储结构表示。邻接矩阵、邻接表、...都不太熟。

    百度一下,在这里发现了一个最爱。这是网上找到一种最简洁的邻接表表示方式。

    接下来对问题本身进行分析:

    显然,问题的解的长度是固定的,亦即所有的路径长度都是固定的:n(不回到出发节点) 或 n+1(回到出发节点)

    每个节点,都有各自的邻接节点。

    对某个节点来说,它的所有邻接节点,可以看作这个节点的状态空间。遍历其状态空间,剪枝,深度优先递归到下一个节点。搞定!

    至此,很明显套用回溯法子集树模板。

    代码

    '''
    图的遍历
    
    从一个节点出发,不重复地经过所有其它节点后,回到出发节点。找出所有的路径
    '''
    
    # 用邻接表表示图
    n = 6  # 节点数
    a,b,c,d,e,f = range(n) # 节点名称
    graph = [
        {b,c},
        {c,d,e},
        {a,d},
        {c},
        {f},
        {c,d}
    ]
    
    x = [0]*(n+1)  # 一个解(n+1元数组,长度固定)
    X = []         # 一组解
    
    
    # 冲突检测
    def conflict(k):
        global n,graph,x
        
        # 第k个节点,是否前面已经走过
        if k < n and x[k] in x[:k]:
            return True
            
        # 回到出发节点
        if k == n and x[k] != x[0]:
            return True
            
        return False # 无冲突
        
    
    # 图的遍历
    def dfs(k): # 到达(解x的)第k个节点
        global n,a,b,c,d,e,f,graph,x,X
        
        if k > n: # 解的长度超出,已走遍n+1个节点 (若不回到出发节点,则 k==n)
            print(x)
            #X.append(x[:])
        else:
            for node in graph[x[k-1]]: # 遍历节点x[k]的邻接节点(x[k]的所有状态)
                x[k] = node
                if not conflict(k): # 剪枝
                    dfs(k+1)
                    
    # 测试
    x[0] = e # 出发节点
    dfs(1)   # 开始处理解x中的第2个节点
    

    效果图

  • 相关阅读:
    php.ini中设置session过期时间
    IP(Internet Protocal) 地址 说明
    html年月日下拉联动菜单 年月日三下拉框联动
    使用数组的键值,做为变量名的方法
    html中js只允许输入数字
    阿里云服务器问题攻略
    小帆远行
    Android图片转换类 1. Bitmap去色,转换为黑白的灰度图, 2. Bitmap图片加圆角效果
    EditText禁止输入回车
    Android之系统自带的文字外观设置
  • 原文地址:https://www.cnblogs.com/hhh5460/p/6928465.html
Copyright © 2011-2022 走看看