예제 #1
0
        public void TestMakeBins()
        {
            int[] population = new int[13];
            for (int i = 0; i < population.Length; i++)
            {
                population[i] = i + 1;
            }

            var result = MetaheuristicsHelper.MakeBins(population, 2);

            Assert.AreEqual(2, result.Length);
            Assert.AreEqual(new[] { 1, 2, 3, 4, 5, 6, 7 }, result[0]);
            Assert.AreEqual(new[] { 8, 9, 10, 11, 12, 13 }, result[1]);
        }
예제 #2
0
        public static IObjectiveScores[] EvaluateScores <T>(IClonableObjectiveEvaluator <T> evaluator, T[] population, Func <bool> isCancelled, ParallelOptions parallelOptions = null) where T : ISystemConfiguration
        {
            if (population.Length == 0)
            {
                return(new IObjectiveScores[0]);
            }
            if (parallelOptions == null)
            {
                parallelOptions = new ParallelOptions()
                {
                    MaxDegreeOfParallelism = -1
                }
            }
            ;

            var procCount = System.Environment.ProcessorCount;

            IObjectiveScores[] result;
            if (evaluator.SupportsThreadSafeCloning)
            {
                // There is presumably no point cloning
                // the system more times than the max level of parallelism
                int nParallel = procCount;
                if (parallelOptions.MaxDegreeOfParallelism > 0)
                {
                    nParallel = Math.Min(nParallel, parallelOptions.MaxDegreeOfParallelism);
                }
                T[][] subPop   = MetaheuristicsHelper.MakeBins(population, nParallel);
                var   taskPkgs = new List <Tuple <T[], IClonableObjectiveEvaluator <T> > >();
                taskPkgs.Add(Tuple.Create(subPop[0], evaluator));
                for (int i = 1; i < subPop.Length; i++)
                {
                    taskPkgs.Add(Tuple.Create(subPop[i], evaluator.Clone()));
                }
                // Need to use Parallel.ForEach rather than Parallel.For to work around a Parallel.For
                // oddity in Mono 3.12.1. Need an identity to iterate over...
                var ramp = new int[subPop.Length];
                // Map of index of subpopulations to indices in the variable result:
                //var offsets = new int[subPop.Length];
                var resultBins = new IObjectiveScores[ramp.Length][];
                for (int i = 1; i < ramp.Length; i++)
                {
                    ramp[i] = i;
                }
                Parallel.ForEach(ramp, parallelOptions,
                                 (i => {
                    resultBins[i] = EvaluateScoresSerial(taskPkgs[i], isCancelled);
                })
                                 );
                result = Gather(resultBins);
            }
            else
            {
                result = new IObjectiveScores[population.Length];
                for (int i = 0; i < population.Length; i++)
                {
                    if (!isCancelled())
                    {
                        result [i] = evaluator.EvaluateScore(population [i]);
                    }
                    else
                    {
                        result [i] = null;
                    }
                }
            }
            return(result);
        }