C# 根据两点名称,寻找两短路程的最优解,【有数据库设计,完整代码】

前言

如果我们遇到路径问题,可以使用点点连线,给定一个点,可以到达另外几个点,寻找最优解
例:如下图所示,如果要从A1-C1,可以有三条路

1.A1-B1-C1
2.A1-B2-C1
3.A1-B3-C1

最优解肯定是A1-B1-C1,因为两点之间直线最短,但当业务复杂时,我们就要通过轮询来查出最优路径
在这里插入图片描述

数据库设计

首先是数据库的设计:创建表:sys_pilot

CREATE TABLE sys_pilot (
	pilotid numeric(1000) NOT NULL, -- 内场点位Id
	ptname varchar(50) NOT NULL, -- 点位名称
	xaxis int4 NOT NULL, -- X轴
	yaxis int4 NULL, -- Y轴
	transfer varchar(500) NULL, -- 经过点
	CONSTRAINT sys_pilot_pk PRIMARY KEY (pilotid)
);
COMMENT ON TABLE public.sys_pilot IS '点位图表';

后端代码

根据传入的两点名称,例:A1,C1
最优解:A1-B1-C1就会被依次返回

        private static Dictionary<string, Sys_Pilot> _points;
		/// <summary>
        /// 查找图形点位
        /// </summary>
        /// <param name="json"></param>
        /// <returns></returns>
        /// <exception cref="InterfaceException"></exception>
        public List<Sys_Pilot> VerifyPilot(string json)
        {
            Sys_Pilot pilot = JsonHelper.Instance.Deserialize<Sys_Pilot>(json);
            string[] values = pilot.PtName.Split(',');

            if (values.Length != 2)
            {
                throw new InterfaceException("请传入两个点");
            }

            string inPoint = values[0];
            string terminus = values[1];

            List<Sys_Pilot> pilots = _paramsDal.FindData(new Sys_Pilot());


            List<Sys_Pilot> shortestPath = ShortestPath(pilots, inPoint, terminus);

            return shortestPath;
        }
        /// <summary>
        /// 轮询查出中间点
        /// </summary>
        /// <param name="pilots"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public List<Sys_Pilot> ShortestPath(List<Sys_Pilot> pilots, string start, string end)
        {
            _points = pilots.ToDictionary(p => p.PtName);

            Dictionary<string, int> distances = new Dictionary<string, int>();
            Dictionary<string, string> previous = new Dictionary<string, string>();
            HashSet<string> visited = new HashSet<string>();

            foreach (var point in _points.Values)
            {
                distances[point.PtName] = int.MaxValue;
                previous[point.PtName] = null;
            }

            distances[start] = 0;

            while (visited.Count < _points.Count)
            {
                string current = null;
                int shortestDistance = int.MaxValue;
                foreach (var point in _points.Values)
                {
                    if (!visited.Contains(point.PtName) && distances[point.PtName] < shortestDistance)
                    {
                        current = point.PtName;
                        shortestDistance = distances[point.PtName];
                    }
                }

                visited.Add(current);

                if (current == end)
                    break;

                if (_points[current].Transfer != null) 
                {
                    foreach (var neighbor in _points[current].Transfer.Split(','))
                    {
                        if (!_points.ContainsKey(neighbor))
                            continue;

                        int alt = distances[current] + Distance(_points[current], _points[neighbor]);
                        if (alt < distances[neighbor])
                        {
                            distances[neighbor] = alt;
                            previous[neighbor] = current;
                        }
                    }
                }
                else if (current == end) 
                {
                    break;
                }
            }

            List<Sys_Pilot> path = new List<Sys_Pilot>();
            string temp = end;
            while (temp != null)
            {
                path.Add(_points[temp]);
                temp = previous[temp];
            }
            path.Reverse();
            return path;
        }

        /// <summary>
        /// 计算X,Y轴距离距离
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        private int Distance(Sys_Pilot a, Sys_Pilot b)
        {
            return (int)Math.Sqrt(Math.Pow((a.XAxis - b.XAxis), 2) + Math.Pow((a.YAxis - b.YAxis), 2));
        }

后记

前端代码是通过Uni-app实现的,有兴趣可以看下Uni-app开发Canvas当子组件示例,点点绘制图形

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值