Exemple #1
0
        public override void Start(CancellationToken token, Action <double> action)
        {
            OptimizerInfo.OnNext("Starting SA Optimizer with cooling rate: " + _config.CoolingRate.ToString());

            Random rand          = new Random();
            double minPathLength = double.MaxValue;
            double curPathLength = double.MaxValue;

            int[] currentSequence = _startPermutation.ToArray();

            double temperature = double.MaxValue;

            while (!token.IsCancellationRequested)
            {
                // Forcing delay for visualization
                if (_config.UseDelay)
                {
                    Thread.Sleep(_config.DelayTime);
                }

                int cp1, cp2;

                do
                {
                    cp1 = rand.Next(0, currentSequence.Length - 1);
                    cp2 = rand.Next(1, currentSequence.Length);
                } while (cp1 == cp2 || cp1 > cp2);

                var nextSequence = Helper.TwoOptSwap(currentSequence, cp1, cp2);

                double nextPathLength = _euclideanPath.GetPathLength(nextSequence, ClosedPath);
                double difference     = nextPathLength - curPathLength;
                curPathLength = nextPathLength;

                if (curPathLength < minPathLength)
                {
                    currentSequence = nextSequence.ToArray();
                    minPathLength   = curPathLength;
                    action?.Invoke(minPathLength);
                    _optimalSequence.OnNext(currentSequence.ToArray());
                }
                else if (difference > 0 && GetProbability(difference, temperature) > rand.NextDouble())
                {
                    currentSequence = nextSequence.ToArray();
                    minPathLength   = curPathLength;
                }

                temperature = temperature * _coolingRate;
            }

            _optimalSequence.OnCompleted();
            OptimizerInfo.OnNext("Terminated SA Optimizer with distance: " + minPathLength.ToString() + " LU");
        }
        public override void Start(CancellationToken token, Action <double> action)
        {
            OptimizerInfo.OnNext("Starting 2-opt Optimizer");

            double minPathLength = double.MaxValue;

            int[] currentSequence = _startPermutation.ToArray();

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

            while (!token.IsCancellationRequested)
            {
                try
                {
                    // When using this parallel loop the calculation will not be deterministic
                    // because of missing locking and therefore random order.
                    // Nevertheless the results will be good
                    Parallel.For(0, _startPermutation.Length - 1, parallelOptions, i =>
                    {
                        for (int k = i + 1; k < _startPermutation.Length; k++)
                        {
                            // Forcing delay for visualization
                            if (_config.UseDelay)
                            {
                                Thread.Sleep(_config.DelayTime);
                            }

                            var nextSequence = Helper.TwoOptSwap(currentSequence, i, k);
                            double curMin    = _euclideanPath.GetPathLength(nextSequence, ClosedPath);

                            if (curMin < minPathLength)
                            {
                                currentSequence = nextSequence.ToArray();
                                minPathLength   = curMin;
                                action?.Invoke(minPathLength);
                                _downSampledOptSequence.OnNext(currentSequence);
                            }
                        }
                    });
                }
                catch (OperationCanceledException)
                {
                    _optimalSequence.OnCompleted();
                    _disposeStream?.Dispose();
                    OptimizerInfo.OnNext("Terminated 2-opt Optimizer with distance: " + minPathLength.ToString() + " LU");
                }
            }
        }
        private void DoLocalOptimizationGidCell()
        {
            Parallel.ForEach(GridCells, cell =>
            {
                int length = cell.GetCompleteIndices().Length;
                OptimizerInfo.OnNext("Local cell element count: " + length.ToString());
                //var euclideanPath = new FastEuclideanPath(_globalGridPoints);
                ITspOptimizer optimizer = new BranchAndBoundOptimizer(cell.GetCompleteIndices(), _euclideanPath, _config);
                {
                    ClosedPath = false;
                };

                int[] optSequence = null;
                optimizer.OptimalSequence.Subscribe(seq => optSequence = seq);
                var cast        = optimizer as BranchAndBoundOptimizer;
                cast.ClosedPath = false;
                cast.Start(_token, _action, 1, length - 2);
                cell.InnerMinSequence = optSequence.Skip(1).Take(length - 2).ToArray();
            });
        }
