예제 #1
0
        /// <summary>
        ///  Factory to create specified optimizer
        /// </summary>
        /// <param name="tspOptimizerAlgorithm"></param>
        /// <param name="startSequence"></param>
        /// <param name="euclideanPath"></param>
        /// <returns></returns>
        public static ITspOptimizer Create(TspOptimizerAlgorithm tspOptimizerAlgorithm,
                                           int[] startSequence, IEuclideanPath euclideanPath,
                                           OptimizerConfig config)
        {
            ITspOptimizer tspOptimizer = null;

            switch (tspOptimizerAlgorithm)
            {
            case TspOptimizerAlgorithm.RandomOptimizer:
                tspOptimizer = new RandomOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.LocalCombinationOptimizer:
                tspOptimizer = new LocalCombinationOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.MultiLocalCombinationOptimizer:
                tspOptimizer = new MultiLocalCombinationOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.LocalTwoOptOptimizer:
                tspOptimizer = new LocalTwoOptOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.BruteForceOptimizer:
                tspOptimizer = new BruteForceOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.BranchAndBoundOptimizer:
                tspOptimizer = new BranchAndBoundOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.SimulatedAnnealingOptimizer:
                tspOptimizer = new SimulatedAnnealingOptimizer(startSequence, euclideanPath, config);
                break;

            case TspOptimizerAlgorithm.GeneticOptimizer:
                tspOptimizer = new GeneticOptimizer(startSequence, euclideanPath, config);
                break;

            default:
                throw new ArgumentException("Unknown optimizer");
            }

            return(tspOptimizer);
        }
        public override void Start(CancellationToken token, Action <double> action)
        {
            _token  = token;
            _action = action;

            // Do pre optimization -> early cuts in branches
            var preOptimizer = new LocalTwoOptOptimizer(_startPermutation, _euclideanPath, _config);

            preOptimizer.Start(1, false, 1);

            var preOptimalSequence = preOptimizer.OptimalSequence;

            _optimalSequence.OnNext(preOptimalSequence.ToArray());
            _minPathLength = _euclideanPath.GetPathLength(preOptimalSequence, ClosedPath);
            action?.Invoke(_minPathLength);
            Permute(_startPermutation, 0, _startPermutation.Length - 1);

            _optimalSequence.OnCompleted();
        }
예제 #3
0
        private void SetPopulationPool(int[,] chromosomePool, double[] distances)
        {
            if (_config.UseBigValleySearch)
            {
                Tuple <double, int[]>[] randomSequences = new Tuple <double, int[]> [_population];

                ParallelOptions parallelOptions = new ParallelOptions
                {
                    CancellationToken      = _token,
                    MaxDegreeOfParallelism = _config.NumberOfCores
                };

                int count = 0;

                try
                {
                    Parallel.For(0, _population, parallelOptions, i =>
                    {
                        int[] sequence = Enumerable.Range(0, _number).ToArray();
                        Helper.Shuffle(sequence);

                        var twoOptOptimizer = new LocalTwoOptOptimizer(sequence, _euclideanPath, _config);
                        twoOptOptimizer.Start(1, true, _config.BigValleySearchRate);

                        var distance       = _euclideanPath.GetPathLength(twoOptOptimizer.OptimalSequence, ClosedPath);
                        randomSequences[i] = new Tuple <double, int[]>(distance, twoOptOptimizer.OptimalSequence);

                        if (count++ % 10 == 0)
                        {
                            OptimizerInfo.OnNext("Progress Big-Valley-Search: " +
                                                 Math.Round(count / (double)_population * 100d, 2).ToString() + "%");
                        }
                    });

                    var orderedSequences = randomSequences.OrderBy(tuple => tuple.Item1).ToArray();

                    for (int p = 0; p < _population; p++)
                    {
                        distances[p] = orderedSequences[p].Item1;
                        int[] sequence = orderedSequences[p].Item2;

                        for (int n = 0; n < _number; n++)
                        {
                            chromosomePool[p, n] = sequence[n];
                        }
                    }

                    MinTour     = orderedSequences.First().Item2.ToArray();
                    MinDistance = orderedSequences.First().Item1;
                }
                catch (OperationCanceledException)
                {
                    OptimizerInfo.OnNext("Big-Valley-Search canceled");
                }

                if (!_token.IsCancellationRequested)
                {
                    OptimizerInfo.OnNext("Big-Valley-Search completed");
                }
            }
            else
            {
                for (int p = 0; p < _population; p++)
                {
                    int[] city = Enumerable.Range(0, _number).ToArray();
                    Helper.Shuffle(city);

                    for (int n = 0; n < _number; n++)
                    {
                        chromosomePool[p, n] = city[n];
                    }

                    distances[p] = TourDistance(city);

                    if (distances[p] < MinDistance)
                    {
                        MinDistance = distances[p];

                        for (int n = 0; n < _number; n++)
                        {
                            MinTour[n] = chromosomePool[p, n];
                        }
                    }
                }
            }

            if (!_token.IsCancellationRequested)
            {
                OptimizerInfo.OnNext("Population initialized");
            }
        }