| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 | using System;using System.Collections.Generic;using System.Linq;namespace wms.service.Extensions.LayerPacking.model{    /// <summary>    /// 层信息    /// </summary>    public class LayerPackingLayerInfo    {        /// <summary>        /// 层产品        /// </summary>        public List<LayerPackingProduct> Products { get; set; }        /// <summary>        /// 层总扭转值        /// </summary>        public decimal TotalTorsion => Products.Sum(p => p.TorsChkValue);        /// <summary>        /// 层总焊点盘数        /// </summary>        public int SolderProductCount => Products.Count(p => p.IsSolderProduct);        /// <summary>        /// 层总焊点数        /// </summary>        public decimal TotalSolderJoints => Products.Sum(p => p.SolderCount);        /// <summary>        /// 层最小目标值        /// </summary>        public decimal MinLayerTarget { get; set; }        /// <summary>        /// 层最大目标值        /// </summary>        public decimal MaxLayerTarget { get; set; }        /// <summary>        /// 层去掉最大最小值后的最大标准差        /// </summary>        private double LayerStandardDeviation = 0.5;        /// <summary>        /// 层目标值        /// </summary>        public decimal LayerTarget { get; set; }        /// <summary>        /// 构造函数        /// </summary>        public LayerPackingLayerInfo()        {            Products = new List<LayerPackingProduct>();        }        /// <summary>        /// 当前层是否有效        /// </summary>        /// <param name="constraints"></param>        /// <returns></returns>        public bool IsValid(LayerPackingConstraints constraints)        {            var total = TotalTorsion;            return total >= constraints.MinLayerTotal && total <= constraints.MaxLayerTotal && LayerStdValid();        }        /// <summary>        /// 获取当前层偏差        /// </summary>        /// <param name="target"></param>        /// <returns></returns>        public decimal GetDeviationFromTarget(decimal target)        {            return Math.Abs(TotalTorsion - target);        }        /// <summary>        /// 当前层中极值对是否有效        /// </summary>        /// <param name="highThreshold">大极值阈值</param>        /// <param name="lowThreshold">小极值阈值</param>        /// <returns></returns>        public bool HasValidExtremePair(decimal highThreshold, decimal lowThreshold)        {            var highCount = Products.Count(p => p.TorsChkValue >= highThreshold);            var lowCount = Products.Count(p => p.TorsChkValue <= lowThreshold);            return (highCount == 0 && lowCount == 0) || (highCount == 1 && lowCount == 1);        }        /// <summary>        /// 去除最大/最小值后10个产品的标准差≤0.5        /// </summary>        /// <returns></returns>        public bool LayerStdValid()        {            if (Products == null || Products.Count < 3) return true;            var ordered = Products.OrderBy(p => p.TorsChkValue).ToList();            var ten = ordered.Skip(1).Take(Products.Count - 2).ToList();            if (ten.Count > 10)            {                int skip = (ten.Count - 10) / 2;                ten = ten.Skip(skip).Take(10).ToList();            }            if (ten.Count < 1) return true;            double avg = (double)ten.Average(p => p.TorsChkValue);            double std = Math.Sqrt(ten.Sum(p => Math.Pow((double)p.TorsChkValue - avg, 2)) / ten.Count);            return std <= LayerStandardDeviation;        }        /// <summary>        /// 获取层标准差(去除最大最小后10个产品)        /// </summary>        public double GetStdAfterTrim()        {            if (Products == null || Products.Count < 3) return 0;            var ordered = Products.OrderBy(p => p.TorsChkValue).ToList();            var ten = ordered.Skip(1).Take(Products.Count - 2).ToList();            if (ten.Count > 10)            {                int skip = (ten.Count - 10) / 2;                ten = ten.Skip(skip).Take(10).ToList();            }            if (ten.Count < 1) return 0;            double avg = (double)ten.Average(p => p.TorsChkValue);            double std = Math.Sqrt(ten.Sum(p => Math.Pow((double)p.TorsChkValue - avg, 2)) / ten.Count);            return std;        }    }}
 |