Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
2023-07-25 09:32:08 +08:00
3 changed files with 269 additions and 280 deletions

View File

@@ -1,215 +1,215 @@
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Text; using System.Text;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using JNPF.Common.Contracts; using JNPF.Common.Contracts;
//using NPOI.SS.Formula.Functions; using NPOI.SS.Formula.Functions;
//using Tnb.WarehouseMgr.Entities; using Tnb.WarehouseMgr.Entities;
//namespace Tnb.WarehouseMgr namespace Tnb.WarehouseMgr
//{ {
// /// <summary> /// <summary>
// /// 迪杰斯特拉(最短路径算法) /// 迪杰斯特拉(最短路径算法)
// /// </summary> /// </summary>
// public class Dijkstra<T> where T : BaseEntity<string>, IWmsRoadEntity, new() //public class Dijkstra<T> where T : BaseEntity<string>, IWmsRoadEntity, new()
// { //{
// public static int MAX = int.MaxValue; // public static int MAX = int.MaxValue;
// public int mEdgNum; // 边的数量 // public int mEdgNum; // 边的数量
// public VNode[] mVexs; // 顶点数组 // public VNode[] mVexs; // 顶点数组
// //private EData[] edges; //边的数组 // //private EData[] edges; //边的数组
// /* // /*
// * 创建图 // * 创建图
// * // *
// * 参数说明: // * 参数说明:
// * vexs -- 顶点数组 // * vexs -- 顶点数组
// * edges -- 边 // * edges -- 边
// */ // */
// public Dijkstra(string[] vexs, EData[] edges) // public Dijkstra(string[] vexs, EData[] edges)
// { // {
// // 初始化"顶点数"和"边数" // // 初始化"顶点数"和"边数"
// int vlen = vexs.Length; // int vlen = vexs.Length;
// int elen = edges.Length; // int elen = edges.Length;
// // 初始化"顶点" // // 初始化"顶点"
// mVexs = new VNode[vlen]; // mVexs = new VNode[vlen];
// for (int i = 0; i < mVexs.Length; i++) // for (int i = 0; i < mVexs.Length; i++)
// { // {
// mVexs[i] = new VNode(); // mVexs[i] = new VNode();
// mVexs[i].data = vexs[i]; // mVexs[i].data = vexs[i];
// mVexs[i].firstEdge = null; // mVexs[i].firstEdge = null;
// } // }
// // 初始化"边" // // 初始化"边"
// mEdgNum = elen; // mEdgNum = elen;
// for (int i = 0; i < elen; i++) // for (int i = 0; i < elen; i++)
// { // {
// // 读取边的起始顶点和结束顶点 // // 读取边的起始顶点和结束顶点
// string c1 = edges[i].start; // string c1 = edges[i].start;
// string c2 = edges[i].end; // string c2 = edges[i].end;
// int weight = edges[i].weight; // int weight = edges[i].weight;
// // 读取边的起始顶点和结束顶点 // // 读取边的起始顶点和结束顶点
// int p1 = GetPosition(c1); // int p1 = GetPosition(c1);
// int p2 = GetPosition(c2); // int p2 = GetPosition(c2);
// // 初始化node1 // // 初始化node1
// ENode node1 = new ENode(); // ENode node1 = new ENode();
// node1.ivex = p2; // node1.ivex = p2;
// node1.weight = weight; // node1.weight = weight;
// // 将node1链接到"p1所在链表的末尾" // // 将node1链接到"p1所在链表的末尾"
// if (mVexs[p1].firstEdge == null) // if (mVexs[p1].firstEdge == null)
// mVexs[p1].firstEdge = node1; // mVexs[p1].firstEdge = node1;
// else // else
// LinkLast(mVexs[p1].firstEdge, node1); // LinkLast(mVexs[p1].firstEdge, node1);
// // 初始化node2 // // 初始化node2
// ENode node2 = new ENode(); // ENode node2 = new ENode();
// node2.ivex = p1; // node2.ivex = p1;
// node2.weight = weight; // node2.weight = weight;
// // 将node2链接到"p2所在链表的末尾" // // 将node2链接到"p2所在链表的末尾"
// if (mVexs[p2].firstEdge == null) // if (mVexs[p2].firstEdge == null)
// mVexs[p2].firstEdge = node2; // mVexs[p2].firstEdge = node2;
// else // else
// LinkLast(mVexs[p2].firstEdge, node2); // LinkLast(mVexs[p2].firstEdge, node2);
// } // }
// } // }
// /* // /*
// * 将node节点链接到list的最后 // * 将node节点链接到list的最后
// */ // */
// private void LinkLast(ENode list, ENode node) // private void LinkLast(ENode list, ENode node)
// { // {
// ENode p = list; // ENode p = list;
// while (p.nextEdge != null) // while (p.nextEdge != null)
// p = p.nextEdge; // p = p.nextEdge;
// p.nextEdge = node; // p.nextEdge = node;
// } // }
// /* // /*
// * 返回ch位置 // * 返回ch位置
// */ // */
// private int GetPosition(string ch) // private int GetPosition(string ch)
// { // {
// for (int i = 0; i < mVexs.Length; i++) // for (int i = 0; i < mVexs.Length; i++)
// if (mVexs[i].data == ch) // if (mVexs[i].data == ch)
// return i; // return i;
// return -1; // return -1;
// } // }
// /* // /*
// * 获取边<start, end>的权值若start和end不是连通的则返回无穷大。 // * 获取边<start, end>的权值若start和end不是连通的则返回无穷大。
// */ // */
// private int GetWeight(int start, int end) // private int GetWeight(int start, int end)
// { // {
// if (start == end) // if (start == end)
// return 0; // return 0;
// ENode node = mVexs[start].firstEdge; // ENode node = mVexs[start].firstEdge;
// while (node != null) // while (node != null)
// { // {
// if (end == node.ivex) // if (end == node.ivex)
// return node.weight; // return node.weight;
// node = node.nextEdge; // node = node.nextEdge;
// } // }
// return MAX; // return MAX;
// } // }
// /* // /*
// * Dijkstra最短路径。 // * Dijkstra最短路径。
// * 即,统计图中"起点D"到其它各个顶点的最短路径。 // * 即,统计图中"起点D"到其它各个顶点的最短路径。
// * // *
// * 参数说明: // * 参数说明:
// * vs -- 起始顶点(start vertex)。 // * vs -- 起始顶点(start vertex)。
// * prev -- 前驱顶点数组。即prev[i]的值是"起点D"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。 // * prev -- 前驱顶点数组。即prev[i]的值是"起点D"到"顶点i"的最短路径所经历的全部顶点中,位于"顶点i"之前的那个顶点。
// * dist -- 长度数组。即dist[i]是"起点D"到"顶点i"的最短路径的长度。 // * dist -- 长度数组。即dist[i]是"起点D"到"顶点i"的最短路径的长度。
// */ // */
// public void CalcDijkstra(int vs, int[] prev, int[] dist, List<T> roads) // public void CalcDijkstra(int vs, int[] prev, int[] dist, List<T> roads)
// { // {
// //List<T> vertexs = new(); //最短路径串联的点位列表 // //List<T> vertexs = new(); //最短路径串联的点位列表
// // flag[i]=true表示"起点D"到"顶点i"的最短路径已成功获取。 // // flag[i]=true表示"起点D"到"顶点i"的最短路径已成功获取。
// bool[] flag = new bool[mVexs.Length]; // bool[] flag = new bool[mVexs.Length];
// // 初始化 // // 初始化
// for (int i = 0; i < mVexs.Length; i++) // for (int i = 0; i < mVexs.Length; i++)
// { // {
// flag[i] = false; // 顶点i的最短路径还没获取到。 // flag[i] = false; // 顶点i的最短路径还没获取到。
// prev[i] = 0; // 顶点i的前驱顶点为0。 // prev[i] = 0; // 顶点i的前驱顶点为0。
// dist[i] = GetWeight(vs, i); // 顶点i的最短路径为"起点D"到"顶点i"的权。 // dist[i] = GetWeight(vs, i); // 顶点i的最短路径为"起点D"到"顶点i"的权。
// } // }
// // 对"起点D"自身进行初始化 // // 对"起点D"自身进行初始化
// flag[vs] = true; // flag[vs] = true;
// dist[vs] = 0; // dist[vs] = 0;
// // 遍历mVexs.Length-1次每次找出一个顶点的最短路径。 // // 遍历mVexs.Length-1次每次找出一个顶点的最短路径。
// int k = 0; // int k = 0;
// for (int i = 1; i < mVexs.Length; i++) // for (int i = 1; i < mVexs.Length; i++)
// { // {
// // 寻找当前最小的路径 // // 寻找当前最小的路径
// // 即在未获取最短路径的顶点中找到离起点D最近的顶点(k)。 // // 即在未获取最短路径的顶点中找到离起点D最近的顶点(k)。
// int min = MAX; // int min = MAX;
// for (int j = 0; j < mVexs.Length; j++) // for (int j = 0; j < mVexs.Length; j++)
// { // {
// if (flag[j] == false && dist[j] < min) // if (flag[j] == false && dist[j] < min)
// { // {
// min = dist[j]; // min = dist[j];
// k = j; // k = j;
// } // }
// } // }
// // 标记"顶点k"为已经获取到最短路径 // // 标记"顶点k"为已经获取到最短路径
// flag[k] = true; // flag[k] = true;
// // 更新当前最短路径和前驱顶点 // // 更新当前最短路径和前驱顶点
// // 即,更新"未获取最短路径的顶点的最短路径和前驱顶点"。 // // 即,更新"未获取最短路径的顶点的最短路径和前驱顶点"。
// for (int j = 0; j < mVexs.Length; j++) // for (int j = 0; j < mVexs.Length; j++)
// { // {
// int tmp = GetWeight(k, j); // int tmp = GetWeight(k, j);
// tmp = (tmp == MAX ? MAX : (min + tmp)); // 防止溢出 // tmp = (tmp == MAX ? MAX : (min + tmp)); // 防止溢出
// if (flag[j] == false && (tmp < dist[j])) // if (flag[j] == false && (tmp < dist[j]))
// { // {
// dist[j] = tmp; // dist[j] = tmp;
// prev[j] = k; // prev[j] = k;
// } // }
// } // }
// } // }
// } // }
// } //}
// /// <summary> ///// <summary>
// /// 邻接表中表对应的链表的顶点 ///// 邻接表中表对应的链表的顶点
// /// </summary> ///// </summary>
// public class ENode //public class ENode
// { //{
// public int ivex; // 该边所指向的顶点的位置 // public int ivex; // 该边所指向的顶点的位置
// public int weight; // 该边的权 // public int weight; // 该边的权
// public ENode nextEdge; // 指向下一条弧的指针 // public ENode nextEdge; // 指向下一条弧的指针
// } //}
// /// <summary> ///// <summary>
// /// 邻接表中表的顶点 ///// 邻接表中表的顶点
// /// </summary> ///// </summary>
// public class VNode //public class VNode
// { //{
// public string data; // 顶点信息 // public string data; // 顶点信息
// public ENode firstEdge; // 指向第一条依附该顶点的弧 // public ENode firstEdge; // 指向第一条依附该顶点的弧
// } //}
// /// <summary> ///// <summary>
// /// 边的结构体 ///// 边的结构体
// /// </summary> ///// </summary>
// public class EData //public class EData
// { //{
// public string start; // 边的起点 // public string start; // 边的起点
// public string end; // 边的终点 // public string end; // 边的终点
// public int weight; // 边的权重 // public int weight; // 边的权重
// public EData(string start, string end, int weight) // public EData(string start, string end, int weight)
// { // {
// this.start = start; // this.start = start;
// this.end = end; // this.end = end;
// this.weight = weight; // this.weight = weight;
// } // }
// } //}
//} }

