public IEnumerable <IRLVItemDisplay> GetMetricSum(Item[] items) { var retVal = new List <IRLVItemDisplay>(); double[] metrics = new double[10]; foreach (var item in items) { var itemMetrics = PlanogramOptimizer.GetCalculatedWeightedMetricArray(item, Parent.SimulationSettings); for (int i = 0; i < itemMetrics.Length; i++) { metrics[i] += itemMetrics[i]; } } for (int i = 0; i < metrics.Length; i++) { retVal.Add(new RLVItemDisplay() { Name = $"Metric {i + 1}", Value = metrics[i] }); } return(retVal); }
/// <summary> /// Does training or prediction for a set number of sessions /// </summary> /// <param name="sessions">Number of session to train/predict for</param> /// <param name="learn">Lets the RLM know if we are training or predicting</param> /// <returns>The final output for the training or prediction</returns> private PlanogramOptResults Optimize(int sessions, bool learn = true, bool enablePlanogramDisplay = false, CancellationToken?cancelToken = null) { var output = new PlanogramOptResultsSettings(); // holds the unique SKUs that are already in the planogram. Ensures there are no duplicate SKUs var hashedSku = new HashSet <int>(); var itemDict = new Dictionary <int, int>(); var shelves = new List <Shelf>(); double totalMetricScore = 0; for (int i = 0; i < sessions; i++) { // reset for next session shelves.Clear(); hashedSku.Clear(); itemDict.Clear(); ResetCurrentItemIndexes(); totalMetricScore = 0; totalSessions++; DateTime startSession = DateTime.Now; // starts the session. we need to save the session ID as we will pass it to the cycle.Run later on long sessionId = network.SessionStart(); int numSlotFlattened = 0; // iterates for how many number of shelves our planogram has for (int shelf = 1; shelf <= simSettings.NumShelves; shelf++) { // this shelf instance will hold the items the RLM will output var shelfInstance = new Shelf() { Number = shelf }; int itemIndex; int numFacings; // iterates for how many number of slots on each shelf // notice that the slot is incremented depending on how many number of facings was outputed by the RLM for (int slot = 1; slot <= simSettings.NumSlots; slot += numFacings) { itemIndex = -1; numFacings = -1; bool isValid = false; numSlotFlattened++; do { // create the inputs with their corresponding values var inputs = new List <RlmIOWithValue>(); //inputs.Add(new RlmIOWithValue(network.Inputs.First(a => a.Name == "Shelf"), shelf.ToString())); //inputs.Add(new RlmIOWithValue(network.Inputs.First(a => a.Name == "Slot"), slot.ToString())); inputs.Add(new RlmIOWithValue(network.Inputs.First(a => a.Name == "Slot"), numSlotFlattened.ToString())); var rlmItemOutput = network.Outputs.FirstOrDefault(); var rlmIdeas = new List <RlmIdea>() { new RlmOutputLimiter(rlmItemOutput.ID, currentItemIndexes.Count - 1, GetEquivalentIndex) }; // runs a cycle with the sessionId passed in var cycle = new RlmCycle(); var rlmOutput = cycle.RunCycle(network, sessionId, inputs, learn, ideas: rlmIdeas); // get the outputs // the RLM outputs the item index so we will get the actual reference to the Item later on and // the second output is the number of facings that will show up on the plangram itemIndex = Convert.ToInt32(rlmOutput.CycleOutput.Outputs.First(a => a.Name == "Item").Value); numFacings = 1;//Convert.ToInt32(rlmOutput.CycleOutput.Outputs.First(a => a.Name == "NumFacings").Value); // we calculate how many remaining slots are there left to check for validity // because there might not be enough slots for what the number of facings was outputed by the RLM int remainingSlots = simSettings.NumSlots - shelfInstance.Items.Count(); bool isWithinLimit = CheckDuplicateItem(itemDict, itemIndex, numFacings); // here we check if the item is not a duplicate and that we have enough slots to fit the number of facings //if (hashedSku.Add(itemIndex) && remainingSlots >= numFacings) if (isWithinLimit && remainingSlots >= numFacings) { isValid = true; Item itemReference = items[itemIndex]; // we get the item reference using the index outputed by the RLM // with the item reference we will also have the Attributes which we need to calculate for the metrics double itemMetricScore = PlanogramOptimizer.GetCalculatedWeightedMetrics(itemReference, simSettings); // we add the item's metric score to totalMetricScore(which is our Session score in this case) // notice that we multplied it with the numFacings since that is how many will also show up on the planogram totalMetricScore += (itemMetricScore * numFacings); // add the items to the shelf container depending on how many facings for (int n = 0; n < numFacings; n++) { shelfInstance.Add(itemReference, itemMetricScore); } // A non-duplicate is good. network.ScoreCycle(rlmOutput.CycleOutput.CycleID, 1); } else { // we give the cycle a zero (0) score as it was not able to satisfy our conditions (punish it) isValid = false; network.ScoreCycle(rlmOutput.CycleOutput.CycleID, -1); //System.Diagnostics.Debug.WriteLine("try again"); } } while (!isValid); // if invalid, we redo the whole thing until the RLM is able to output an item that is unique and fits the remaining slot in the planogram } shelves.Add(shelfInstance); } // ends the session with the summed metric score for all items in the planogram network.SessionEnd(totalMetricScore); // set statistics and the optimized planogram shelves (and items inside them) output.Shelves = shelves; metricScoreHistory.Add(totalMetricScore); metricAvgLastTen.Enqueue(totalMetricScore); if (metricAvgLastTen.Count > 10) { metricAvgLastTen.Dequeue(); } output.Score = totalMetricScore; output.AvgScore = metricScoreHistory.Average(); output.AvgLastTen = metricAvgLastTen.Average(); output.MinScore = metricScoreHistory.Min(); output.MaxScore = metricScoreHistory.Max(); output.TimeElapsed = DateTime.Now - simSettings.StartedOn; output.CurrentSession = totalSessions; output.MaxItems = MAX_ITEMS; output.StartRandomness = network.StartRandomness; output.EndRandomness = network.EndRandomness; output.SessionsPerBatch = DEFAULT_SESSIONS_PER_BATCH; output.InputType = inputType.ToString(); output.CurrentRandomnessValue = network.RandomnessCurrentValue; if (logger != null) { SimulationData logdata = new SimulationData(); logdata.Session = output.CurrentSession; logdata.Score = output.Score; logdata.Elapse = DateTime.Now - startSession; logger.Add(logdata); } // update the numScoreHits if the sim type is Score if (simSettings.SimType == SimulationType.Score) { if (totalMetricScore >= simSettings.Score.Value) { numScoreHits++; output.NumScoreHits = numScoreHits; } else { numScoreHits = 0; } } //OnSessionDone?.Invoke(output); // updates the results to the UI //bool enableSimDisplay = (!learn) ? true : (learn && simSettings.EnableSimDisplay) ? true : false; if (enablePlanogramDisplay) { output.MetricMin = simSettings.ItemMetricMin; output.MetricMax = simSettings.ItemMetricMax; output.CalculateItemColorIntensity(); } UpdateUI?.Invoke(output, enablePlanogramDisplay); // checks if we have already by passed the time or score that was set // if we did, then we stop the training and end it abruptly if ((simSettings.SimType == SimulationType.Time && simSettings.EndsOn.Value <= DateTime.Now) || (simSettings.SimType == SimulationType.Score && numScoreHits >= RPOCSimulationSettings.NUM_SCORE_HITS)) { break; } if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested) { return(output); } } return(output); }
public PlanogramOptResults ScorePilot() { PlanogramOptResults retVal = new PlanogramOptResults(); var shelves = new List <Shelf>(); double totalMetricScore = 0; int slotNumber = 0; Dictionary <int, int> itemDict = new Dictionary <int, int>(); bool hasExceedMax = false; for (int i = 0; i < simSettings.NumShelves; i++) { Shelf shelfInstance = new Shelf(); for (int p = 0; p < simSettings.NumSlots; p++) { var inputs = new BasicMLData(1); inputs[0] = slotNormalizer.Normalize(slotNumber); ////Actual Code //IMLData output = network.Compute(inputs); //int index = Convert.ToInt32(itemNormalizer.DeNormalize(output[0])); int index = 1; IMLData output = null; //Test Code do { output = network.Compute(inputs); index = Convert.ToInt32(itemNormalizer.DeNormalize(output[0])); } while (index < 0 || index > items.Length - 1); //// Gino Code for Genetic //if (index < 0 || index > items.Length - 1) //{ // index = 0; //} Item itemReference = items[index]; if (!hasExceedMax) { hasExceedMax = !(CheckDuplicateItem(itemDict, index)); } // with the item reference we will also have the Attributes which we need to calculate for the metrics double itemMetricScore = PlanogramOptimizer.GetCalculatedWeightedMetrics(itemReference, simSettings); // we add the item's metric score to totalMetricScore(which is our Session score in this case) // notice that we multplied it with the numFacings since that is how many will also show up on the planogram totalMetricScore += itemMetricScore; shelfInstance.Add(itemReference, itemMetricScore); slotNumber++; } shelves.Add(shelfInstance); } retVal.Shelves = shelves; retVal.Score = (hasExceedMax) ? 0 : totalMetricScore; retVal.TimeElapsed = DateTime.Now - simSettings.StartedOn; return(retVal); }