import numpy as np
import pandas as pd
from collections import deque
import heapq

# 读取网络数据
logicalNetwork = pd.read_excel('逻辑网络1.xls', header=None).to_numpy()
physicalNetwork = pd.read_excel('物理网络1.xls', header=None).to_numpy()

# 获取网络的节点数
num_nodes = logicalNetwork.shape[0]

# 用于存储已经存在的路径
existing_paths = set()

# 随机删除6条物理边
np.random.seed(0)
deleted_edges = np.random.choice(np.argwhere(physicalNetwork != 0), size=6, replace=False)
for edge in deleted_edges:
    physicalNetwork[edge[0], edge[1]] = 0

# 用于Dijkstra搜索的辅助函数
def dijkstra(source, target, graph):
    # 初始化优先队列,格式为(最小负载,当前节点,路径)
    queue = [(-graph[source].max(), source, [source])]
    # 初始化一个集合存储已经访问过的节点
    visited = set([source])
    while queue:
        min_load, node, path = heapq.heappop(queue)
        min_load = -min_load  # 因为Python的heapq是最小堆,所以我们存储负载的相反数,使得负载最大的路径优先出队
        if node == target:
            return [n+1 for n in path]  # 返回的路径节点编号要加1,因为我们的节点编号是从0开始的
        for next_node, next_load in enumerate(graph[node]):
            if next_node not in visited and next_load >= min_load:
                heapq.heappush(queue, (-next_load, next_node, path + [next_node]))
                visited.add(next_node)
    return []

# 用于广度优先搜索的辅助函数
def bfs(source, target):
    queue = deque([[source]])
    while queue:
        path = queue.popleft()
        node = path[-1]
        if node == target:
            return [n+1 for n in path]
        for next_node, next_load in enumerate(physicalNetwork[node]):
            if next_load > 0 and next_node not in path:
                queue.append(path + [next_node])
    return []

# 遍历所有逻辑网络中的节点对
for i in range(num_nodes):
    for j in range(i+1, num_nodes):
        if logicalNetwork[i, j] != 0:  # 如果逻辑网络中的节点对是直接连接的
            # 使用BFS找到节点数最少的路径
            path = bfs(i, j)
            print(f'From node {i+1} to node {j+1}, path is {path}')

            # 创建物理网络的副本
            physicalNetwork_copy = physicalNetwork.copy()

            # 使用Dijkstra搜索找到备用路径
            path2 = dijkstra(i, j, physicalNetwork_copy)
            print(f'From node {i+1} to node {j+1}, alternate path is {path2}')

            # 删除备用路径上的所有边
            for k in range(len(path2) - 1):
                physicalNetwork[path2[k]-1, path2[k+1]-1] = 0

代码解释:

  1. 导入必要的库:

    • numpy 用于处理数组和矩阵。
    • pandas 用于读取Excel文件。
    • collections 中的 deque 用于实现广度优先搜索的队列。
    • heapq 用于实现Dijkstra算法的优先队列。
  2. 读取网络数据:

    • 使用 pd.read_excel() 函数读取逻辑网络和物理网络的数据,并使用 .to_numpy() 方法将它们转换为NumPy数组。
  3. 获取网络的节点数:

    • 使用 logicalNetwork.shape[0] 获取逻辑网络的节点数。
  4. 随机删除物理边:

    • 使用 np.random.choice() 函数随机选择6条物理边,并将其权重设置为0,模拟网络故障或资源占用。
  5. 定义 dijkstra() 函数:

    • 该函数使用Dijkstra算法找到从源节点到目标节点的负载最大的路径。
    • 函数接受三个参数:源节点、目标节点和物理网络的邻接矩阵。
    • 函数返回找到的路径,如果没有找到路径则返回空列表。
  6. 定义 bfs() 函数:

    • 该函数使用广度优先搜索算法找到从源节点到目标节点的节点数最少的路径。
    • 函数接受两个参数:源节点和目标节点。
    • 函数返回找到的路径,如果没有找到路径则返回空列表。
  7. 遍历所有逻辑网络中的节点对:

    • 使用两个嵌套的循环遍历所有逻辑网络中的节点对。
    • 如果节点对之间存在连接,则使用 bfs() 函数找到节点数最少的路径作为主路径。
    • 然后,创建物理网络的副本,并使用 dijkstra() 函数在副本上找到备用路径。
    • 最后,删除物理网络中备用路径上的所有边,模拟资源占用。

总结:

本文介绍的Python代码实现了一种基于图论的逻辑网络映射和备用路由算法。该算法简单易懂,可以方便地应用于实际网络中。

Python实现基于图论的逻辑网络映射和备用路由算法

原文地址: https://www.cveoy.top/t/topic/Uvc 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录