Dijkstra算法最短路径可视化(新)

内容还是比较详细的,这里不废话了,代码里都有

注意的是,绿色线尽头的点是:起点到达该点的最短距离

算法会寻找每个点临近点中最近的点,排除掉已经访问过的点

(matplotlib坏了还没修好,暂时用的cv2绘制)

python 复制代码
import math
import cv2
import numpy as np


class Dj:
    def __init__(self, points, start, end):
        self.points, self.start, self.end = points, start, end
        self.w, self.h = 1000, 600
        self.image = np.zeros((self.h, self.w, 3), dtype=np.uint8)
        self.route = []
        self.generate_map()
        self.video = cv2.VideoWriter("output.mp4", cv2.VideoWriter_fourcc(*'XVID'), 1, (self.w, self.h))  # 录制

    def generate_map(self):
        for p in self.points:
            cv2.circle(self.image, p, 10, (0, 0, 255), - 1)
            for ps in self.points[p]:
                cv2.line(self.image, p, ps, (255, 255, 255), 4)

    def line_shortest(self, p1, p2):
        cv2.line(self.image, p1, p2, (0, 255, 0), 4)
        return p2

    def line_route(self):
        for i in range(1, len(self.route) - 1):
            cv2.line(self.image, self.route[i - 1], self.route[i], (0, 255, 255), 4)

    def distance(self, point1, point2):
        return math.sqrt((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2)

    # Dijkstra算法实现
    def dijkstra(self):
        dist = {point: float('inf') for point in self.points}  # 点:起点到当前点的最短距离
        dist[self.start] = 0  # 起点到自身距离设为0
        prev = {point: None for point in self.points}  # 记录每个点的前驱节点,用于回溯最短路径
        visited = set()  # 以及访问过的点
        while len(visited) < len(self.points):  # 未访问所有点
            frame = self.image.copy()
            current = None  # 到达的当前点为None
            min_dist = float("inf")  # 对于全部点,起点到达该点的最短距离
            # ########################################### 更新起点到当前点的所经过的最短路径(总距离) 和 当前点
            for point in points:  # 对于每个点
                if point not in visited and dist[point] < min_dist:  # 如果未访问,且起点到当前点的距离小于全局最短距离
                    min_dist = dist[point]  # 更新全局最短距离
                    current = point  # 更新到达的点

            visited.add(current)  # 在目前距离最优的情况下,该点已访问
            ##############################################
            if current == self.end:
                break  # 如果到达的点是终点,结束
            # ############################################# 更新起点到当前点相邻点中最近的点,和 到达距离
            for neighbor in points[current]:  # 对于当前点的所有相邻点
                new_dist = dist[current] + self.distance(current, neighbor)  # 更新起点到当前点的相邻点的总距离
                color = (255, 0, 0)
                if new_dist < dist[neighbor]:  # 如果这个距离是起点到该点相邻点的最短距离
                    dist[neighbor] = new_dist  # 更新起点到达该点相邻点的最短距离
                    prev[neighbor] = current
                    color = (0, 255, 0)
                    self.line_shortest(current, neighbor)  # 在原图上绘制到达该点的最短路径
                if neighbor in visited:  # 避免画回头的线
                    continue
                cv2.line(frame, neighbor, current, color, 4)  # 绘制临近点的路径
                cv2.waitKey(1000)
                ##############################################
                cv2.imshow("dj", frame)
                self.video.write(frame)
        cv2.imshow('dj', self.image)
        self.video.write(self.image)
        cp = self.end
        self.route = [cp]
        while cp:
            self.route.append(prev[cp])
            cp = prev[cp]
        cv2.waitKey(1000)
        self.line_route()
        cv2.imshow('dj', self.image)
        self.video.write(self.image)
        self.video.release()

        key = cv2.waitKey()
        if key == 27:  # 如果按下ESC键(ASCII码值为27),退出循环
            cv2.destroyAllWindows()
        return dist


# points = {
#     (0, 0): [(0, 200), (200, 300), (400, 100)],
#     (0, 200): [(200, 300), (0, 0)],
#     (200, 300): [(0, 200), (0, 0), (500, 500)],
#     (400, 100): [(0, 0), (500, 500)],
#     (500, 500): [(200, 300), (400, 100)],
# }
# 点与其相邻点
points = {
    (0, 0): [(400, 0), (0, 200), (500, 300)],
    (400, 0): [(0, 0), (700, 100)],
    (0, 200): [(0, 0), (300, 350)],
    (300, 350): [(0, 200), (400, 500)],
    (400, 500): [(300, 350), (600, 600)],
    (600, 600): [(400, 500), (500, 300), (1000, 600)],
    (500, 300): [(0, 0), (700, 100), (1000, 250), (600, 600)],
    (700, 100): [(400, 0), (500, 300), (1000, 250)],
    (1000, 250): [(700, 100), (500, 300), (900, 400)],
    (900, 400): [(1000, 250), (1000, 600)],
    (1000, 600): [(1000, 250), (600, 600)]

}
d = Dj(points, (0, 0), (1000, 600))
d.dijkstra()
相关推荐
闲人编程3 分钟前
OpenCV图像轮廓分析完全指南
python·opencv·图像识别
神仙别闹11 分钟前
基于Python+Neo4j实现新冠信息挖掘系统
开发语言·python·neo4j
navyDagger12 分钟前
GAN生成对抗网络数学原理解释并实现MNIST数据集生产(附代码演示)
人工智能·python
没有梦想的咸鱼185-1037-166316 分钟前
【降尺度】ChatGPT+DeepSeek+python+CMIP6数据分析与可视化、降尺度技术与气候变化的区域影响、极端气候分析
python·chatgpt·数据分析
berryyan19 分钟前
傻瓜教程安装Trae IDE用AI撰写第一个AKShare接口脚本
python·trae
东方翱翔21 分钟前
第十六届蓝桥杯大赛软件赛省赛第二场 C/C++ 大学 A 组
算法·职场和发展·蓝桥杯
灏瀚星空37 分钟前
从基础到实战的量化交易全流程学习:1.3 数学与统计学基础——概率与统计基础 | 基础概念
笔记·python·学习·金融·概率论
Hellohistory42 分钟前
HOTP 算法与实现解析
后端·python
伊织code43 分钟前
cached-property - 类属性缓存装饰器
python·缓存·cache·装饰器·ttl·property·cached-property
Blossom.1181 小时前
量子计算在密码学中的应用与挑战:重塑信息安全的未来
人工智能·深度学习·物联网·算法·密码学·量子计算·量子安全