Exemple #4
0
        public override void Start(CancellationToken token, Action <double> action)
        {
            _token = token;

            if (_config.UseBigValleySearch)
            {
                OptimizerInfo.OnNext("Starting Genetic Optimizer with Big-Valley-Search");
            }
            else
            {
                OptimizerInfo.OnNext("Starting Genetic Optimizer without Big-Valley-Search");
            }

            _action = action;
            double[] distances = new double[_population];
            MinTour = Enumerable.Range(0, _number).ToArray();
            int[,] chromosomePool = new int[_population, _number];

            SetPopulationPool(chromosomePool, distances);

            if (!token.IsCancellationRequested)
            {
                OptimizerInfo.OnNext("Starting genetic optimization");
            }

            while (!token.IsCancellationRequested)
            {
                // Forcing delay for visualization
                if (_config.UseDelay)
                {
                    Thread.Sleep(_config.DelayTime);
                }

                if (_random.NextDouble() < _rate)
                {
                    int   i, j, parent1, parent2;
                    int[] p1 = new int[_number];
                    int[] p2 = new int[_number];

                    i = _random.Next(_population);
                    j = _random.Next(_population);

                    if (distances[i] < distances[j])
                    {
                        parent1 = i;
                    }

                    else
                    {
                        parent1 = j;
                    }

                    i = _random.Next(_population);
                    j = _random.Next(_population);

                    if (distances[i] < distances[j])
                    {
                        parent2 = i;
                    }

                    else
                    {
                        parent2 = j;
                    }

                    for (i = 0; i < _number; i++)
                    {
                        p1[i] = chromosomePool[parent1, i];
                        p2[i] = chromosomePool[parent2, i];
                    }

                    int cp1 = -1, cp2 = -1;

                    do
                    {
                        cp1 = _random.Next(_number);
                        cp2 = _random.Next(_number);
                    } while (cp1 == cp2 || cp1 > cp2);

                    ChromosomeSegment segment = new ChromosomeSegment(cp1, cp2);
                    var offSpringPair         = _partiallyMappedCrossover.GetCrossCombinedOffSpringPair(segment, new ParentPair <int>(p1, p2));

                    int[] o1 = offSpringPair.ChildA;
                    int[] o2 = offSpringPair.ChildB;

                    double o1Fitness = TourDistance(o1);
                    double o2Fitness = TourDistance(o2);

                    if (o1Fitness < distances[parent1])
                    {
                        for (i = 0; i < _number; i++)
                        {
                            chromosomePool[parent1, i] = o1[i];
                        }
                    }

                    if (o2Fitness < distances[parent2])
                    {
                        for (i = 0; i < _number; i++)
                        {
                            chromosomePool[parent2, i] = o2[i];
                        }
                    }

                    for (int p = 0; p < _population; p++)
                    {
                        if (distances[p] < MinDistance)
                        {
                            MinDistance = distances[p];

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

                    int i = _random.Next(_population);
                    int j = _random.Next(_population);

                    if (distances[i] < distances[j])
                    {
                        p = i;
                    }

                    else
                    {
                        p = j;
                    }

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


                    child = DoMutation(child);

                    double childDistance = TourDistance(child);

                    int    maxIndex    = int.MaxValue;
                    double maxDistance = double.MinValue;

                    for (int q = 0; q < _population; q++)
                    {
                        if (distances[q] >= maxDistance)
                        {
                            maxIndex    = q;
                            maxDistance = distances[q];
                        }
                    }

                    int[] index = new int[_population];
                    int   count = 0;

                    for (int q = 0; q < _population; q++)
                    {
                        if (distances[q] == maxDistance)
                        {
                            index[count++] = q;
                        }
                    }

                    maxIndex = index[_random.Next(count)];

                    if (childDistance < distances[maxIndex])
                    {
                        distances[maxIndex] = childDistance;

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

                        if (childDistance < MinDistance)
                        {
                            MinDistance = childDistance;

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

            _optimalSequence.OnCompleted();
            OptimizerInfo.OnNext("Genetic optimization terminated with distance: " + MinDistance.ToString() + " LU");
        }
Exemple #5
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");
            }
        }