コード例 #1
0
        /// <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);
        }
コード例 #2
0
        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
        }