图的应用拓扑排序

图的应用:拓扑排序(Toplogical Sort)

很多问题都介意转化为图,利用图算法解决,比如早餐吃薄煎饼的过程:

  1. 以动作为顶点,以先后次序为有向边

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1qLTg2m3-1614327070641)(C:\Users\93623\AppData\Roaming\Typora\typora-user-images\image-20210221154333432.png)]

  1. 工作流程图得到工作次序排列的算法称为"拓扑排序"

  2. 拓扑排序处理一个DAG,输出顶点的线性序列

    1. 使得两个顶点v,w,如果G中有(v,w)边,在线性序列中v就出现在w之前
  3. 拓扑序列广泛应用在依赖事件的排序上,还可以用在项目管理,数据库查询优化和矩阵乘法的次序优化上

  4. 拓扑排序可以采用DFS很好地实现

    1. 将工作流程建立为图,工作项是节点,依赖关系是有向边
    2. 工作流程图一定是个DAG,否则有循环依赖
    3. 对DAG图调用DFS算法,以得到每个顶点的"结束时间"
    4. 按照每个顶点的"结束时间"从大到小排序输出这个次序下的顶点列表
# coding: utf-8

from pythonds.graphs import Graph
# 通用深度优先搜索

class DFSGraph(Graph):
    """
    time, 发现时间,结束时间对于深度遍历是没有用的
    主要是用于强连通和拓扑
    """
    def __init__(self):
        super().__init__()
        self.time = 0

    def dfs(self):
        # 颜色的初始化, 将所有顶点的颜色都置为白色,前驱都为-1
        for aVertex in self:
            aVertex.setColor('white')
            aVertex.setPred(-1)
        for aVertex in self:
            # 如果还有未包括的顶点,则建森林
            if aVertex.getColor() == 'white':
                # print("wwwwwwwwww",aVertex.getId())
                self.dfsvisit(aVertex)

    def dfsvisit(self, startVertex):

        startVertex.setColor('gray')
        # 算法的步数加一
        self.time += 1
        startVertex.setDiscovery(self.time)
        for nextVertex in startVertex.getConnections():
            if nextVertex.getColor() == 'white':
                nextVertex.setPred(startVertex)
                # 深度优先递归访问
                self.dfsvisit(nextVertex)
        startVertex.setColor('black')
        self.time += 1
        startVertex.setFinish(self.time)
        print(startVertex.getId(), end=" ")


if __name__ == '__main__':

    # g = DFSGraph()
    # for i in range(6):
    #     g.addVertex(i)
    # # print(g.vertList)
    # g.addEdge(0, 1, 5)
    # g.addEdge(1, 2, 4)
    # g.addEdge(2, 3, 9)
    # g.addEdge(3, 4, 7)
    #
    # g.addEdge(4, 0, 1)
    # g.addEdge(0, 5, 2)
    # g.addEdge(5, 4, 8)
    # g.addEdge(3, 5, 3)
    # g.addEdge(5, 2, 1)
    # g.dfs()

    # g = DFSGraph()
    # g.addVertex('A')
    # g.addVertex('B')
    # g.addVertex('C')
    # g.addVertex('D')
    # g.addVertex('E')
    # g.addVertex('F')
    # g.addEdge('A', 'B', 1)
    # g.addEdge('B', 'C', 1)
    # g.addEdge('A', 'D', 1)
    # g.addEdge('B', 'D', 1)
    # g.addEdge('D', 'E', 1)
    # g.addEdge('E', 'F', 1)
    # g.addEdge('F', 'C', 1)
    # g.addEdge('E', 'B', 1)
    # g.dfs()
    # for node in g:
    #     print(node.getId(), node.getDiscovery(), node.getFinish())

    g = DFSGraph()
    g.addVertex('一个鸡蛋')
    g.addVertex('一勺油')
    g.addVertex('3/4杯牛奶')
    g.addVertex('一杯混合')
    g.addVertex('加热枫糖浆')
    g.addVertex('加热平底锅')
    g.addVertex('到入1/4杯')
    g.addVertex('翻面')
    g.addVertex('享用')
    g.addEdge('一个鸡蛋','一杯混合')
    g.addEdge('一勺油','一杯混合')
    g.addEdge('3/4杯牛奶','一杯混合')
    g.addEdge('一杯混合', '加热枫糖浆')
    g.addEdge('一杯混合', '到入1/4杯')
    g.addEdge('加热平底锅', '到入1/4杯')
    g.addEdge('到入1/4杯','翻面')
    g.addEdge('翻面','享用')
    g.addEdge('加热枫糖浆','享用')
    g.dfs()
    lists = []
    for node in g:
        print(node.getId(), node.getFinish(), node.getDiscovery())
        lists.append(node)

    # 根据结束时间,将定点按照递减顺序存储在列表中
    lists.sort(key=lambda x: -x.fin)
    print("==============")
    for node in lists:
        print(node.getId(), node.getDiscovery(), node.getFinish())

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值