C#实现最短路径算法

 创建点集

            double r = 200 * 500;
            double width = 1920;
            double height = 1080;

            int col = (int)(r / width);
            int row = (int)(r / height);
            List<(double, double)> list1 = new List<(double, double)>();
            for (int i = 0; i < row; ++i)
            {
                var y = i * height;
                if (y < r)
                {
                    var xxx = Math.Sqrt(r * r - y * y);
                    var x = xxx - (xxx % width);
                    list1.Add((x, y));
                    list1.Add((-x, y));
                    list1.Add((x, -y));
                    list1.Add((-x, -y));
                }
            }

 点阵像这样一样

最短路径算法,使用LinkedList返回,后续对插入友好

  LinkedList<(double, double)> NearestNeighborTSP(List<(double, double)> points)
        {
            int n = points.Count;
            bool[] visited = new bool[n];
            visited[0] = true;
            int current = 0;
            LinkedList<(double, double)> path = new LinkedList<(double, double)>();
            path.AddLast(points[current]);

            for (int i = 1; i < n; i++)
            {
                double minDistance = double.MaxValue;
                int next = -1;

                for (int j = 0; j < n; j++)
                {
                    if (!visited[j])
                    {
                        double dist = Distance(points[current], points[j]);
                        if (dist < minDistance)
                        {
                            minDistance = dist;
                            next = j;
                        }
                    }
                }

                current = next;
                visited[current] = true;
                path.AddLast(points[current]);
            }

            path.AddLast(points[0]);

            return path;
        }

        double Distance((double, double) point1, (double, double) point2)
        {
            return Math.Sqrt(Math.Pow(point1.Item1 - point2.Item1, 2) + Math.Pow(point1.Item2 - point2.Item2, 2));
        }

 路径找完之后(局部展示图,斜线连起来的)

 矫正斜线

            var currentNode = res.First;
            while (currentNode != null && currentNode.Next != null)
            {
                var nextNode = currentNode.Next;
                if (currentNode.Value.Item1 != nextNode.Value.Item1 && currentNode.Value.Item2 != nextNode.Value.Item2)
                {
                    var tempX = Math.Min(currentNode.Value.Item1, nextNode.Value.Item1);
                    var tempY = currentNode.Value.Item1 > nextNode.Value.Item1 ? currentNode.Value.Item2 : nextNode.Value.Item2;
                    res.AddAfter(currentNode, (tempX, tempY));
                    currentNode = nextNode; // Skip the inserted node
                }
                else
                    currentNode = currentNode.Next;
            }

矫正后效果

完整测试代码(demo中所用WPF框架,图表控件为ScottPlot5,nuget里直接搜,装5.0以上版本):

public void test()
        {

            double r = 200 * 500;
            double width = 1920;
            double height = 1080;

            int col = (int)(r / width);
            int row = (int)(r / height);
            List<(double, double)> list1 = new List<(double, double)>();
            for (int i = 0; i < row; ++i)
            {
                var y = i * height;
                if (y < r)
                {
                    var xxx = Math.Sqrt(r * r - y * y);
                    var x = xxx - (xxx % width);
                    list1.Add((x, y));
                    list1.Add((-x, y));
                    list1.Add((x, -y));
                    list1.Add((-x, -y));
                }
            }
            var wpfPlot = new ScottPlot.WPF.WpfPlot();
            var xs = list1.Select(x => x.Item1).ToArray();
            var ys = list1.Select(y => y.Item2).ToArray();
            var xx = wpfPlot.Plot.Add.Scatter(xs, ys, ScottPlot.Colors.Red).LineWidth = 0;
            var res = NearestNeighborTSP(list1);
            var currentNode = res.First;
            while (currentNode != null && currentNode.Next != null)
            {
                var nextNode = currentNode.Next;
                if (currentNode.Value.Item1 != nextNode.Value.Item1 && currentNode.Value.Item2 != nextNode.Value.Item2)
                {
                    var tempX = Math.Min(currentNode.Value.Item1, nextNode.Value.Item1);
                    var tempY = currentNode.Value.Item1 > nextNode.Value.Item1 ? currentNode.Value.Item2 : nextNode.Value.Item2;
                    res.AddAfter(currentNode, (tempX, tempY));
                    currentNode = nextNode; // Skip the inserted node
                }
                else
                    currentNode = currentNode.Next;
            }

            var xs2 = res.Select(x => x.Item1).ToArray();
            var ys2 = res.Select(x => x.Item2).ToArray();
            var yy = wpfPlot.Plot.Add.Scatter(xs2, ys2, ScottPlot.Colors.Blue).LineWidth = 1;
            grid.Children.Add(wpfPlot);
        }


        LinkedList<(double, double)> NearestNeighborTSP(List<(double, double)> points)
        {
            int n = points.Count;
            bool[] visited = new bool[n];
            visited[0] = true;
            int current = 0;
            LinkedList<(double, double)> path = new LinkedList<(double, double)>();
            path.AddLast(points[current]);

            for (int i = 1; i < n; i++)
            {
                double minDistance = double.MaxValue;
                int next = -1;

                for (int j = 0; j < n; j++)
                {
                    if (!visited[j])
                    {
                        double dist = Distance(points[current], points[j]);
                        if (dist < minDistance)
                        {
                            minDistance = dist;
                            next = j;
                        }
                    }
                }

                current = next;
                visited[current] = true;
                path.AddLast(points[current]);
            }

            path.AddLast(points[0]);

            return path;
        }

        double Distance((double, double) point1, (double, double) point2)
        {
            return Math.Sqrt(Math.Pow(point1.Item1 - point2.Item1, 2) + Math.Pow(point1.Item2 - point2.Item2, 2));
        }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/796422.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