View File

@@ -561,88 +561,77 @@ namespace Tnb.WarehouseMgr
private async Task<List<WmsPointH>> LocPathCalcAlgorithms(string pStartId, string pEndId, List<WmsRoad> roads) private async Task<List<WmsPointH>> LocPathCalcAlgorithms(string pStartId, string pEndId, List<WmsRoad> roads)
{ {
var points = await _db.Queryable<WmsPointH>().ToListAsync(); #region dp
List<WmsPointH> results = new(); //List<WmsPointH> results = new();
Dictionary<string, bool> isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false);
List<string> pointIds = new();
List<string> codes = new();
Dp dp = new();
dynamic obj = new ExpandoObject();
obj.isArrivedEpoint = false;
dp.DpFunc(roads, pointIds, isVisited, pStartId, pEndId, obj);
foreach (var pid in pointIds)
{
var point = points.Find(x => x.id == pid);
if (point != null)
{
results.Add(point);
}
}
return results;
#region dijkstra
//var points = await _db.Queryable<WmsPointH>().ToListAsync(); //var points = await _db.Queryable<WmsPointH>().ToListAsync();
//var startObj = points.Find(x => x.id == pStartId); //Dictionary<string, bool> isVisited = roads.Select(x => x.startpoint_id).Distinct().ToDictionary(x => x, x => false);
//var endObj = points.Find(x => x.id == pEndId);
//var sIndex = points.IndexOf(startObj); //List<string> pointIds = new();
//var eIndex = points.IndexOf(endObj); //List<string> codes = new();
//if (eIndex < sIndex) //Dp dp = new();
//dynamic obj = new ExpandoObject();
//obj.isArrivedEpoint = false;
//dp.DpFunc(roads, pointIds, isVisited, pStartId, pEndId, obj);
//foreach (var pid in pointIds)
//{ //{
// var tempIndex = sIndex; // var point = points.Find(x => x.id == pid);
// sIndex = eIndex; // if (point != null)
// eIndex = tempIndex;
// var temp = points[sIndex];
// points[sIndex] = points[eIndex];
// points[eIndex] = temp;
//}
////MatchPoint(results, roads, shortestPathPoints, isVisited, pStartId, pEndId);
//var vexs = points.Select(p => p.id).ToArray();
//EData[] edges = new EData[roads.Count];
//for (int i = 0; i < edges.Length; i++)
//{
// var start = roads[i].startpoint_id;
// var end = roads[i].endpoint_id;
// var weight = roads[i].distance;
// edges[i] = new EData(start, end, weight);
//}
//Dijkstra pG = new(vexs, edges);
//int[] prev = new int[pG.mVexs.Length];
//int[] dist = new int[pG.mVexs.Length];
//List<WmsPointH> vertexs = new() { startObj };
//pG.CalcDijkstra(sIndex, prev, dist);
//var pointIds = points.Select(p => p.id).ToList();
//List<string> result = new();
//GetPoints(pointIds, prev, result, eIndex);
//var items =new List<string>();
//foreach (var item in prev.Where(x=>x!=0))
//{
// if (points[item] != null)
// { // {
// items.Add(points[item].point_code); // results.Add(point);
// } // }
//} //}
//var @strings = string.Join(",", items.OrderBy(o=>o)); //return results;
#endregion
//var shortestPathPoints = points.FindAll(x => result.Contains(x.id)); #region dijkstra
//if (shortestPathPoints.IndexOf(startObj) < 0) var points = await _db.Queryable<WmsPointH>().ToListAsync();
//{ var startObj = points.Find(x => x.id == pStartId);
// shortestPathPoints.Add(startObj); var endObj = points.Find(x => x.id == pEndId);
//} var sIndex = points.IndexOf(startObj);
var eIndex = points.IndexOf(endObj);
if (eIndex < sIndex)
{
var tempIndex = sIndex;
sIndex = eIndex;
eIndex = tempIndex;
var temp = points[sIndex];
points[sIndex] = points[eIndex];
points[eIndex] = temp;
}
//List<WmsPointH> results = new() { startObj }; var vexs = points.Select(p => p.id).ToArray();
//var isVisited = shortestPathPoints.ToDictionary(x => x.id, x => false); EData[] edges = new EData[roads.Count];
//var isVisited2 = shortestPathPoints.ToDictionary(x => x.id, x => false); for (int i = 0; i < edges.Length; i++)
//isVisited[pStartId] = true; {
var start = roads[i].startpoint_id;
var end = roads[i].endpoint_id;
var weight = roads[i].distance;
edges[i] = new EData(start, end, weight);
}
//MatchPoint(results, roads, shortestPathPoints, isVisited, pStartId, pEndId); Dijkstra pG = new(vexs, edges);
//results.Add(endObj); int[] prev = new int[pG.mVexs.Length];
int[] dist = new int[pG.mVexs.Length];
List<WmsPointH> vertexs = new() { startObj };
pG.CalcDijkstra(sIndex, prev, dist);
var pointIds = points.Select(p => p.id).ToList();
Stack<string> result = new();
GetPoints(pointIds, prev, result, eIndex);
List<WmsPointH> results = new() { startObj };
if (points?.Count > 0)
{
foreach (var i in result)
{
WmsPointH? point = points?.Find(x => x.id == i);
if (point != null)
{
results.Add(point);
}
}
}
return results;
#endregion #endregion
} }
@@ -677,12 +666,12 @@ namespace Tnb.WarehouseMgr
/// <param name="prev"></param> /// <param name="prev"></param>
/// <param name="result"></param> /// <param name="result"></param>
/// <param name="eIdx"></param> /// <param name="eIdx"></param>
private static void GetPoints(List<string> pointIds, int[] prev, List<string> result, int eIdx) private static void GetPoints(List<string> pointIds, int[] prev, Stack<string> result, int eIdx)
{ {
var index = eIdx; var index = eIdx;
while (index != 0) while (index != 0)
{ {
result.Add(pointIds[index]); result.Push(pointIds[index]);
index = prev[index]; index = prev[index];
} }
} }

View File

@@ -62,15 +62,15 @@ namespace Tnb.Common.Utils
mVexs[p1].firstEdge = node1; mVexs[p1].firstEdge = node1;
else else
LinkLast(mVexs[p1].firstEdge, node1); LinkLast(mVexs[p1].firstEdge, node1);
// 初始化node2 //// 初始化node2
ENode node2 = new ENode(); //ENode node2 = new ENode();
node2.ivex = p1; //node2.ivex = p1;
node2.weight = weight; //node2.weight = weight;
// 将node2链接到"p2所在链表的末尾" //// 将node2链接到"p2所在链表的末尾"
if (mVexs[p2].firstEdge == null) //if (mVexs[p2].firstEdge == null)
mVexs[p2].firstEdge = node2; // mVexs[p2].firstEdge = node2;
else //else
LinkLast(mVexs[p2].firstEdge, node2); // LinkLast(mVexs[p2].firstEdge, node2);
} }
} }