首页 新闻 会员 周边

两点间所有路径(DFS)

0
[待解决问题]

为什么顶点数目过多时,路径会紊乱?(我将dfs搜索路径改为了可行路径)
并且改变终点时,可能会得不到任何结果

class Vertex: # 节(顶)点类#
def init(self, name, v_id=0):
# 顶点的编号
self.v_id = v_id
# 顶点的名称
self.v_name = name
# 是否被访问过:False 没有 True:有
self.visited = False

# 自我显示
def __str__(self):
    return '[编号为 {0},名称为 {1} ] 的顶点'.format(self.v_id, self.v_name)

class Graph:
#nums:相邻矩阵的大小
def init(self, nums):
# 一维列表,保存节点,最多只能有 nums 个节点
self.vert_list = []
# 二维列表,存储顶点及顶点间的关系(权重)
# 初始权重为 0 ,表示节点与节点之间还没有建立起关系
self.matrix = [[0] * nums for _ in range(nums)]
# 顶点个数
self.v_nums = 0
# 使用队列模拟队列或栈,用于广度、深度优先搜索算法
self.queue_stack = []
# 保存搜索到的路径
self.searchPath = []

def add_vertex(self, vert):  # 添加新顶点
    if vert in self.vert_list:
        # 已经存在
        return
    if self.v_nums >= len(self.matrix):
        # 超过相邻矩阵所能存储的节点上限
        return
    # 顶点的编号内部生成
    vert.v_id = self.v_nums
    self.vert_list.append(vert)
    # 数量增一
    self.v_nums += 1

def add_edge(self, from_v, to_v):  # 添加节点与节点之间的边,如果是无权重图,统一设定为 1
    # 如果节点不存在
    if from_v not in self.vert_list:
        self.add_vertex(from_v)
    if to_v not in self.vert_list:
        self.add_vertex(to_v)
    # from_v 节点的编号为行号,to_v 节点的编号为列号
    self.matrix[from_v.v_id][to_v.v_id] = 1

def add_edge(self, from_v, to_v, weight):  # 添加有权重的边
    # 如果节点不存在
    if from_v not in self.vert_list:
        self.add_vertex(from_v)
    if to_v not in self.vert_list:
        self.add_vertex(to_v)
    # from_v 节点的编号为行号,to_v 节点的编号为列号
    self.matrix[from_v.v_id][to_v.v_id] = weight

def find_vertex(self, v_id):  # 根据节点编号返回节点
    if v_id >= 0 or v_id <= self.v_nums:  # 节点编号必须存在

        return [tmp_v for tmp_v in self.vert_list if tmp_v.v_id == v_id][0]

def find_only_vertexes(self):  #输出所有顶点信息
    for tmp_v in self.vert_list:
        print(tmp_v)

def find_vertexes(self):  # 迭代节点与节点之间的关系(边)
    for tmp_v in self.vert_list:
        edges = self.matrix[tmp_v.v_id]
        for col in range(len(edges)):
            w = edges[col]
            if w != 0:
                print(tmp_v, '和', self.vert_list[col], '的权重为:', w)

def find_neighbor(self, find_v):  # 查找某一节点的相邻节点,并添加到队列(栈)中
    if find_v.visited:
        return
    find_v.visited = True
    # 找到保存 find_v 节点相邻节点的列表
    lst = self.matrix[find_v.v_id]
    for idx in range(len(lst)):
        if lst[idx] != 0:  # 权重不为 0 ,可判断相邻
            self.queue_stack.append(self.vert_list[idx])

