作者: cookyo | 来源:发表于2019-06-04 19:20 被阅读0次
    1 图的邻接矩阵表示
    inf = float("inf")
    class Graph:
        def __init__(self, mat, unconn=0):
            vnum = len(mat)
            for x in mat:
                if len(x) != vnum:
                    raise ValueError("Argument for 'Graph'.")
            self._mat = [mat[i][:] for i in range(vnum)]
            self._unconn = unconn
            self._vnum = vnum
            
        def vertex_num(self):
            return self._vnum
        
        def _invalid(self, v):
            return 0 > v or v >= self._vnum
        
        def add_vertex(self):
            raise GraphError("Adj-Matrix does not support 'add_vertex'.")
            
        def add_edge(self, vi, vj, val = 1):
            if self._invalid(vi) or self._invalid(vj):
                raise GraphError(str(vi) + 'or'+ str(vj) + " is not a valid vertex.")
            self._mat[vi][vj] = val
            
        def get_edge(self, vi, vj):
            if self._invalid(vi) or self._invalid(vj):
                raise GraphError(str(vi) + 'or'+ str(vj) + " is not a valid vertex.")
            return self._mat[vi][vj]
        
        def out_edges(self, vi):
            if self._invalid(vi):
                raise GraphError(str(vi) + " is not a valid vertex.")
            return self._out_edges(self._mat[vi], self._unconn)
        
        @staticmethod
        def _out_edges(row, unconn):
            edges = []
            for i in range(len(row)):
                if row[i] != unconn:
                    edges.append((i, row[i]))
            return edges
    
    2 图的邻接表表示
    class Graph2:
        def __init__(self):
            self.node_neighbors = {}
            self.nodes = []
            
            
        def nodes(self):
            return self.node_neighbors.keys()
            
        def add_nodes(self, nodelist):
            for node in nodelist:
                self.add_node(node)
                
        def add_node(self, node):
            if not node in self.nodes():
                self.node_neighbors[node] = []
                
        def add_edge(self, edge):
            u, v = edge
            if (v not in self.node_neighbors[u]):
                self.node_neighbors[u].append(v)
            
        def depth_search(self, root = None):
            order = []
            visited = {}
            
            def dfs(node):
                visited[node] = True
                order.append(node)
                for n in self.node_neighbors[node]:
                    if not n in visited:
                        dfs(n)
            
            if root:
                dfs(root)
            for n in self.nodes():
                if not n in visited:
                    dfs(n)
            print(order)
            
        def breadth_search(self, root = None):
            queue = []
            order = []
            visited = {}
            def bfs():
                while len(queue) > 0:
                    node = queue.pop(0)
                    visited[node] = True
                    for n in self.node_neighbors[node]:
                        if (not n in visited) and (not n in queue):
                            queue.append(n)
                            order.append(n)
            if root:
                queue.append(root)
                order.append(root)
                bfs()
            for node in self.nodes():
                if not node in visited:
                    queue.append(node)
                    order.append(node)
            print(order)
    
    3 生成树
    def DFS_span_forest(graph):
        vnum = graph.vertex_num()
        span_forest = [None] * vnum
        
        def dfs(graph, v):
            nonlocal span_forest  #在函数或其他作用域中使用外层(非全局)变量
            for u, w in graph.out_edges(v):
                if span_forest[u] is None:
                    span_forest[u] = (v, w)
                    dfs(graph, u)
        for v in range(vnum):
            if span_forest[v] is None:
                span_forest[v] = (v, 0)
                dfs(graph, v)
        return span_forest
    
    4 dijkstra
    # 动规
    def dijkstra(A,v0): # v0: [0 ,vnum-1]
        vnum = len(A[0])
        res = [float('inf')] * vnum
        book = [0] * vnum  # 记录是否访问
        start = v0
        res[start] = 0
        book[start] = 1
        for i in range(vnum):
            res[i] = min(res[i], A[start][i])
        for i in range(vnum-1):
            minn = float('inf')
            for j in range(vnum):
                if book[j] == 0 and minn > res[j]:
                    minn = res[j]
                    start = j
            book[start] = 1
            for j in range(vnum):
                res[j] = min(res[j], res[start] + A[start][j])
        return res
    
    5 floyd
    def floyd(A):
        vnum = len(A[0])
        nextvet = [[-1 if A[i][j] == inf else j
                   for j in range(vnum)]
                  for i in range(vnum)]
        for k in range(vnum):
            for i in range(vnum):
                for j in range(vnum):
                    if A[i][j] > A[i][k] + A[k][j]:
                        A[i][j] = A[i][k] + A[k][j]
                        nextvet[i][j] = nextvet[i][k]
        return (A, nextvet)
    
    inf = float('inf')
    A = [[0,5,8,inf,inf],[5,0,1,3,2],[8,1,0,inf,inf],[inf,3,inf,0,7],[inf,2,inf,7,0]]
    print(floyd(A)[0])
    
    6 kruskal & 并查集
    def find(x,parent):
        s = x
        while parent[s] >= 0:
            s = parent[s]
        while s != x:
            tmp = parent[x]
            parent[x] = s
            x = tmp
        return s
    
    def union(R1, R2, parent):
        r1 = find(R1, parent)
        r2 = find(R2, parent)
        tmp = parent[r1] + parent[r2]
        if parent[r1] < parent[r2]:
            parent[r2] = r1
            parent[r1] = tmp
        else:
            parent[r1] = r2
            parent[r2] = tmp
    
    def Kruskal(A): 
        vnum = len(A[0])
        edges = []
        for i in range(vnum-1):
            for j in range(i+1,vnum):
                if A[i][j] != float('inf'):
                    edges.append((A[i][j], i, j))
        edges.sort()
        print(edges)
        parent = [-1] * vnum
        res = []
        sumweight = 0
        enum = 0
        for i in range(len(edges)):
            if find(edges[i][1], parent) != find(edges[i][2], parent):
                res.append((edges[i][1],edges[i][2]))
                sumweight += edges[i][0]
                union(edges[i][1],edges[i][2], parent)
                enum += 1
                print(parent)
                print((edges[i][1],edges[i][2]))
            if enum >= vnum - 1:
                break
        return res
    
    inf = float('inf')
    A = [[0,5,8,inf,inf],[5,0,1,3,2],[8,1,0,inf,inf],[inf,3,inf,0,7],[inf,2,inf,7,0]]
    print(Kruskal(A))
    
    [(1, 1, 2), (2, 1, 4), (3, 1, 3), (5, 0, 1), (7, 3, 4), (8, 0, 2)]
    [-1, 2, -2, -1, -1]
    (1, 2)
    [-1, 2, -3, -1, 2]
    (1, 4)
    [-1, 2, -4, 2, 2]
    (1, 3)
    [2, 2, -5, 2, 2]
    (0, 1)
    [(1, 2), (1, 4), (1, 3), (0, 1)]
    

    相关文章

      网友评论

          本文标题:

          本文链接:https://www.haomeiwen.com/subject/ffirxctx.html