C#实现最短路径算法

news2024/9/21 22:40:08

 创建点集

            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));
        }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[web]-图片上传、文件包含-图片上传

题目内容提示&#xff1a;上传图片试试吧&#xff0c;注意统一时区问题 打开页面如图&#xff0c;源码没有过滤&#xff0c;随便输入&#xff0c;进入上传目录 根据链接可以看到是文件包含&#xff0c;可以利用编码读取源码&#xff0c;这里只列出有用页面的编码&#xff08;?…

数据结构:链表详解 (c++实现)

前言 对于数据结构的线性表&#xff0c;其元素在逻辑结构上都是序列关系&#xff0c;即数据元素之间有前驱和后继关系。 但在物理结构上有两种存储方式&#xff1a; 顺序存储结构&#xff1a; 使用此结构的线性表也叫 顺序表物理存储上是连续的&#xff0c;因此可以随机访问…

Redis 中Sorted Set 类型命令(命令语法、操作演示、命令返回值、时间复杂度、注意事项)

Sorted Set 类型 文章目录 Sorted Set 类型zadd 命令zrange 命令zcard 命令zcount 命令zrevrange 命令zrangebyscore 命令zpopmax 命令bzpopmax 命令zpopmin 命令bzpopmin 命令zrank 命令zscore 命令zrem 命令zremrangebyrank 命令zremrangebyscore 命令zincrby 命令zinterstor…

秋招Java后端开发冲刺——Mybatis使用总结

一、基本知识 1. 介绍 MyBatis 是 Apache 的一个开源项目&#xff0c;它封装了 JDBC&#xff0c;使开发者只需要关注 SQL 语句本身&#xff0c;而不需要再进行繁琐的 JDBC 编码。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java POJO&#xff08;Plain …

服务器数据恢复—2块硬盘离线且热备盘未完全激活的raid5数据恢复案例

服务器存储数据恢复环境&#xff1a; 北京某企业一台EMC FCAX-4存储上搭建一组由12块成员盘的raid5磁盘阵列&#xff0c;其中包括2块热备盘。 服务器存储故障&#xff1a; raid5阵列中两块硬盘离线&#xff0c;热备盘只有一块成功激活&#xff0c;raid瘫痪&#xff0c;上层LUN…

Sentinel限流算法:滑动时间窗算法、漏桶算法、令牌桶算法。拦截器定义资源实现原理

文章目录 滑动时间窗算法基本知识源码算法分析 漏桶算法令牌桶算法拦截器处理web请求 滑动时间窗算法 基本知识 限流算法最简单的实现就是使用一个计数器法。比如对于A接口来说&#xff0c;我要求一分钟之内访问量不能超过100&#xff0c;那么我们就可以这样来实现&#xff1…

学习C++,应该循序渐进的看哪些书?

学习C是一个循序渐进的过程&#xff0c;需要根据自己的基础和目标来选择合适的书籍。以下是一个推荐的学习路径&#xff0c;包含了从入门到进阶的书籍&#xff1a; 1. 入门阶段 《C Primer Plus 第6版 中文版》 推荐理由&#xff1a;这本书同样适合C零基础的学习者&#xff0…

几何建模-Parasolid中GO功能使用

1.背景介绍 1.1 Parasolid和它的接口间关系 1.2 什么是GO GO全称是Graphical Output.你的程序需要在屏幕或者打印设备上显示模型数据时。在需要使用PK中的某个渲染函数时创建图形显示数据时&#xff0c;Parasolid会调用GO相关的函数。GO函数会输出绘图指令给你的应用程序提供…

映美精黑白相机IFrameQueueBuffer转halcon的HObject

映美精黑白相机&#xff0c;用wpfhalcon开发取图 1.到官网下载&#xff0c;开发包 1sdk 2c开发例子 3c#开发例子 引入TIS.Imaging.ICImagingControl35.dll 3.ICImagingControl使用这个类控制相机 /// <summary> /// 相机控制 /// </summary> public ICImagingC…

《昇思25天学习打卡营第16天|基于MindNLP+MusicGen生成自己的个性化音乐》

