【图论】【python实现】通信网算法基础-搜索、贪心

本文介绍了图论在通信网中的应用,详细讲解了搜索算法(BFS、DFS)和贪心算法在解决实际问题中的运用,如最小生成树和最短路径问题。通过Python实现,探讨了Prim、Kruskal算法以及Dijkstra算法,分析了其复杂度,并提出了算法优化的可能性。
摘要由CSDN通过智能技术生成

7桥问题

著名的七桥问题,为我们带来了“图”的概念。

一、搜索

目标:给定起点,遍历图中所有顶点。
方法:BFS、DFS
典型应用:web crawling
伪码示例:

BFS(G, s)
// B=所有边界点构成的集合
B.EnQueue(s);
WHILE B非空
    d=B.DeQueue();
    将d标记为“已探索”;
    FOR d的所有邻居t
        IF t的标记为“未探索”
            B.EnQueue(t);
    ENDFOR
ENDWHILE
DFS(G, s)
// B=所有边界点构成的集合
B.Push(s);
WHILE B非空
    d=B.Pop();
    将d标记为“已探索”;
    FOR d的所有邻居t
        IF t的标记为“未探索”
            B.Push(t);
    ENDFOR
ENDWHILE

应用:

求有向图的强连通分量(Strongly Connected Component, SCC)

#TWO-PASS算法(Kosaraju算法)
TWO-PASS(G)
G中有向边方向取反→G^rev^
Loop-DFS(G^rev^,记录每个顶点的完成时间f(v).
按f(v)的降序,在G中运行Loop-DFS,记录每个顶点的Leader l(v). 
具有相同leader的顶点属于同一个SCC

Loop-DFS( G )
global t=0
global s=NULL
FOR i=1 to n
    IF i的标记为“未探索”
        s = i;
        DFS(G, i);
ENDFOR

求给定两点间所有路径

python实现

f = open('test-6.txt', 'r')
Graph = {
   }
edge_num = int(f.readline())
node_num = int(f.readline())
#文件读取

# edge_num = int(input("图的边数:"))
# node_num = int(input("图的点数:"))
# print("请输入%d行链路:" % edge_num)
#手动输入

while edge_num > 0:
    edge_num = edge_num - 1
    s = f.readline()
    node1, node2 = s.split()
    # node1, node2 = input().split()
    if (node1 not in Graph):
        Graph[node1] = []#读入点
    Graph[node1].append(node2)#读入有向边
    if (node2 not in Graph):
        Graph[node2] = []
    Graph[node2].append(node1)
#用读入的数据生成图

Path = []#DFS路径点
num = 0#total paths num


def DFS(Graph, start, end):
    Path.append(start)
    while (start in Path):
        for i in Graph[start]:
            if i not in Path:
                if i == end:
                    Path.append(i)
                    global num
                    num = num + 1
                    Path.pop()
                else:
                    DFS(Graph, i, end)
        Path.pop()


if (node_num == len(Graph)):
    start = f.readline()
    start = start.replace(start[-1], '')
    end = f.readline()
    print("从" + start + "到" + end + "的所有路径为:")
    DFS(Graph, start, end)
    print("total paths num:", num)
else:
    print("图的点数与输入路径不符!")

引申:

求解思路:BFS-分支定界;DFS-回溯
它们是求解问题的两种基本范型。

在这里插入图片描述

看累了来吸会儿猫(

二、贪心

思想:求局部最佳解,“希望”最终得到的是全局最佳解。

最小生成树

目标:以最小代价连接所有点。
方法:Prim、Kruskal

#基于堆的Prim实现
from heapq import heappush, heapify, heappop


class WeightedGraph(object):
    def __init__(self):
        self.edges = []
        self.adj = {
   }  # 邻接边集
        self.edge_num = 0
        self.node_num = 0

    def generate_graph(self, node1, node2, w):
        self.adj.setdefault(node1, [(w, node1, node2)])
        self.adj.setdefault(node2, [(w, node2, node1)])
        if (w, node1, node2) not in self.adj[node1]:
            self.adj[node1].append((w, node1, node2))
        if (w, node2, node1) not in self.adj[node2]:
            self.adj[node2].append((w, node2, node1))
        self.edges.append((w, node1, node2))


class MST(object):
    def __init__(self):
        self.shape = []
        self.weight = 0


def initialize_graph():  # 根据输入数据初始化图
    graph = WeightedGraph()
    f = open('test-3.txt', 'r')
    graph.edge_num = int(f.readline())
    graph.node_num = int(f.readline())
    for line in f.readlines():
        node1, node2, w = line.split()
        graph.generate_graph(node1, node2, int(w))
    return graph


def prim(Graph):
    T = MST()  # 初始化最小树
    start = Graph.edges[0][1]  # 起始点
    S = list(start)  # 树上顶点集合
    cut_edges = Graph.adj[start]  # 边界边集合
    heapify(cut_edges)  # 边界边建堆
    while len(S) < Graph.node_num:  # 直到生成树包含所有点
        min_edge = heappop(cut_edges)
        w, node1, node2 = min_edge
        if node2 not in S:
            T.shape.append(min_edge)
            T.weight = T.weight + w
            S.append(node2)
        for adj_edge in Graph.adj[node2]:  # 将与node2相邻的边界边加入堆
            if adj_edge[2] not in S:
                heappush(cut_edges, adj_edge)
    return T


def main():
    graph = initialize_graph()
    T = prim(graph)
    for edge in T.shape:
        print('(' + edge[1] + ',' + edge[2] + ')')
    print("Weight Sum:", T.weight)


if __name__ == "__main__":
    main()


#基于并查集的Kruskal实现
class WeightedGraph(object):
    def __init__(self):
        self.edges = []
        self.leader_set = {
   }
        self.leader = {
   }
        self.edge_num = 0
        self.node_num = 0

    def generate_graph(self, node1, node2, w):
        self.edges.append((w, node
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值