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(); }); }
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"); }
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"); } }