图路径算法综合

前言

文中涉及的关于最优路径以及相关算法的讨论,仅限静态下以距离作为优先考量的有向图、无向图或混合图的最优路径求解,不考虑时序相关性。时序相关或状态转移模型可参考图概率模型,诸如马尔可夫链、隐马尔科夫模型、条件随机场等。两者的主要区别在于后者求解的是随机过程中发生概率最大的时序转移路径。

概念

图 (Graph) 是一种表示对象之间关系的数据结构,一个图由多个顶点,以及顶点之间的边构成。如果图中所有的边都是无向的 (即双向),则这个图称为无向图;如果所有的边都是有向的 (可以理解为单向),则这个图称为有向图;如果既有无向也有有向的边,则称为混合图路径是交替的顶点和边构成的序列,表示从一个顶点转移至另一个顶点所经过的顶点和边。以下是有向图的示例:

在这里插入图片描述

准备工作

为运行算法,我们统一构建一套有向图案例,一套无向图案例,以及一套混合图案例。考虑到代码简洁性的需求,不构建图和边的对象。案例中,每个顶点包含ID、邻接点、邻接边长三种信息。

import re
class Vertex(object):
    def __init__(self,ID):
        self.id = ID    #顶点ID
        self.neighbors = []    #邻点对象
        self.edges = []   #与邻点相连的边长度
def gen_graphs():    
    sample = "(ID,Neighbors,Edge)(0,[1],[4])(1,[2,4,8],[12,10,8])(2,[3],[10])(3,[2,4,7],[10,12,6])(4,[7],[10])(5,[6],[12])(6,[11],[20])(7,[11],[10])(8,[1,4,10],[18,12,6])(9,[6,14],[10,10])(10,[5],[16])(11,[7,12],[10,4])(12,[9,14],[12,4])(13,[12,5],[6,22])(14,[10,15],[10,6])(15,[None],[None])"
    directed = [Vertex(i) for i in range(16)]    #构建有向图
    undirected = [Vertex(i) for i in range(16)]    #构建无向图
    mixed = [Vertex(i) for i in range(16)]    #构建混合图
    vertices_info = re.findall(r'([\w\[\],]+)',sample)[1:]
    for vertex_info in vertices_info:    #遍历每一个顶点
        ID = int(re.findall(r'[\w]+',vertex_info)[0])    #读取ID
        neighbors = eval(re.findall(r'\[[\w,]+\]',vertex_info)[0])    #读取邻点
        directed[ID].neighbors = [directed[i] for i in neighbors if i is not None]
        undirected[ID].neighbors = [undirected[i] for i in neighbors if i is not None]
        mixed[ID].neighbors = [mixed[i] for i in neighbors if i is not None]
        edges = eval(re.findall(r'\[[\w,]+\]',vertex_info)[1])    #读取边
        directed[ID].edges = [i for i in edges if i is not None]
        undirected[ID].edges = [i for i in edges if i is not None]
        mixed[ID].edges = [i for i in edges if i is not None]
    for vertex in directed:    #构建有向非循环图
        for i in range(len(vertex.neighbors)-1,-1,-1):
            neighbor = vertex.neighbors[i]
            if neighbor.id < vertex.id:    
                del vertex.neighbors[i]
                del vertex.edges[i]
    for i in range(len(mixed)):    #补充无向图对象缺失的边
        vertex = mixed[i]
        for j in range(len(vertex.neighbors)):    
            neighbor = vertex.neighbors[j]
            if vertex not in neighbor.neighbors:    
                undirected[i].neighbors[j].neighbors.append(undirected[i])
                undirected[i].neighbors[j].edges.append(undirected[i].edges[j])
    return directed, undirected, mixed
directed, undirected, mixed = gen_graphs()

构建好案例后,使用代码对无向图案例进行简单的可视化,生成图像和代码如下:

在这里插入图片描述

import math
import matplotlib.pyplot as plt
#import seaborn as sns
#sns.set(color_codes=True)
plt.figure(figsize=(7,7))
Graph = undirected
for i in range(len(Graph)):
    x, y = math.cos(i/16*2*math.pi),math.sin(i/16*2*math.pi)
    plt.scatter([x],[y],s=18,c='black',label=str(i))
    plt.annotate(str(i), 
    			xy=(x, y),
    			xycoords='data',
    			xytext=(+5, +5), 
    			textcoords='offset points', 
    			fontsize=12)
    for j in range(len(Graph[i].neighbors)):
        if Graph[i].neighbors[j].id < Graph[i].id: continue
        x2, y2 = math.cos(Graph[i].neighbors[j].id/16*2*math.pi),math.sin(Graph[i].neighbors[j].id/16*2*math.pi)
        plt.plot([x,x2],
                 [y,y2],
                 linewidth=1,color='gray')
        plt.annotate('(%d)'%Graph[i].edges[j], 
                     xy=((x+x2)/2, (y+y2)/2</
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值