首页 > 编程语言 > 详细

算法87-----DAG有向无环图的拓扑排序

时间:2019-03-09 15:32:01      阅读:142      评论:0      收藏:0      [点我收藏+]

一、题目:课程排表---210

课程表上有一些课,是必须有修学分的先后顺序的,必须要求在上完某些课的情况下才能上下一门。问是否有方案修完所有的课程?如果有的话请返回其中一个符合要求的路径,否则返回[].

例子1:

Input: 2, [[1,0]]
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished  
             course 0. So the correct course order is [0,1].

例子2:

Input: 4, [[1,0],[2,0],[3,1],[3,2]]
Output: [0,1,2,3] or [0,2,1,3]

Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both    
             courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
             So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .

BFS思路:每次找入度为0的节点。

1、先建立图(邻接表)、和入度表。

2、循环n次(n为节点数),每次找到度为0 的节点(循环n次,从头开始找),加入path中,然后将其出度的节点的入度-=1(循环入度表)。

先是找到入度为0的节点:1

将1加入path中,然后是2,3节点的入度减去1,因为1已经被处理掉了。

此时度为0的节点是2,3。

将2,3加入path中,…… 

技术分享图片

 

 

伪代码:

循环n次:

循环n次:

找入度为0的节点

将度为0节点加入path中

循环入度表:

将度为0节点的出度节点的入度节点-=1

代码:

 

from collections import defaultdict
def BFS(n,arr):
    # n 为节点数,arr为【【u1,v1】,【u2,v2】……】,这里的u和v中,v是u的父节点。
    if not arr:
        return -1
    graph = defaultdict(list)
    indegree = defaultdict(int)
    path = []
    for u , v in arr:
        graph[v].append(u)
        indegree[u] += 1
    for i in range(n):
        zeroDegree = False
        for j in range(n):
            if indegree[j] == 0:
                zeroDegree = True
                break
        if not zeroDegree:
            return []
        indegree[j] -= 1
        path.append(j)
        for val in graph[j]:
            indegree[val] -= 1
    return path
n= 5
arr = [[1,0],[2,0],[3,1],[3,2],[4,0]]
print(BFS(n,arr))

 

 

DFS思路:递归

  1、建立图

  2、循环n次,每次是遍历一个节点是否已经visited且合法地加入path中了,如果False不合法则直接返回【】。

  3、遍历一个节点时会将其后面的所有子节点都处理掉。

如,先是1,将1进行dfs处理【path中加入1,2,4,8,5】

  然后是2,将2进行dfs处理,已经visited过了,继续循环

  然后是3,将3进行dfs处理,没有visited,unkown状态,【path=【1,2,4,8,5】中加入【3,6,7】】

  然后是4……,后面都是visited过的,都直接跳过。

技术分享图片

 

 

 

 

 

 

 

 

 代码:

 

from collections import defaultdict
def findPath(n,arr):
    if n == 0:
        return []
    graph = defaultdict(list)
    for u , v in arr:
        graph[v].append(u)
    # 0为Unkown,1为visiting,2为visited
    path = []
    visited = [0] * n
    for i in range(n):
        if not DFS(graph,visited,path,i):
            return []
    return path
def DFS(graph,visited,path,i):
    ####i节点:其正在遍历,但它的子节点的子节点也是它,表示产生了有环,则return FALSE
    if visited[i] == 1: return False
    ####i节点 :已经遍历过,后面已经没有节点了,return true
    elif visited[i] == 2:return True
    ####表示正在遍历i节点
    visited[i] = 1
    for j in graph[i]:
        if not DFS(graph,visited,path,j):
            return False
    path.append(i)
    visited[i] = 2
    return True


n = 5
arr = [[1,0],[2,0],[3,1],[3,2],[4,0]]
print(findPath(n,arr))

 

二、题目:解题报告,连除----399

已经给出了某些变量的比值,求新的变量的比值。如果这个变量没有出现过,或者不可到达,那么返回-1.

技术分享图片

 

DFS思路: 

 

题目中给了顶点和顶点之间的关系,其实就是制定了这个图的样子。然后要求的新的比值其实就是从一个顶点到达另外一个顶点的路径,并且把这条路径上所有的权重相乘。

 

注意,如果a/b=3,那么从a到b是3,那么从b到a是1/3.

 

既然是从一个顶点出发到达另外一个顶点,所以应该是dfs解决的问题。
原文:https://blog.csdn.net/fuxuemingzhu/article/details/82591165

 

  1、建立图  {a:{b : 2.0} 、b:{a:1 /2.0,c:3.0}、c:{b:1/3.0}}

  2、不在图中则返回-1  

  3、在图中,x == y,返回1,x != y,返回x到y的拓扑排序的权重相乘值。

代码:

  

from collections import defaultdict
def solveque(arr ,values , que):
    if not arr:
        return [-1] * len(que)
    if not que:
        return []
    graph = defaultdict(dict)
    for (x,y) , value in zip(arr,values):
        graph[x][y] = value
        graph[y][x] = 1/value if value else 0
    for x,y in que:
        if x in graph and y in graph:
            return dfs(graph,x,y,set())
        else:
            return -1.0
def dfs(graph,x,y,visited):
    if x == y:
        return 1.0
    visited.add(x)
    for k in graph[x]:
        if k in visited:continue
        visited.add(k)
        d = dfs(graph,k,y,visited)
        if d > 0:
            return d*graph[x][k]
    return -1.0
arr = [[a,b],[b,c]]
values = [2.0,3.0]
que = [[a,c],[a,v]]
print(solveque(arr ,values , que))

 

 

 

 
 

 

算法87-----DAG有向无环图的拓扑排序

原文:https://www.cnblogs.com/Lee-yl/p/10500569.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!