From e644b249b5a3d4b3b0e72f00d60eb06ae3743d3a Mon Sep 17 00:00:00 2001 From: chengsc <11752@DESKTOP-DS49RCP> Date: 星期六, 19 四月 2025 17:48:44 +0800 Subject: [PATCH] Merge branch 'master' of http://47.95.120.53:8083/r/JC34WMS --- Wms/WMS.DAL/Common.cs | 329 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 328 insertions(+), 1 deletions(-) diff --git a/Wms/WMS.DAL/Common.cs b/Wms/WMS.DAL/Common.cs index 3b87b65..3941cf0 100644 --- a/Wms/WMS.DAL/Common.cs +++ b/Wms/WMS.DAL/Common.cs @@ -1,6 +1,7 @@ 锘縰sing System; using System.Collections.Generic; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.Design; using System.Data; using System.Linq; @@ -8,6 +9,7 @@ using System.Threading.Tasks; using Model.ModelDto.BllSoDto; using Model.ModelDto.SysDto; +using Serilog; using SqlSugar; using WMS.Entity.BllAsnEntity; using WMS.Entity.BllCheckEntity; @@ -17,12 +19,13 @@ using WMS.Entity.LogEntity; using WMS.Entity.SysEntity; + namespace WMS.DAL { public class Common { //public static readonly DataContext Db = new DataContext(); - + /// <summary> /// 鑾峰彇娣卞害涓�1鐨勫偍浣嶅彿锛堟牴鎹繁搴︿负2鐨勫偍浣嶅彿锛� @@ -477,6 +480,268 @@ } } + /// <summary> + /// 鑾峰彇灏忚溅璺緞 + /// </summary> + /// <param name="startLocation">璧峰浣嶇疆</param> + /// <param name="endLocation">鐩爣浣嶇疆</param> + /// <param name="moveType">绉诲姩绫诲瀷 0:绉诲姩 1:鍙栬揣 2:鏀捐揣</param> + /// <param name="isLoad">鏄惁杞借揣0锛氭湭杞借揣 1锛氬凡杞借揣</param> + /// <returns></returns> + public static List<CarModel> GetCarPath(string startLocation, string endLocation, int moveType, string isLoad = "0") + { + var _db = DataContext.Db; + if (string.IsNullOrEmpty(startLocation) || string.IsNullOrEmpty(endLocation)) + { + return null; + } + + // 璧峰浣嶇疆 + CarModel start = new CarModel() + { + X = int.Parse(startLocation.Substring(0, 2)), + Y = int.Parse(startLocation.Substring(2, 2)), + Z = int.Parse(startLocation.Substring(4, 2)), + NodeCom = 0 + }; + + // 鐩爣浣嶇疆 + CarModel end = new CarModel() + { + X = int.Parse(endLocation.Substring(0, 2)), + Y = int.Parse(endLocation.Substring(2, 2)), + Z = int.Parse(endLocation.Substring(4, 2)), + NodeCom = 0 + }; + + // 鑾峰彇鍌ㄤ綅琛ㄤ俊鎭瓨鍌ㄥ埌闆嗗悎閲� + var layer = int.Parse(startLocation.Substring(4, 2)); + + // 鑾峰彇褰撳墠灞傚偍浣嶄俊鎭� + var locationModels = _db.Queryable<WCSStorageLocat>() + .Where(m => m.WareHouseNo == "W01" && m.Layer == layer && m.IsDelete == false) + .ToList(); + + #region 涓嶇敤缁樺埗鍦板浘锛岀洿鎺ユ牴鎹偍浣嶈〃璁$畻 liudl + // 缁樺埗浠撳簱鍦板浘 -1:涓嶅彲鐢� 0锛氫富閫氶亾 1锛氬瓙閫氶亾 + //int[,] warehouseMap = new int[maxRow, maxColumn]; + //for (int row = 0; row < maxRow; row++) + //{ + // for (int column = 0; column < maxColumn; column++) + // { + // // 鑾峰彇褰撳墠浣嶇疆鍌ㄤ綅淇℃伅 + // var locationModel = locationModels.First(it => it.Row == row && it.Column == column); + + // // 涓嶅瓨鍦ㄦ浣嶇疆淇℃伅 + // if (locationModel == null) + // { + // warehouseMap[row, column] = -1; + // continue; + // } + + // // 鍌ㄤ綅鐘舵�佷负鎹熷潖涓嶅彲閫氳 鍌ㄤ綅鐘舵�佷负灞忚斀涓哄彲閫氳涓嶅彲瀛樺偍鎵樼洏 + // if (locationModel.Flag == "2") + // { + // warehouseMap[row, column] = -1; + // continue; + // } + + // warehouseMap[row, column] = int.Parse(locationModel.Make); + // } + //} + #endregion + + #region 浣跨敤绠楁硶璁$畻灏忚溅璺緞 + try + { + // 瀹氫箟寮�鍙戝垪琛ㄥ瓨鍌ㄨ矾寰勮妭鐐� + var openSet = new SortedSet<(int fscore, CarModel pos)>(); + // 瀹氫箟鍏抽棴鑺傜偣瀛楀吀 + var closeSet = new Dictionary<CarModel, CarModel>(); + // 瀹氫箟涓婁竴浣嶇疆涓庣洰鏍囦綅缃瓧鍏� + var cameFrom = new Dictionary<CarModel, CarModel>(); + // 瀹氫箟涓婁竴浣嶇疆涓庣洰鏍囦綅缃殑瀹為檯璺濈瀛楀吀 + var gScore = new Dictionary<CarModel, int>(); + // 瀹氫箟涓婁竴浣嶇疆涓庣洰鏍囦綅缃殑棰勪及璺濈瀛楀吀 + var fScore = new Dictionary<CarModel, int>(); + + // 瀛樺偍鏈�浼樿窛绂伙紝鍙婅捣濮嬭妭鐐� + openSet.Add((Heuristic(start, end), start)); + gScore[start] = 0; + fScore[start] = Heuristic(start, end); + + // 寰幆鏌ユ壘璺緞 + while (openSet.Count > 0) + { + var current = openSet.Min.pos; + openSet.Remove(openSet.Min); + + if (current.Equals(end)) + { + Log.Error(ReconstructPath(cameFrom, current).ToString()); + return ReconstructPath(cameFrom, current); + } + + // 瀛樺偍灏忚溅鍙繍琛岀殑鏂瑰悜 + var validDirections = new List<CarModel>(); + var currentLocation = locationModels.FirstOrDefault(m => m.Row == current.X && m.Column == current.Y); + if (currentLocation.Make == "0") + { + // 涓婚�氶亾 + validDirections.Add(new CarModel() { X = 1, Y = 0 }); // 鍙� + validDirections.Add(new CarModel() { X = -1, Y = 0 }); // 宸� + validDirections.Add(new CarModel() { X = 0, Y = 1 }); // 涓� + validDirections.Add(new CarModel() { X = 0, Y = -1 }); // 涓� + } + + if (currentLocation.Make == "1" ) + { + // 瀛愰�氶亾 + // 鍏堟媶鍒嗗嚭鍙� + var outNode = currentLocation.AisleOne; + if (string.IsNullOrEmpty(outNode)) + { + throw new Exception("褰撳墠浣嶇疆娌℃湁缁存姢鍑哄彛锛�"); + } + int outX = int.Parse(outNode.Substring(0, 2)); + int outY = int.Parse(outNode.Substring(2, 2)); + if (current.X == outX) + { + validDirections.Add(new CarModel() { X = 0, Y = 1 }); // 涓� + validDirections.Add(new CarModel() { X = 0, Y = -1 }); // 涓� + + } + else + { + validDirections.Add(new CarModel() { X = 1, Y = 0 }); // 鍙� + validDirections.Add(new CarModel() { X = -1, Y = 0 }); // 宸� + } + } + + // 寰幆杩炴帴鑺傜偣銆� + bool isNextNode = false; + foreach (var dir in validDirections) + { + CarModel neighbor = new CarModel() { X = current.X + dir.X, Y = current.Y + dir.Y ,Z=layer}; + + // 楠岃瘉涓嬩竴鑺傜偣浣嶇疆鏄惁鍙�氳骞朵笖鍒ゆ柇鏄惁琚叾浠栧皬杞﹀崰鐢� + + + // 鍒ゆ柇涓嬩竴鑺傜偣鏄惁鍏抽棴 + if (closeSet.ContainsKey(neighbor)) + { + closeSet[neighbor] = neighbor; + } + + // 褰撳墠鑺傜偣 + var currentModel = locationModels.FirstOrDefault(it => it.Row == current.X && it.Column == current.Y); + // 涓嬩竴鑺傜偣 + var locationModel = locationModels.FirstOrDefault(it => it.Row == neighbor.X && it.Column == neighbor.Y); + + // 涓嶅瓨鍦ㄦ浣嶇疆淇℃伅 + if (locationModel == null) + { + closeSet[neighbor] = neighbor; + continue; + } + // 鍌ㄤ綅鐘舵�佷负鎹熷潖涓嶅彲閫氳 鍌ㄤ綅鐘舵�佷负灞忚斀涓哄彲閫氳涓嶅彲瀛樺偍鎵樼洏 + if (locationModel.Flag == "2") + { + closeSet[neighbor] = neighbor; + continue; + } + // 鍒ゆ柇涓嬩竴鑺傜偣涓婃槸鍚︽湁鎵樼洏 + if (!string.IsNullOrEmpty(locationModel.PalletNo)) + { + // 鍒ゆ柇灏忚溅鏄惁杞芥墭鐩樼洏 + if (isLoad == "1") + { + closeSet[neighbor] = neighbor; + // 灏忚溅涓婅浇鎵樼洏涓嶅彲閫氳璺宠繃 + continue; + } + } + // 浼樺寲椤癸紝楠岃瘉涓嬩竴鑺傜偣鏄惁琚埆鐨勫皬杞﹀崰鐢� liudl锛氬湪姝ゆ坊鍔犱紭鍖栦唬鐮� + + // 鏇存柊瀹為檯璺濈 + int tentativeGScore = gScore[current] + 1; + // 鍒ゆ柇浣嶇疆鏄惁宸插寘鍚湪璺緞鍐� 涓� 鏄惁鏇磋繎鑺傜偣 + if (!gScore.ContainsKey(neighbor) || tentativeGScore < gScore[neighbor]) + { + neighbor.IsSendPlc = false; + // 琛ュ厖鍙傛暟 + if (neighbor.Equals(end)) + { + neighbor.NodeCom = moveType; + neighbor.IsSendPlc = true; + } + else if (currentModel.Make != locationModel.Make) + { + if (current.X == neighbor.X) + { + neighbor.NodeCom = 3; + } + else if (current.Y == neighbor.Y) + { + neighbor.NodeCom = 2; + } + + neighbor.IsSendPlc = true; + } + + // 鏇存柊瀹為檯璺濈涓庨浼拌窛绂� + cameFrom[neighbor] = current; + gScore[neighbor] = tentativeGScore; + fScore[neighbor] = tentativeGScore + Heuristic(neighbor, end); + openSet.Add((fScore[neighbor], neighbor)); + isNextNode = true; + } + } + + if (!isNextNode) + { + closeSet[current] = current; + } + } + #endregion + } + catch (Exception ex) + { + throw ex; + } + + + return null; + } + + /// <summary> + /// 璁$畻鏇煎搱椤胯窛绂� + /// </summary> + /// <param name="start">璧峰浣嶇疆</param> + /// <param name="end">鐩爣浣嶇疆</param> + /// <returns>浣嶇疆璺濈</returns> + private static int Heuristic(CarModel start, CarModel end) + { + return Math.Abs(start.X - end.X) + Math.Abs(start.Y - end.Y); + } + + /// <summary> + /// 閲嶆瀯瀹屾暣璺緞 + /// </summary> + /// <param name="cameFrom"></param> + /// <param name="current"></param> + /// <returns></returns> + private static List<CarModel> ReconstructPath(Dictionary<CarModel, CarModel> cameFrom, CarModel current) + { + var path = new List<CarModel> { current }; + while (cameFrom.ContainsKey(current)) + { + current = cameFrom[current]; + path.Insert(0, current); + } + return path; + } + } public enum InOutFlag { @@ -522,4 +787,66 @@ [Description("璐ㄦ璇烽獙鍗�")] QC } + + public class CarModel : IComparable<CarModel> + { + /// <summary> + /// 琛�=X + /// </summary> + public int X { get; set; } + + /// <summary> + /// 鍒�=Y + /// </summary> + public int Y { get; set; } + + /// <summary> + /// 灞�=Z + /// </summary> + public int Z { get; set; } + + /// <summary> + /// 鑺傜偣鍛戒护 1:椤惰揣 2:瀛愰�氶亾杩愯 3:涓婚�氶亾杩愯 4:鏀捐揣 + /// </summary> + public int NodeCom { get; set; } + + /// <summary> + /// 鏄惁涓嬪彂plc + /// </summary> + public bool IsSendPlc { get; set; } + + public int CompareTo(CarModel other) + { + if (other == null) + return 1; + + // 杩欓噷鏍规嵁 X銆乊銆乑 鍧愭爣杩涜姣旇緝 + int result = X.CompareTo(other.X); + if (result != 0) + return result; + + result = Y.CompareTo(other.Y); + if (result != 0) + return result; + + return Z.CompareTo(other.Z); + } + + // 閲嶅啓 Equals 鏂规硶 + public override bool Equals(object obj) + { + if (obj == null || GetType() != obj.GetType()) + return false; + + CarModel other = (CarModel)obj; + return X == other.X && Y == other.Y && Z == other.Z; + } + + // 閲嶅啓 GetHashCode 鏂规硶 + public override int GetHashCode() + { + return HashCode.Combine(X, Y, Z); + } + } + } -- Gitblit v1.8.0