def dfs(self, from_v, to_v):  # 深度优先搜索算法使用栈存储下一个需要查找的节点
    global cost
    infos = [(0, 5, 3), (0, 3, 6.8), (0, 16, 2),
             (1, 11, 0.6), (1, 15, 0.6),
             (2, 4, 1.8), (2, 7, 0.7), (2, 6, 0.3), (2, 12, 3),
             (3, 17, 2.4), (3, 10, 7.6), (3, 16, 6.9), (3, 5, 7.1),
             (4, 5, 8), (4, 6, 1.6), (4, 12, 6),
             (5, 16, 1),
             (7, 8, 1.4), (7, 12, 3.1),
             (8, 15, 1.8),
             (9, 15, 4),
             (10, 17, 4),
             (11, 14, 5),
             (12, 14, 2),
             (13, 14, 20)]
    self.find_neighbor(from_v)  # 查找与 from_v 相邻的节点
    lst_path = [from_v]  # 临时路径
    costsort = []
    while len(self.queue_stack) != 0:  # 重复条件:栈不为空
        tmp_v = self.queue_stack.pop()  # 从栈中取一个节点(模拟栈)
        lst_path.append(tmp_v)  # 添加到列表中

        if tmp_v.v_id == to_v.v_id:  # 是不是目标节点
            self.searchPath.append(lst_path)
            allpath = [v_.v_id for v_ in lst_path]  # allpath为所有路径
            cost = 0
            res_list1 = [x[0] for x in infos]
            res_list2 = [x[1] for x in infos]
            res_list = list(zip(res_list1, res_list2))  # 以列表元组形式,判断所走路径是否合理
            pathlist = []
            for i in range(1,len(allpath)):
                path1 = (allpath[i - 1], allpath[i])
                pathlist.append(path1)  # pathlist为dfs的搜索路径
            for i in range(len(allpath)):
                for x in infos:
                    if x[0] == allpath[i-1] and x[1] == allpath[i]:
                        cost = cost + x[2]
            for i in range(len(pathlist)):
                if pathlist[i-1] not in res_list:  # 如果infos中不存在该路径,则删去该点
                    allpath.pop(i-1)
            print(allpath)
            print('所需权值:', cost)
            costsort.append([cost, allpath])  # 将cost和路径存入列表,运用列表进行排序
            lst_path.pop()
        else:
            self.find_neighbor(tmp_v)
    for i in range(0, len(costsort)):
        for j in range(0, len(costsort) - i - 1):
            if costsort[j][0] > costsort[j + 1][0]:
                costsort[j], costsort[j + 1] = costsort[j + 1], costsort[j]
    print('排序结果:', costsort)

if name == "main":
# 初始化图对象
g = Graph(18)
# 添加顶点
node = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R']
for v_name in node:
v = Vertex(v_name)
g.add_vertex(v)
print("-----------顶点与顶点关系--------------")
g.find_vertexes()
# 节点之间的关系
infos = [(0, 5, 3), (0, 3, 6.8), (0, 16, 2),
(1, 11, 0.6), (1, 15, 0.6),
(2, 4, 1.8), (2, 7, 0.7), (2, 6, 0.3), (2, 12, 3),
(3, 17, 2.4), (3, 10, 7.6), (3, 16, 6.9), (3, 5, 7.1),
(4, 5, 8), (4, 6, 1.6), (4, 12, 6),
(5, 16, 1),
(7, 8, 1.4), (7, 12, 3.1),
(8, 15, 1.8),
(9, 15, 4),
(10, 17, 4),
(11, 14, 5),
(12, 14, 2),
(13, 14, 20)]
for i in infos:
v = g.find_vertex(i[0])
v1 = g.find_vertex(i[1])
g.add_edge(v, v1, i[2])

print("----------- 深度优先路径搜索--------------")
f_v = g.find_vertex(0)
t_v = g.find_vertex(16)
g.dfs(f_v, t_v)
LLLxAi的主页 LLLxAi | 菜鸟二级 | 园豆:202
提问于:2023-01-04 16:33
< >
分享
所有回答(1)
0

请问你的代码是要实现什么功能?有没有要求一定要OOP?

瓶瓶罐罐 | 园豆:201 (菜鸟二级) | 2023-01-05 13:52

实现两点之间的所有路径,要求要oop

支持(0) 反对(0) LLLxAi | 园豆:202 (菜鸟二级) | 2023-01-05 14:14
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册