From a575a20126bbf40e4462ac283294ddf9a7cb9ad2 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Wed, 16 Jun 2021 15:19:46 +0200 Subject: [PATCH] Fix algoritmo ricerca step minimo --- NKC_WF/NKC_WF.csproj | 1 + NKC_WF/NLog.config | 29 +++++ .../cmp_batchDetailSplit.ascx.cs | 122 ++++++++++++------ NKC_WF/WebUserControls/cmp_batchList.ascx.cs | 33 ++++- NKC_WF/WebUserControls/cmp_orderExtList.ascx | 2 +- 5 files changed, 143 insertions(+), 44 deletions(-) create mode 100644 NKC_WF/NLog.config diff --git a/NKC_WF/NKC_WF.csproj b/NKC_WF/NKC_WF.csproj index f3c1428..b1ab65e 100644 --- a/NKC_WF/NKC_WF.csproj +++ b/NKC_WF/NKC_WF.csproj @@ -344,6 +344,7 @@ + diff --git a/NKC_WF/NLog.config b/NKC_WF/NLog.config new file mode 100644 index 0000000..6f8be8c --- /dev/null +++ b/NKC_WF/NLog.config @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NKC_WF/WebUserControls/cmp_batchDetailSplit.ascx.cs b/NKC_WF/WebUserControls/cmp_batchDetailSplit.ascx.cs index de80bbf..12c8abf 100644 --- a/NKC_WF/WebUserControls/cmp_batchDetailSplit.ascx.cs +++ b/NKC_WF/WebUserControls/cmp_batchDetailSplit.ascx.cs @@ -2,6 +2,7 @@ using NKC_SDK; using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using System.Web; using System.Web.UI; @@ -217,10 +218,8 @@ namespace NKC_WF.WebUserControls // sistemazione ratio calcolata... DS_App.OrderListTreeDataTable tabNe01 = DLMan.taOLT.getByBatch(cmp_orderExtListNE01.BatchId); DS_App.OrderListTreeDataTable tabNe02 = DLMan.taOLT.getByBatch(cmp_orderExtListNE02.BatchId); - double totTime01 = tabNe01.Sum(x => x.EstProcTime); double totTime02 = tabNe02.Sum(x => x.EstProcTime); - // aggiorno valore ratio e ratio last... fullTime = totTime01 + totTime02; fullTime = fullTime > 0 ? fullTime : 1; @@ -237,26 +236,25 @@ namespace NKC_WF.WebUserControls // solo se variato il ratio... if (valRatio != lastValRatio) { + Stopwatch stopWatch = new Stopwatch(); + stopWatch.Start(); // costruisco vettore durata ordini OrderSetSim FullSet = new OrderSetSim(); OrderSetSim SetNe01 = new OrderSetSim(); OrderSetSim SetNe02 = new OrderSetSim(); - // creo liste x i valori da processare... Dictionary RawList = new Dictionary(); Dictionary OrderedList = new Dictionary(); - foreach (var item in TabOrders) { RawList.Add(item.OrdID, item.EstProcTime); } - // ordino la lista x processing successivo OrderedList = RawList.OrderBy(x => x.Value).ToDictionary(t => t.Key, t => t.Value); - + // imposto maxDepth ... + int maxDepth = 5; // salvo i set FullSet.OrderSet = OrderedList; - // lavoro sull'ottimizzare il MINORE double ValRatioP = (double)valRatio / 100; // se uno è zero @@ -279,7 +277,7 @@ namespace NKC_WF.WebUserControls else if (valRatio <= 50) { SetNe01.TargetValue = FullSet.ActualValue * ValRatioP; - SetNe01.OrderSet = findLocalMin(OrderedList, SetNe01.TargetValue); + SetNe01.OrderSet = findLocalMin(OrderedList, SetNe01.TargetValue, maxDepth); // l'altro è la differenza SetNe02.OrderSet = OrderedList; foreach (var item in SetNe01.OrderSet) @@ -290,7 +288,7 @@ namespace NKC_WF.WebUserControls else { SetNe02.TargetValue = FullSet.ActualValue * (1 - ValRatioP); - SetNe02.OrderSet = findLocalMin(OrderedList, SetNe02.TargetValue); + SetNe02.OrderSet = findLocalMin(OrderedList, SetNe02.TargetValue, maxDepth); // l'altro è la differenza SetNe01.OrderSet = OrderedList; foreach (var item in SetNe02.OrderSet) @@ -298,7 +296,6 @@ namespace NKC_WF.WebUserControls SetNe01.OrderSet.Remove(item.Key); } } - // riorganizzo tabOrders... foreach (var orderItem in TabOrders) { @@ -317,9 +314,11 @@ namespace NKC_WF.WebUserControls } } } - // --> richiede salvataggio needSave = true; + // salvo tempo calcolo + stopWatch.Stop(); + Log.Instance.Info($"Rebalance executed | valRatio: {valRatio} | maxDepth: {maxDepth} | elapsed ms: {stopWatch.ElapsedMilliseconds}"); } fixRatio(); } @@ -341,14 +340,14 @@ namespace NKC_WF.WebUserControls /// Cerca il set con lo score migliore calcolando x subset della lista ordinata /// /// Lista ordinata oggetti (INT) + valore - /// Valore desiderato (comeSOMMA) + /// Valore desiderato (come SOMMA) + /// Massima profondità ricorsione accettata (x evitare loop infinito) /// - protected Dictionary findLocalMin(Dictionary OrderedList, double TargetVal) + protected Dictionary findLocalMin(Dictionary OrderedList, double TargetVal, int maxDepth) { Dictionary answ = new Dictionary(); List Candidates = new List(); OrderSetSim CurrSimSet = new OrderSetSim(); - // parte dal valore (singolo) più piccolo tra quelli maggiori del target... se c'è... var OrdSup = OrderedList.Where(x => x.Value > TargetVal).OrderBy(x => x.Value); if (OrdSup != null && OrdSup.Any()) @@ -359,7 +358,6 @@ namespace NKC_WF.WebUserControls CurrSimSet.OrderSet.Add(currOrder.Key, currOrder.Value); Candidates.Add(CurrSimSet); } - // ora guardo gli elementi restanti.. se ci sono var OrdInf = OrderedList.Where(x => x.Value <= TargetVal).OrderByDescending(x => x.Value).ToDictionary(t => t.Key, t => t.Value); if (OrdInf != null && OrdInf.Any()) @@ -369,30 +367,61 @@ namespace NKC_WF.WebUserControls CurrSimSet.TargetValue = TargetVal; CurrSimSet.OrderSet.Add(currOrder.Key, currOrder.Value); Candidates.Add(CurrSimSet); + // prendo i restanti tranne il primo OrdInf.Remove(currOrder.Key); - // se rimane qualcosa... - if (OrdInf != null && OrdInf.Any()) + + // guardo i successivi che NON superano + corrente... + Dictionary TestOrderSetMinDelta = findStepMin(OrdInf, TargetVal - currOrder.Value); + TestOrderSetMinDelta.Add(currOrder.Key, currOrder.Value); + // verifico se migliorativo... + if (TestOrderSetMinDelta.Count > 0) { - // calcolo il minimo locale nei 2 casi, da soli - Dictionary TestOrderSet01 = findLocalMin(OrdInf, TargetVal); - if (TestOrderSet01.Count > 0) + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal - currOrder.Value; + CurrSet.OrderSet = TestOrderSetMinDelta; + Candidates.Add(CurrSet); + } + + // solo successivi che non superano + Dictionary TestOrderSetMin = findStepMin(OrdInf, TargetVal); + // verifico se migliorativo... + if (TestOrderSetMin.Count > 0) + { + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal - currOrder.Value; + CurrSet.OrderSet = TestOrderSetMin; + Candidates.Add(CurrSet); + } + + // se posso fare ricorsioni + if (maxDepth > 0) + { + maxDepth--; + + // se rimane qualcosa... + if (OrdInf != null && OrdInf.Any()) { - OrderSetSim CurrSet = new OrderSetSim(); - CurrSet.TargetValue = TargetVal; - CurrSet.OrderSet = TestOrderSet01; - Candidates.Add(CurrSet); - } - // ...e con il primo valore... - Dictionary TestOrderSet02 = findLocalMin(OrdInf, TargetVal - currOrder.Value); - TestOrderSet02.Add(currOrder.Key, currOrder.Value); - // verifico se migliorativo... - if (TestOrderSet02.Count > 0) - { - OrderSetSim CurrSet = new OrderSetSim(); - CurrSet.TargetValue = TargetVal - currOrder.Value; - CurrSet.OrderSet = TestOrderSet02; - Candidates.Add(CurrSet); + // calcolo il minimo locale nei 2 casi, da soli + Dictionary TestOrderSet01 = findLocalMin(OrdInf, TargetVal, maxDepth); + if (TestOrderSet01.Count > 0) + { + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal; + CurrSet.OrderSet = TestOrderSet01; + Candidates.Add(CurrSet); + } + // ...e con il primo valore... + Dictionary TestOrderSet02 = findLocalMin(OrdInf, TargetVal - currOrder.Value, maxDepth); + TestOrderSet02.Add(currOrder.Key, currOrder.Value); + // verifico se migliorativo... + if (TestOrderSet02.Count > 0) + { + OrderSetSim CurrSet = new OrderSetSim(); + CurrSet.TargetValue = TargetVal - currOrder.Value; + CurrSet.OrderSet = TestOrderSet02; + Candidates.Add(CurrSet); + } } } } @@ -401,11 +430,32 @@ namespace NKC_WF.WebUserControls { answ = Candidates.OrderBy(x => x.IndexScore).FirstOrDefault().OrderSet; } - // calcolo il minimo e lo restituisco... return answ; } + /// + /// Cerca il set della lista ordinata <= target val + /// + /// Lista ordinata oggetti (INT) + valore + /// Valore desiderato (come SOMMA) + /// + protected Dictionary findStepMin(Dictionary OrderedList, double TargetVal) + { + double CurrVal = 0; + Dictionary answ = new Dictionary(); + foreach (var item in OrderedList) + { + CurrVal += item.Value; + if (CurrVal <= TargetVal) + { + answ.Add(item.Key, item.Value); + } + } + // restituisco set minore... + return answ; + } + protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) diff --git a/NKC_WF/WebUserControls/cmp_batchList.ascx.cs b/NKC_WF/WebUserControls/cmp_batchList.ascx.cs index 1a2db31..e719de2 100644 --- a/NKC_WF/WebUserControls/cmp_batchList.ascx.cs +++ b/NKC_WF/WebUserControls/cmp_batchList.ascx.cs @@ -26,6 +26,17 @@ namespace NKC_WF.WebUserControls } } + /// + /// Status corrente del batch + /// + protected BatchStatus CurrBatchStatus + { + get + { + return ComLib.BStatus(BatchIdSel); + } + } + protected int currSelRow { get @@ -166,13 +177,16 @@ namespace NKC_WF.WebUserControls private void fixDetails() { - divDetail.Visible = currSelRow >= 0; lastSelRow = currSelRow; - // recupero BatchId selezionato - cmp_batchDetail.BatchId = 0; - cmp_batchDetail.BatchId = BatchIdSel; - cmp_batchDetail.doUpdate(); - updPanelDetail.Update(); + divDetail.Visible = currSelRow >= 0; + if (divDetail.Visible) + { + // recupero BatchId selezionato + cmp_batchDetail.BatchId = 0; + cmp_batchDetail.BatchId = BatchIdSel; + cmp_batchDetail.doUpdate(); + updPanelDetail.Update(); + } } private void resetSelezione() @@ -365,7 +379,12 @@ namespace NKC_WF.WebUserControls checkFixOds(); grView.DataBind(); currSelRow = lastSelRow; - fixDetails(); + var currBStatus = CurrBatchStatus; + // solo se il batch è in fase di stima/nesting... + if (currBStatus == BatchStatus.NestRequested || currBStatus == BatchStatus.EstimationRequested) + { + fixDetails(); + } } /// diff --git a/NKC_WF/WebUserControls/cmp_orderExtList.ascx b/NKC_WF/WebUserControls/cmp_orderExtList.ascx index 8000f6f..dfc288a 100644 --- a/NKC_WF/WebUserControls/cmp_orderExtList.ascx +++ b/NKC_WF/WebUserControls/cmp_orderExtList.ascx @@ -12,7 +12,7 @@ - +