Fix algoritmo ricerca step minimo

This commit is contained in:
Samuele Locatelli
2021-06-16 15:19:46 +02:00
parent 0622e8a869
commit a575a20126
5 changed files with 143 additions and 44 deletions
+1
View File
@@ -344,6 +344,7 @@
<Content Include="Content\bootstrap-reboot.css.map" />
<Content Include="Content\bootstrap-grid.min.css.map" />
<Content Include="Content\bootstrap-grid.css.map" />
<Content Include="NLog.config" />
<None Include="Scripts\jquery-3.6.0.intellisense.js" />
<Content Include="Scripts\jquery-3.6.0.js" />
<Content Include="Scripts\jquery-3.6.0.min.js" />
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="false"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variabeles
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue" />
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<targets async="true">
<target xsi:type="File"
name="NKC"
fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} ${uppercase:${level}} ${message}" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="NKC" />
</rules>
</nlog>
@@ -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<int, double> RawList = new Dictionary<int, double>();
Dictionary<int, double> OrderedList = new Dictionary<int, double>();
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
/// </summary>
/// <param name="OrderedList">Lista ordinata oggetti (INT) + valore</param>
/// <param name="TargetVal">Valore desiderato (comeSOMMA)</param>
/// <param name="TargetVal">Valore desiderato (come SOMMA)</param>
/// <param name="maxDepth">Massima profondità ricorsione accettata (x evitare loop infinito)</param>
/// <returns></returns>
protected Dictionary<int, double> findLocalMin(Dictionary<int, double> OrderedList, double TargetVal)
protected Dictionary<int, double> findLocalMin(Dictionary<int, double> OrderedList, double TargetVal, int maxDepth)
{
Dictionary<int, double> answ = new Dictionary<int, double>();
List<OrderSetSim> Candidates = new List<OrderSetSim>();
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<int, double> 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<int, double> 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<int, double> 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<int, double> 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<int, double> 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<int, double> 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;
}
/// <summary>
/// Cerca il set della lista ordinata <= target val
/// </summary>
/// <param name="OrderedList">Lista ordinata oggetti (INT) + valore</param>
/// <param name="TargetVal">Valore desiderato (come SOMMA)</param>
/// <returns></returns>
protected Dictionary<int, double> findStepMin(Dictionary<int, double> OrderedList, double TargetVal)
{
double CurrVal = 0;
Dictionary<int, double> answ = new Dictionary<int, double>();
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)
+26 -7
View File
@@ -26,6 +26,17 @@ namespace NKC_WF.WebUserControls
}
}
/// <summary>
/// Status corrente del batch
/// </summary>
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();
}
}
/// <summary>
+1 -1
View File
@@ -12,7 +12,7 @@
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lbtSel" runat="server" CausesValidation="False" CommandName="Select" CssClass="btn btn-dark btn-sm" ToolTip='<%# traduci("ExchangeOrder") %>'><i class="fa fa-arrows-h" aria-hidden="true"></i></asp:LinkButton>
<asp:LinkButton ID="lbtSel" runat="server" CausesValidation="False" CommandName="Select" CssClass="btn btn-dark btn-sm py-0" ToolTip='<%# traduci("ExchangeOrder") %>'><i class="fa fa-arrows-h" aria-hidden="true"></i></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="OrderExtCode" HeaderText="Ord.Code" SortExpression="OrderExtCode" />