MindNLP 原理 MindNLP 是一个自然语言处理&#xff08;NLP&#xff09;框架&#xff0c;用于处理和分析文本数据。 文本预处理&#xff1a;包括去除噪声、分词、词性标注、命名实体识别等步骤&#xff0c;使文本数据格式化并准备好进行进一步分析。 特征提取&#xff1a;将文…

LightRAG:高效构建和优化大型语言模型应用的 PyTorch 框架

一、前言 随着大语言模型 (LLM) 的蓬勃发展&#xff0c;检索增强生成 (RAG) 技术作为一种将 LLM 与外部知识库结合的有效途径&#xff0c;受到了越来越多的关注。 然而&#xff0c;构建 LLM 应用的真正挑战在于开发者需要根据具体需求进行高度定制化&#xff0c;而现有的 RAG …

《向量数据库指南》2024年中国向量数据库名录大全

2024年中国向量数据库名录大全 序号 百科ID 数据库名称 slogan 厂商 来源 开源 类型 1 1228 TensorDB 爱可生向量数据库 上海爱可生信息技术股份有限公司 自研 商业 向量 2 972 Milvus 开源向量数据库 上海赜睿信息科技…

centos安装minio文件系统服务器(踩坑版)

centos安装minio文件系统服务器&#xff08;踩坑版&#xff09; 引安装1. 下载2. 启动3. 创建access keys4. 创建buckets 坑 引 本来安装挺简单的&#xff0c;网上的教程一大堆&#xff0c;有些写的也挺详细的。不过自己还是踩到坑了&#xff0c;耽误了个把小时&#xff0c;特…

【源码+文档+调试讲解】全国消费水平展示平台

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于全国消费水平展示平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了全国消费水平展示平台&#xff0c;它彻底…

如何找回误删的文件?4个常用文件恢复方法!

对于许多用户来说&#xff0c;误删文件是一种常见而令人懊恼的情况。恢复误删文件的重要性在于&#xff0c;它可以帮助用户找回宝贵的数据&#xff0c;避免因数据丢失带来的各种不便和损失。 如何找回不小心删除的文件&#xff1f; 误删数据不知道怎么恢复&#xff0c;会给我…

对进阶指针的追忆

目录 思维导图 指针前言 一&#xff1a;字符指针 二&#xff1a;指针数组 三&#xff1a;数组指针 四&#xff1a;数组参数 && 指针参数 五&#xff1a;函数指针 六&#xff1a;函数指针数组 七&#xff1a;函数指针数组的指针 八&#xff1a;回调函数 思维导…

MySql 数据库 (基础) - 下载安装

MySQL数据库 简单介绍 数据库 数据存储的仓库数据库管理系统 操作和管理数据库的大型软件SQL 操作关系型数据库的变成语言&#xff0c;是一套标准 版本 MySQL官方提供了两种不同的版本&#xff1a; 社区版 免费&#xff0c;MySQL不提供任何的技术支持商业版 收费&#xff0c…

暑期备考美国数学竞赛AMC8和AMC10:吃透1850道真题和知识点

距离接下来的AMC8、AMC10美国数学竞赛还有几个月的时间&#xff0c;实践证明&#xff0c;做真题&#xff0c;吃透真题和背后的知识点是备考AMC8、AMC10有效的方法之一。 通过做真题&#xff0c;可以帮助孩子找到真实竞赛的感觉&#xff0c;而且更加贴近比赛的内容&#xff0c;…

谷粒商城实战笔记-29~34-前端基础 - ES6

文章目录 零&#xff0c;安装Live Server插件一&#xff0c;创建前端工程1&#xff0c;创建工程2&#xff0c;在工程ES6中创建一个html文件 二&#xff0c;ES6 简介1&#xff0c;ES6 的历史 三&#xff0c;前端基础ES61&#xff0c;let 和 const1.1&#xff0c;let1.1.1 严格的…

JavaScript青少年简明教程:开发工具与运行环境

JavaScript青少年简明教程&#xff1a;开发工具与运行环境 JavaScript是一种基于对象和事件驱动且具有安全性能的脚本语言。使用它和HTML结合可以开发出交互式的Web页面。 脚本语言是为了缩短传统的编写-编译-链接-运行过程而创建的计算机编程语言。脚本通常是解释执行而非编…