青年发展型城市成新青择地,期待与挑战并存

随着社会的发展和城市化进程的加快&#xff0c;青年人在选择未来定居地时面临着越来越多的选择。近日&#xff0c;中国青年报社社会调查中心联合问卷网对1500名青年进行的一项调查显示&#xff0c;74.8%的受访青年表示会优先考虑青年发展型城市。那么&#xff0c;青年在选择未来…

编程范式之并发编程

目录 前言1. 并发编程的定义2. 并发编程的特点2.1 任务交替执行2.2 状态共享与同步2.3 并行执行 3. 并发编程的适用场景3.1 高性能计算3.2 I/O 密集型应用3.3 实时系统 4. 并发编程的优点4.1 提高资源利用率4.2 缩短响应时间4.3 提高系统吞吐量 5. 并发编程的缺点5.1 编程复杂性…

gpt-4o看图说话-根据图片回答问题

问题&#xff1a;中国的人口老龄化究竟有多严重&#xff1f; 代码下实现如下&#xff1a;&#xff08;直接调用openai的chat接口&#xff09; import os import base64 import requests def encode_image(image_path): """ 对图片文件进行 Base64 编码 输入…

微分方程建模

微分方程建模是数学建模的重要方法&#xff0c;因为许多实际问题的数学描述将导致求解微分方程的定解问题。在高教杯数学建模竞赛中每年都会有一道微分方程建模问题&#xff0c;大体上可以按以 下几步&#xff1a; 1. 根据实际要求确定要研究的量(自变量、未知函数、必要的参数…

【Linux信号】阻塞信号、信号在内核中的表示、信号集操作函数、sigprocmask、sigpending

我们先来了解一下关于信号的一些常见概念&#xff1a; 实际执行 信号的处理动作 称为信号递达。 信号从产生到递达的之间的状态称为信号未决。 进程可以选择阻塞(Block)某个信号。 被阻塞的信号产生时是处于未决状态的&#xff0c;知道进程解除对该信号的阻塞&#xff0c;该…

基于颜色模型和边缘检测的火焰识别FPGA实现,包含testbench和matlab验证程序

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 (完整程序运行后无水印) 将FPGA仿真结果导入到matlab显示结果&#xff1a; 测试样本1 测试样本2 测试样本3 2.算法运行软件版本 vivado2019.2 …

鸿蒙HarmonyOS应用开发为何选择ArkTS不是Java?

前言 随着智能设备的快速发展&#xff0c;操作系统的需求也变得越来越多样化。为了满足不同设备的需求&#xff0c;华为推出了鸿蒙HarmonyOS。 与传统的操作系统不同&#xff0c;HarmonyOS采用了一种新的开发语言——ArkTS。 但是&#xff0c;刚推出鸿蒙系统的时候&#xff0…

MySQL数据库课程设计——订餐系统(MySQL数据库+Qt5用户界面+python)

目录 一、系统定义 二、需求分析 三、系统设计 四、详细设计 五、参考文献 一、系统定义 订餐系统是一种基于网络技术的在线点餐平台&#xff0c;旨在为用户提供方便快捷的订餐服务。该系统主要包括用户登录、用户管理、菜单管理、订单管理、支付管理、评价管理等功能模块…

云服务器重置密码后,xshell远程连接不上,重新启用密码登录方式

云服务器重置密码后 &#xff0c;xshell连接出现不能使用密码登录 解决方案&#xff1a;以下来自阿里云重新启用密码登录方式帮助文档 为轻量应用服务器创建密钥且重启服务器使密钥生效后&#xff0c;服务器会自动禁止使用root用户及密码登录。如果您需要重新启用密码登录方式&…

