/// <summary> /// This Process is the main idea of this algorithm. /// </summary> private void SmartMoveDownProcess() { // For every split for (int i = 0; i < Splits.Count; i++) { if (i > 0) { ResetSplitWithAllClassesFilled(Splits, Splits[i]); } // mode down process. the most important thing on this algorithm MoveDownCarsSplits(Splits, Splits[i], i); if (Splits[i].Number == INTERRUPT_BEFORE_MOVEDOWN_SPLITNUMBER) { return; } } SplitsRepartitionOptimizer optimizer = new SplitsRepartitionOptimizer(Splits, fieldSize, carClassesIds, carclasses, baseAlgorithm as ClassicAffineDistribution); Splits = optimizer.OptimizeAndSolveDifferences(); // a third pass carclasses = Tools.SplitCarsPerClass(data); }
public void Compute(List <Line> data, int fieldSize) { if (ParameterDebugFileValue == 1) { PredictionsEvaluator.CleanOldDebugFiles(); } minCarsToHalfSplits = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(ParameterMinCarsValue) / 2d)); // Calc number of splits required // And try to reduce fieldSize, if possible, for the same number of splits numberOfSplits = Tools.DivideAndCeil(data.Count, fieldSize); int betterFieldSize = Tools.DivideAndCeil(data.Count, numberOfSplits); this.fieldSize = Math.Min(fieldSize, betterFieldSize); // create classes queues classesQueues = Tools.SplitCarsPerClass(data); classesIds = (from r in classesQueues select r.CarClassId).ToList(); // instanciate an ClassicAffineDistributio algorithm to use its car distribution system affineDistributor = new ClassicAffineDistribution(); affineDistributor.ParameterMinCarsValue = this.ParameterMinCarsValue; affineDistributor.SetFieldSize(fieldSize); affineDistributor.InitData(classesIds, data); if (classesQueues.Count == 1) { // if only one class, the affinedistributor will do the job affineDistributor.Compute(data, fieldSize); Splits = affineDistributor.Splits; return; } // Starting the process Splits = new List <Split>(); // this variable will contain the SoF Max of the 'Most Populated Class' of the last split // it will be given to the next one to help evaluating possible situations int prevMaxPopSof = -1; // for each split required for (int i = 0; i < numberOfSplits; i++) { // call the prediction algorithm, and get the best situation var prediction = ComputeFieldPredictionsAndKeepTheBest(i, prevMaxPopSof); // if something is possible if (prediction != null) { // Create the split, for true. Implement(prediction); // remember the Max SoF of the 'Most Populated Class' prevMaxPopSof = prediction.CurrentSplit.GetMaxClassSof(); } } // create the last split ... var lastsplit = Splits.Last(); // by checking any class queues for (int i = 0; i < classesQueues.Count; i++) { // if any cars are still in the queue var cars = classesQueues[i].PickCars(classesQueues[i].CarsCount); if (cars.Count > 0) { // put them in this last split if (lastsplit.GetClassId(i) == 0) { lastsplit.SetClass(i, classesIds[i]); } lastsplit.AppendClassCars(i, cars); } } // call the optimizer process (second pass algorithm) for // rounding cars number between splits, or fix some issue // if some splits exceed the fieldsize classesQueues = Tools.SplitCarsPerClass(data); SplitsRepartitionOptimizer optimizer = new SplitsRepartitionOptimizer(Splits, fieldSize, classesIds, classesQueues, affineDistributor); Splits = optimizer.OptimizeAndSolveDifferences(); // now we have the final result }