public static ItemArray<IItem> Apply(IItem initiator, IItem guide, IntValue k, PercentValue n) { if (!(initiator is RealVector) || !(guide is RealVector)) throw new ArgumentException("Cannot relink path because one of the provided solutions or both have the wrong type."); if (n.Value <= 0.0) throw new ArgumentException("RelinkingAccuracy must be greater than 0."); RealVector v1 = initiator.Clone() as RealVector; RealVector v2 = guide as RealVector; if (v1.Length != v2.Length) throw new ArgumentException("The solutions are of different length."); IList<RealVector> solutions = new List<RealVector>(); for (int i = 0; i < k.Value; i++) { RealVector solution = v1.Clone() as RealVector; for (int j = 0; j < solution.Length; j++) solution[j] = v1[j] + 1 / (k.Value - i) * (v2[j] - v1[j]); solutions.Add(solution); } IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return new ItemArray<IItem>(selection); }
public static ItemArray<IItem> Apply(IItem initiator, IItem[] guides, DistanceMatrix distances, PercentValue n) { if (!(initiator is Permutation) || guides.Any(x => !(x is Permutation))) throw new ArgumentException("Cannot relink path because some of the provided solutions have the wrong type."); if (n.Value <= 0.0) throw new ArgumentException("RelinkingAccuracy must be greater than 0."); Permutation v1 = initiator.Clone() as Permutation; Permutation[] targets = new Permutation[guides.Length]; Array.Copy(guides, targets, guides.Length); if (targets.Any(x => x.Length != v1.Length)) throw new ArgumentException("At least one solution is of different length."); IList<Permutation> solutions = new List<Permutation>(); for (int i = 0; i < v1.Length; i++) { int currCityIndex = i; int bestCityIndex = (i + 1) % v1.Length; double currDistance = distances[v1[currCityIndex], v1[bestCityIndex]]; // check each guiding solution targets.ToList().ForEach(solution => { // locate current city var node = solution.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == v1[currCityIndex]); int pred = solution[(node.Index - 1 + solution.Length) % solution.Length]; int succ = solution[(node.Index + 1) % solution.Length]; // get distances to neighbors var results = new[] { pred, succ }.Select(x => new { Id = x, Distance = distances[x, node.Id] }); var bestCity = results.Where(x => x.Distance < currDistance).OrderBy(x => x.Distance).FirstOrDefault(); if (bestCity != null) { bestCityIndex = v1.Select((x, index) => new { Id = x, Index = index }).Single(x => x.Id == bestCity.Id).Index; currDistance = bestCity.Distance; } }); Invert(v1, currCityIndex + 1, bestCityIndex); solutions.Add(v1.Clone() as Permutation); } IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return new ItemArray<IItem>(selection); }
public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) { if (!(initiator is Permutation) || !(guide is Permutation)) throw new ArgumentException("Cannot relink path because one of the provided solutions or both have the wrong type."); if (n.Value <= 0.0) throw new ArgumentException("RelinkingAccuracy must be greater than 0."); Permutation firstInitiator = initiator.Clone() as Permutation; Permutation firstGuide = guide.Clone() as Permutation; Permutation secondInitiator = firstGuide.Clone() as Permutation; Permutation secondGuide = firstInitiator.Clone() as Permutation; if (firstInitiator.Length != firstGuide.Length) throw new ArgumentException("The solutions are of different length."); IList<Permutation> solutions = new List<Permutation>(); for (int i = 0; i < firstInitiator.Length / 2; i++) { if (firstInitiator[i] != firstGuide[i]) { var target = firstInitiator.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == firstGuide[i]); // XOR swap firstInitiator[i] ^= firstInitiator[target.ValueIndex]; firstInitiator[target.ValueIndex] ^= firstInitiator[i]; firstInitiator[i] ^= firstInitiator[target.ValueIndex]; solutions.Add(firstInitiator.Clone() as Permutation); } int j = secondInitiator.Length - 1 - i; if (secondInitiator[j] != secondGuide[j]) { var target = secondInitiator.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == secondGuide[j]); // XOR swap secondInitiator[j] ^= secondInitiator[target.ValueIndex]; secondInitiator[target.ValueIndex] ^= secondInitiator[j]; secondInitiator[j] ^= secondInitiator[target.ValueIndex]; solutions.Add(secondInitiator.Clone() as Permutation); } } IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return new ItemArray<IItem>(selection); }
public override IOperation Apply() { ItemArray<BoolValue> tabu = IsTabuParameter.ActualValue; if (tabu.Length > 0) { PercentValue value = PercentTabuParameter.ActualValue; if (value == null) { value = new PercentValue(); PercentTabuParameter.ActualValue = value; } value.Value = tabu.Where(x => x.Value).Count() / (double)tabu.Length; ResultCollection results = ResultsParameter.ActualValue; if (results != null) { IResult result = null; results.TryGetValue(PercentTabuParameter.ActualName, out result); if (result != null) result.Value = value; else results.Add(new Result(PercentTabuParameter.ActualName, "Indicates how much of the neighborhood is tabu.", (IItem)value.Clone())); } } return base.Apply(); }
public static ItemArray<IItem> Apply(IItem initiator, IItem guide, PercentValue n) { if (!(initiator is BinaryVector) || !(guide is BinaryVector)) throw new ArgumentException("Cannot relink path because one of the provided solutions or both have the wrong type."); if (n.Value <= 0.0) throw new ArgumentException("RelinkingAccuracy must be greater than 0."); BinaryVector firstInitiator = initiator.Clone() as BinaryVector; BinaryVector firstGuide = guide.Clone() as BinaryVector; BinaryVector secondInitiator = firstGuide.Clone() as BinaryVector; BinaryVector secondGuide = firstInitiator.Clone() as BinaryVector; if (firstInitiator.Length != firstGuide.Length) throw new ArgumentException("The solutions are of different length."); IList<BinaryVector> solutions = new List<BinaryVector>(); for (int i = 0; i < firstInitiator.Length / 2; i++) { if (firstInitiator[i] != firstGuide[i]) { firstInitiator[i] = firstGuide[i]; solutions.Add(firstInitiator.Clone() as BinaryVector); } int j = secondInitiator.Length - 1 - i; if (secondInitiator[j] != secondGuide[j]) { secondInitiator[j] = secondGuide[j]; solutions.Add(secondInitiator.Clone() as BinaryVector); } } IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return new ItemArray<IItem>(selection); }
protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) { if (parents.Length != 2) throw new ArgumentException("The number of parents is not equal to 2."); return Apply(parents[0], parents[1], RelinkingIntensity, n); }
protected PercentValue(PercentValue original, Cloner cloner) : base(original, cloner) { restrictToUnitInterval = original.restrictToUnitInterval; }
private void AfterDeserialization() { #region conversion of old NSM parameters if (Parameters.ContainsKey(SelectorParameterName)) { // change SelectorParameter type from ISelector to ISingleObjectiveSelector ValueParameter<ISelector> param = Parameters[SelectorParameterName] as ValueParameter<ISelector>; if (param != null) { ISingleObjectiveSelector selector = param.Value as ISingleObjectiveSelector; if (selector == null) selector = new TournamentSelector(); Parameters.Remove(SelectorParameterName); Parameters.Add(new ValueParameter<ISingleObjectiveSelector>(SelectorParameterName, "The inner selection operator to select the parents.", selector)); } } // FixedValueParameter for quality difference percentage, max attempts, use range if (Parameters.ContainsKey(QualityDifferencePercentageParameterName)) { ValueParameter<PercentValue> param = Parameters[QualityDifferencePercentageParameterName] as ValueParameter<PercentValue>; if (!(param is FixedValueParameter<PercentValue>)) { PercentValue diff = param != null ? param.Value as PercentValue : null; if (diff == null) diff = new PercentValue(0.05); Parameters.Remove(QualityDifferencePercentageParameterName); Parameters.Add(new FixedValueParameter<PercentValue>(QualityDifferencePercentageParameterName, "The minimum quality difference from parent1 to parent2 to accept the selection.", diff)); } } if (Parameters.ContainsKey(QualityDifferenceMaxAttemptsParameterName)) { ValueParameter<IntValue> param = Parameters[QualityDifferenceMaxAttemptsParameterName] as ValueParameter<IntValue>; if (!(param is FixedValueParameter<IntValue>)) { IntValue attempts = param != null ? param.Value as IntValue : null; if (attempts == null) attempts = new IntValue(5); Parameters.Remove(QualityDifferenceMaxAttemptsParameterName); Parameters.Add(new FixedValueParameter<IntValue>(QualityDifferenceMaxAttemptsParameterName, "The maximum number of attempts to find parents which differ in quality.", attempts)); } } if (Parameters.ContainsKey(QualityDifferenceUseRangeParameterName)) { ValueParameter<BoolValue> param = Parameters[QualityDifferenceUseRangeParameterName] as ValueParameter<BoolValue>; if (!(param is FixedValueParameter<BoolValue>)) { BoolValue range = param != null ? param.Value as BoolValue : null; if (range == null) range = new BoolValue(true); Parameters.Remove(QualityDifferenceUseRangeParameterName); Parameters.Add(new FixedValueParameter<BoolValue>(QualityDifferenceUseRangeParameterName, "Use the range from minimum to maximum quality as basis for QualityDifferencePercentage.", range)); } } if (!Parameters.ContainsKey(QualityDifferenceUseRangeParameterName)) // add use range parameter Parameters.Add(new FixedValueParameter<BoolValue>(QualityDifferenceUseRangeParameterName, "Use the range from minimum to maximum quality as basis for QualityDifferencePercentage.", new BoolValue(true))); #endregion RegisterParameterEventHandlers(); }
public static ItemArray<IItem> Apply(PotvinEncoding initiator, PotvinEncoding guide, PercentValue n, int sampleSize, int iterations, IRandom rand, IVRPProblemInstance problemInstance) { if (initiator == null || guide == null) throw new ArgumentException("Cannot relink path because one of the provided solutions or both are null."); double sigma = 1.5; double minPenalty = 0.001; double maxPenalty = 1000000000; var originalOverloadPenalty = new DoubleValue(); if (problemInstance is IHomogenousCapacitatedProblemInstance) originalOverloadPenalty.Value = (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value; var originalTardinessPenalty = new DoubleValue(); if (problemInstance is ITimeWindowedProblemInstance) originalTardinessPenalty.Value = (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value; PotvinEncoding current = MatchTours(initiator, guide, problemInstance); double currentSimilarity = VRPSimilarityCalculator.CalculateSimilarity(current, guide); IList<PotvinEncoding> solutions = new List<PotvinEncoding>(); int i = 0; while (i < iterations && !currentSimilarity.IsAlmost(1.0)) { var currentEval = problemInstance.Evaluate(current); currentSimilarity = VRPSimilarityCalculator.CalculateSimilarity(current, guide); if (currentSimilarity < 1.0) { for (int sample = 0; sample < sampleSize; sample++) { var next = current.Clone() as PotvinEncoding; int neighborhood = rand.Next(3); switch (neighborhood) { case 0: next = RouteBasedXOver(next, guide, rand, problemInstance); break; case 1: next = SequenceBasedXOver(next, guide, rand, problemInstance); break; case 2: GuidedRelocateMove(next, guide, rand); break; } next = MatchTours(next, guide, problemInstance); var nextEval = problemInstance.Evaluate(next); if ((nextEval.Quality < currentEval.Quality)) { current = next; solutions.Add(current); break; } } if (problemInstance is IHomogenousCapacitatedProblemInstance) { if (((CVRPEvaluation)currentEval).Overload > 0) { (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = Math.Min(maxPenalty, (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value * sigma); } else { (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = Math.Max(minPenalty, (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value * sigma); } } if (problemInstance is ITimeWindowedProblemInstance) { if (((CVRPTWEvaluation)currentEval).Tardiness > 0) { (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = Math.Min(maxPenalty, (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value * sigma); } else { (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = Math.Max(minPenalty, (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value / sigma); } } i++; } } if (problemInstance is IHomogenousCapacitatedProblemInstance) (problemInstance as IHomogenousCapacitatedProblemInstance).OverloadPenalty.Value = originalOverloadPenalty.Value; if (problemInstance is ITimeWindowedProblemInstance) (problemInstance as ITimeWindowedProblemInstance).TardinessPenalty.Value = originalTardinessPenalty.Value; return new ItemArray<IItem>(ChooseSelection(solutions, n)); }
protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) { if (parents.Length != 2) throw new ArgumentException("The number of parents is not equal to 2."); if (!(parents[0] is PotvinEncoding)) parents[0] = PotvinEncoding.ConvertFrom(parents[0] as IVRPEncoding, ProblemInstanceParameter.ActualValue); if (!(parents[1] is PotvinEncoding)) parents[1] = PotvinEncoding.ConvertFrom(parents[1] as IVRPEncoding, ProblemInstanceParameter.ActualValue); return Apply(parents[0] as PotvinEncoding, parents[1] as PotvinEncoding, n, SampleSizeParameter.Value.Value, IterationsParameter.Value.Value, RandomParameter.ActualValue, ProblemInstanceParameter.ActualValue); }
private static IList<IItem> ChooseSelection(IList<PotvinEncoding> solutions, PercentValue n) { IList<IItem> selection = new List<IItem>(); if (solutions.Count > 0) { int noSol = (int)(solutions.Count * n.Value); if (noSol <= 0) noSol++; double stepSize = (double)solutions.Count / (double)noSol; for (int i = 0; i < noSol; i++) selection.Add(solutions.ElementAt((int)((i + 1) * stepSize - stepSize * 0.5))); } return selection; }
protected override ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n) { if (parents.Length < 2) throw new ArgumentException("The number of parents is smaller than 2."); return Apply(parents[0], parents.Skip(1).ToArray(), DistanceMatrix, n); }
protected abstract ItemArray<IItem> Relink(ItemArray<IItem> parents, PercentValue n);