比特币交易繁忙的一天

早晨:市场开盘与准备工作 6:00 AM - 全球市场监测 交易员们早早起床,开始监测全球市场动态,尤其是亚洲市场的动向。通过查看新闻、分析报告和市场数据,了解可能影响比特币价格的因素。 7:00 AM - 团队会议 召开晨会,讨论当天的交易策略。团队分析前一天的交易情况,评…

OpenGL笔记五之VBO与VAO

OpenGL笔记五之VBO与VAO 总结自bilibili赵新政老师的教程 code review! 文章目录 OpenGL笔记五之VBO与VAO1.VBO2.VAO3.VBO与VAO对比 1.VBO 代码 void prepareVBO() {//1 创建一个vbo *******还没有真正分配显存*********GLuint vbo 0;GL_CALL(glGenBuffers(1, &vbo))…

适合创业公司使用的wordpress主题

对于创业公司来说&#xff0c;‌选择一个适合的WordPress主题至关重要&#xff0c;‌它不仅能够提升公司网站的外观和用户体验&#xff0c;‌还能帮助优化搜索引擎排名&#xff0c;‌从而吸引更多的潜在客户。‌以下是一些推荐的WordPress主题&#xff0c;‌特别适合创业公司使…

人工智能算法工程师(中级)课程2-Opencv视觉处理之高级操作与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程2-Opencv视觉处理之高级操作与代码详解。在上一节课中的OpenCV基础操作我们了解到OpenCV是一个开源的计算机视觉软件库。它提供了各种视觉处理函数&#xff0c;并支持多种编程语言&…

传感器标定(三)激光雷达外参标定(lidar2ins)

一、数据采集 1、LiDAR 传感器的 LiDAR PCD 数据 2、来自 IMU 传感器的姿势文件 3、手动测量传感器之间外部参数初始值并写入的 JSON 文件 二、下载标定工具 //总的git地址&#xff1a; https://github.com/PJLab-ADG/SensorsCalibration git地址&#xff1a; https://githu…

扩散基生物打印:打造多材料组织构建的新篇章

生物打印技术正在经历快速发展&#xff0c;而扩散基生物打印作为一种新兴策略&#xff0c;为制造更复杂和功能化的组织构建物提供了新的可能性。这种方法利用扩散原理&#xff0c;通过在不同区域之间扩散酶、交联剂或可交联聚合物来促进交联&#xff0c;从而实现多种材料的集成…

【论文阅读笔记】ASPS: Augmented Segment Anything Model for Polyp Segmentation

1.论文介绍 ASPS: Augmented Segment Anything Model for Polyp Segmentation ASPS&#xff1a;用于息肉分割的扩展SAM模型 2024年 arxiv Paper Code 2.摘要 息肉分割在结直肠癌诊断中起着至关重要的作用。最近&#xff0c;Segment Anything Model(SAM)的出现利用其在大规模…

软件缺陷简介

缺陷种类 遗漏&#xff0c;指规定或预期的需求为体现在产品种错误&#xff0c;需求是明确的&#xff0c;在实现阶段未将需求的功能正确实现冗余&#xff0c;需求说明文档中未涉及的需求被实现了不满意&#xff0c;用户对产品的实现不满意也成为缺陷 缺陷等级划分 致命&#…

【测试】软件测试报告模板(直接套用)

软件资料清单列表部分文档清单&#xff1a;工作安排任务书&#xff0c;可行性分析报告&#xff0c;立项申请审批表&#xff0c;产品需求规格说明书&#xff0c;需求调研计划&#xff0c;用户需求调查单&#xff0c;用户需求说明书&#xff0c;概要设计说明书&#xff0c;技术解…

PGCCC|【PostgreSQL】PCA+PCP+PCM等IT类认证申报个税退税指南

小编特将PostgreSQL证书申报个税退税流程&#xff0c;编辑成文&#xff0c;供大家申报参考哦~ 1.申报专项附加扣除 第一步&#xff1a;打开个人所得税APP&#xff0c;选择“专项附加扣除填报”&#xff1a; 第二步&#xff1a;“扣除年度”选择您要申报的年度&#xff0c;并…

Java之封装、继承,多态

文章目录 Java 之封装、继承&#xff0c;多态一、封装1.封装的基本介绍2. 封装的实现3. 将构造器与 setXxx 方法结合 二、继承1. 继承的基本介绍2. 基本语法3.继承的深入理解4. 继承的本质分析&#xff08;内存存在形式&#xff09;5. 子类创建的内存布局6. super 关键字6.1 su…