前言
如果我们遇到路径问题,可以使用点点连线,给定一个点,可以到达另外几个点,寻找最优解
例:如下图所示,如果要从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, -- 内场点位Idptname 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当子组件示例,点点绘制图形