using HH.WMS.Common.Algorithm;
using HH.WMS.Entitys.Algorithm;
using HH.WMS.Entitys.Basic;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HH.WMS.Common.Algorithm
{
///
/// 策略实体 指可抽象出来的策略
///
public class AlgorTacticsCommon
{
#region 设备均衡 确定任务数最少对应的巷道下的货位列表
///
/// 设备均衡策略
///
/// AMS设备数据
/// 可用的货位列表
/// 返回使用的设备号
/// 计算后可用的货位列表
public List EquipmentBalance(List lstDevice, List lstTrueLocation, out string deviceCode)
{
//计算后可用的货位列表
List location_roadray = new List();
if (lstDevice == null || lstDevice.Count == 0)
{
location_roadray = lstTrueLocation;
deviceCode = "";
}
else
{
//按照任务数量顺序排列
lstDevice = lstDevice.OrderBy(o => o.taskNum).ToList();
//设备号
string device = string.Empty;
foreach (Device model in lstDevice)
{
string[] roadRay = model.roadWay.Split(',');
//获得当前设备所属巷道下的所有货位
location_roadray = lstTrueLocation.Where(o => roadRay.Contains(o.CN_S_ROADWAY)).ToList();
if (location_roadray != null && location_roadray.Count > 0)
{
device = model.deviceCode;
break;
}
}
deviceCode = device;
}
return location_roadray;
}
#endregion
#region 巷道均衡 返回巷道对应的货位列表
///
/// 巷道均衡策略
///
/// 可用的货位信息数据
/// 计算后返回的实体
public List RoadWayBalance(List lstTrueLocation)
{
//指定计算后返回的实体
List location_roadray = new List();
//按照巷道分组 并获得巷道中可用货位的数据
//之后进行倒叙 找到可用货位最多的巷道
var v = lstTrueLocation.GroupBy(x => x.CN_S_ROADWAY).Select(g => (new
{
roadWay = g.Key,
qty = g.Count()
})).OrderByDescending(o => o.qty);
//倒叙排列后的巷道 循环
foreach (var item in v)
{
//取得巷道列表中可用货位最多的巷道 并获取巷道中所有货位
location_roadray = lstTrueLocation.Where(o => o.CN_S_ROADWAY == item.roadWay).ToList();
if (location_roadray != null && location_roadray.Count > 0)
{
break;
}
}
return location_roadray;
}
#endregion
#region 就近原则 只返回一个货位实体
///
/// 就近原则
///
/// 一个巷道内的所有货位数据
///
public List NearbyBalance(List lstTrueLocation)
{
List lstNearLocation = new List();
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
{
return lstNearLocation;
}
//先判断是否存在多个巷道,如果存在就近选择一个巷道
var location_roadray = lstTrueLocation.OrderBy(o => o.CN_S_ROADWAY).Select(o => o.CN_S_ROADWAY).Distinct().ToList();
if(location_roadray!=null && location_roadray.Count >1 )
{
lstTrueLocation = lstTrueLocation.Where(o => o.CN_S_ROADWAY == location_roadray[0].ToString()).ToList();
}
//按照排分组 并获得排中可用货位的数据
var v = lstTrueLocation.GroupBy(x => x.CN_S_ROW).Select(g => (new
{
row = g.Key,
qty = g.Count()
})).OrderByDescending(o => o.qty).ThenBy(o => o.row).ToList();//按照货位可用数量进行倒叙,找到可用货位最多的排
//如果每一排中可用货位相同,则在顺序排列,取最近的排
//找到排空货位最多的排
var v_row = lstTrueLocation.Where(o => o.CN_S_ROW == v[0].row).ToList();
//找到最小的列
var v_col = v_row.OrderBy(o => o.CN_S_COL.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_COL)).ToList();
var min_col = v_col[0].CN_S_COL;
//找到一个排下最小的列对应的所有货位
var v_f = v_row.Where(o => o.CN_S_COL == min_col).OrderBy(o => o.CN_S_FLOOR.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_FLOOR)).ToList();
//先按照层倒叙取最小的层
var min_floor = v_f[0].CN_S_FLOOR;
//获得层最小的单个
lstNearLocation.Add(v_f.Where(o => o.CN_S_FLOOR == min_floor).FirstOrDefault());
return lstNearLocation;
}
#endregion
#region 就近原则 只返回一个货位实体
///
/// 就近原则
///
/// 一个巷道内的所有货位数据
///
public List NearbyBalanceRow(List lstTrueLocation)
{
List lstNearLocation = new List();
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
{
return lstNearLocation;
}
//先判断是否存在多个巷道,如果存在就近选择一个巷道
var location_row = lstTrueLocation.OrderBy(o => o.CN_S_ROW).Select(o => o.CN_S_ROW).Distinct().ToList();
//找到排空货位最多的排
var v_row = lstTrueLocation.Where(o => o.CN_S_ROW == location_row[0]).ToList();
//找到最小的列
var v_col = v_row.OrderBy(o => o.CN_S_COL.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_COL)).ToList();
var min_col = v_col[0].CN_S_COL;
//找到一个排下最小的列对应的所有货位
var v_f = v_row.Where(o => o.CN_S_COL == min_col).OrderBy(o => o.CN_S_FLOOR.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_FLOOR)).ToList();
//先按照层倒叙取最小的层
var min_floor = v_f[0].CN_S_FLOOR;
//获得层最小的单个
lstNearLocation.Add(v_f.Where(o => o.CN_S_FLOOR == min_floor).FirstOrDefault());
return lstNearLocation;
}
#endregion
#region 货位平均使用原则 只返回一个货位实体
///
/// 货位平均使用原则
///
/// 一个巷道内的所有货位数据
///
public AutoBomLocationAbbreEntity AverageBalance(List lstTrueLocation)
{
AutoBomLocationAbbreEntity nearLocationEntity = new AutoBomLocationAbbreEntity();
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
{
return nearLocationEntity;
}
//按照排分组 并获得排中可用货位的数据
var v = lstTrueLocation.OrderBy(o => o.CN_N_INTASK_QTY).ToList();//按照货位可用数量进行升序, 找到CN_N_INTASK_QTY最小的货位
nearLocationEntity = v.FirstOrDefault();
return nearLocationEntity;
}
#endregion
#region 宇寿入库 先进后出
///
/// 就近原则
///
/// 一个巷道内的所有货位数据
///
public List FirstInLastOut(List lstTrueLocation, List lstAllLocation, List lstLockLItem, List lstStrate)
{
List location_rowray = new List();
List lstResultLocation = new List();
List lstFalseLocation = new List();
List lstEmptyCol = new List();
//获得库区中含有空货位的列
if (lstStrate.Contains("InSmallToBig"))
{
lstEmptyCol = lstTrueLocation.OrderBy(o => o.CN_S_ROW).ThenBy(o => int.Parse(o.CN_S_COL)).Distinct().ToList();
}
else if (lstStrate.Contains("InBigToSmall"))
{
lstEmptyCol = lstTrueLocation.OrderBy(o => o.CN_S_ROW).ThenByDescending(o => int.Parse(o.CN_S_COL)).Distinct().ToList();
}
else
{
lstEmptyCol = lstTrueLocation.OrderBy(o => o.CN_S_ROW).ThenBy(o => int.Parse(o.CN_S_COL)).Distinct().ToList();
}
Log.AlgorInfo("InAssign-FirstInLastOut", "lstEmptyCol数据:" + JsonConvert.SerializeObject(lstEmptyCol));
//查找最小列中的货位
location_rowray = lstTrueLocation.Where(o => o.CN_S_COL == lstEmptyCol[0].CN_S_COL && o.CN_S_ROW == lstEmptyCol[0].CN_S_ROW).ToList();
//找到该列下最小的层
var v_f = location_rowray.OrderBy(o => o.CN_S_FLOOR.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_FLOOR)).ToList();
//先按照层倒叙取最小的层
var min_floor = v_f[0].CN_S_FLOOR;
//获得层最小的单个
lstResultLocation.Add(v_f.Where(o => o.CN_S_FLOOR == min_floor).FirstOrDefault());
return lstResultLocation;
}
#endregion
#region 隆基入库 先进后出
///
/// 就近原则
///
/// 一个巷道内的所有货位数据
///
public List FirstInLastOutLj(List lstTrueLocation, List lstAllLocation, List lstLockLItem, List lstStrate)
{
List location_rowray = new List();
List lstResultLocation = new List();
List lstFalseLocation = new List();
List lstEmptyCol = new List();
//获得库区中含有空货位的列
if (lstStrate.Contains("InSmallToBig"))
{
lstEmptyCol = lstTrueLocation.OrderBy(o => int.Parse(o.CN_S_COL)).ThenBy(o => o.CN_S_ROW).Distinct().ToList();
}
else if (lstStrate.Contains("InBigToSmall"))
{
lstEmptyCol = lstTrueLocation.OrderBy(o => int.Parse(o.CN_S_COL)).ThenByDescending(o => o.CN_S_ROW).Distinct().ToList();
}
else
{
lstEmptyCol = lstTrueLocation.OrderBy(o => int.Parse(o.CN_S_COL)).ThenBy(o => o.CN_S_ROW).Distinct().ToList();
}
Log.AlgorInfo("InAssign-FirstInLastOut", "lstEmptyCol数据:" + JsonConvert.SerializeObject(lstEmptyCol));
//查找最小列中的货位
location_rowray = lstTrueLocation.Where(o => o.CN_S_COL == lstEmptyCol[0].CN_S_COL && o.CN_S_ROW == lstEmptyCol[0].CN_S_ROW).ToList();
//找到该列下最小的层
var v_f = location_rowray.OrderBy(o => o.CN_S_FLOOR.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_FLOOR)).ToList();
//先按照层倒叙取最小的层
var min_floor = v_f[0].CN_S_FLOOR;
//获得层最小的单个
lstResultLocation.Add(v_f.Where(o => o.CN_S_FLOOR == min_floor).FirstOrDefault());
return lstResultLocation;
}
#endregion
#region 设备均衡 确定任务数最少对应的巷道下的货位列表
///
/// 设备均衡策略
///
/// AMS设备数据
/// 可用的货位列表
/// 返回使用的设备号
/// 计算后可用的货位列表
public List EquipmentBalanceOut(List lstDevice, List lstTrueLocation, out string deviceCode)
{
//计算后可用的货位列表
List location_roadray = new List();
if (lstDevice == null || lstDevice.Count == 0)
{
location_roadray = lstTrueLocation;
deviceCode = "";
}
else
{
//按照任务数量顺序排列
lstDevice = lstDevice.OrderBy(o => o.taskNum).ToList();
//设备号
string device = string.Empty;
foreach (Device model in lstDevice)
{
string[] roadRay = model.roadWay.Split(',');
//获得当前设备所属巷道下的所有货位
location_roadray = lstTrueLocation.Where(o => roadRay.Contains(o.CN_S_ROADWAY)).ToList();
if (location_roadray != null && location_roadray.Count > 0)
{
device = model.deviceCode;
break;
}
}
deviceCode = device;
}
return location_roadray;
}
#endregion
#region 巷道均衡 返回巷道对应的货位列表
///
/// 巷道均衡策略
///
/// 可用的货位信息数据
/// 计算后返回的实体
public List RoadWayBalanceOut(List lstTrueLocation)
{
//指定计算后返回的实体
List location_roadray = new List();
//按照巷道分组 并获得巷道中可用货位的数据
//之后进行倒叙 找到可用货位最多的巷道
var v = lstTrueLocation.GroupBy(x => x.CN_S_ROADWAY).Select(g => (new
{
roadWay = g.Key,
qty = g.Count()
})).OrderByDescending(o => o.qty);
//倒叙排列后的巷道 循环
foreach (var item in v)
{
//取得巷道列表中可用货位最多的巷道 并获取巷道中所有货位
location_roadray = lstTrueLocation.Where(o => o.CN_S_ROADWAY == item.roadWay).ToList();
if (location_roadray != null && location_roadray.Count > 0)
{
break;
}
}
return location_roadray;
}
#endregion
#region 就近原则 只返回一个货位实体
///
/// 就近原则
///
/// 一个巷道内的所有货位数据
///
public List NearbyBalanceOut(List lstTrueLocation)
{
List lstNearLocation = new List();
if (lstTrueLocation == null || lstTrueLocation.Count == 0)
{
return lstNearLocation;
}
//先判断是否存在多个巷道,如果存在就近选择一个巷道
var location_roadray = lstTrueLocation.OrderBy(o => o.CN_S_ROADWAY).Select(o => o.CN_S_ROADWAY).Distinct().ToList();
if (location_roadray != null && location_roadray.Count > 1)
{
lstTrueLocation = lstTrueLocation.Where(o => o.CN_S_ROADWAY == location_roadray[0].ToString()).ToList();
}
//按照排分组 并获得排中可用货位的数据
var v = lstTrueLocation.GroupBy(x => x.CN_S_ROW).Select(g => (new
{
row = g.Key,
qty = g.Count()
})).OrderByDescending(o => o.qty).ThenBy(o => o.row).ToList();//按照货位可用数量进行倒叙,找到可用货位最多的排
//如果每一排中可用货位相同,则在顺序排列,取最近的排
//找到排空货位最多的排
var v_row = lstTrueLocation.Where(o => o.CN_S_ROW == v[0].row).ToList();
//找到最小的列
var v_col = v_row.OrderBy(o => o.CN_S_COL.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_COL)).ToList();
var min_col = v_col[0].CN_S_COL;
//找到一个排下最小的列对应的所有货位
var v_f = v_row.Where(o => o.CN_S_COL == min_col).OrderBy(o => o.CN_S_FLOOR.Trim().Length == 0 ? 0 : int.Parse(o.CN_S_FLOOR)).ToList();
//先按照层倒叙取最小的层
var min_floor = v_f[0].CN_S_FLOOR;
//获得层最小的单个
lstNearLocation.Add(v_f.Where(o => o.CN_S_FLOOR == min_floor).FirstOrDefault());
return lstNearLocation;
}
#endregion
}
}