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()); }
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], n)); }
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)); }
private void TestRange(PercentValue minimumValue, PercentValue actualValue, PercentValue maximalValue) { Assert.IsTrue(minimumValue < actualValue, $"Expected {minimumValue}<{actualValue}"); Assert.IsTrue(actualValue < maximalValue, $"Expected {actualValue}<{maximalValue}"); Assert.IsTrue(minimumValue.Value < actualValue.Value, $"Expected {minimumValue.Value}<{actualValue.Value}"); Assert.IsTrue(actualValue.Value < maximalValue.Value, $"Expected {actualValue.Value}<{maximalValue.Value}"); }
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)); }
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 v1 = initiator.Clone() as Permutation; Permutation v2 = guide as Permutation; if (v1.Length != v2.Length) { throw new ArgumentException("The solutions are of different length."); } IList <Permutation> solutions = new List <Permutation>(); for (int i = 0; i < v1.Length; i++) { if (v1[i] != v2[i]) { var target = v1.Select((x, index) => new { Value = x, ValueIndex = index }).First(x => x.Value == v2[i]); if (v1[i] != v1[target.ValueIndex]) { // XOR swap v1[i] ^= v1[target.ValueIndex]; v1[target.ValueIndex] ^= v1[i]; v1[i] ^= v1[target.ValueIndex]; 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)); }
private void DrawText(Graphics g) { RectangleF centerRect = new RectangleF(knobCenter.X - (radius), knobCenter.Y - (radius / 4), 2 * (radius), 2 * (radius / 4)); StringFormat sf = new StringFormat(); sf.LineAlignment = StringAlignment.Center; sf.Alignment = StringAlignment.Center; // SHOW PERCENTAGE if (ShowPercentage) { g.DrawString(PercentValue.ToString("##0.##") + "%", Font, new SolidBrush(ForeColor), centerRect, sf); } }
private static IEnumerable <IResult> ExtractAndAggregateResults <T>(IEnumerable <KeyValuePair <string, IItem> > results) where T : class, IItem, new() { Dictionary <string, List <double> > resultValues = new Dictionary <string, List <double> >(); foreach (var resultValue in results.Where(r => r.Value.GetType() == typeof(T))) { if (!resultValues.ContainsKey(resultValue.Key)) { resultValues[resultValue.Key] = new List <double>(); } resultValues[resultValue.Key].Add(ConvertToDouble(resultValue.Value)); } DoubleValue doubleValue; if (typeof(T) == typeof(PercentValue)) { doubleValue = new PercentValue(); } else if (typeof(T) == typeof(DoubleValue)) { doubleValue = new DoubleValue(); } else if (typeof(T) == typeof(IntValue)) { doubleValue = new DoubleValue(); } else { throw new NotSupportedException(); } List <IResult> aggregatedResults = new List <IResult>(); foreach (KeyValuePair <string, List <double> > resultValue in resultValues) { doubleValue.Value = resultValue.Value.Average(); aggregatedResults.Add(new Result(resultValue.Key + " (average)", (IItem)doubleValue.Clone())); doubleValue.Value = resultValue.Value.StandardDeviation(); aggregatedResults.Add(new Result(resultValue.Key + " (std.dev.)", (IItem)doubleValue.Clone())); } return(aggregatedResults); }
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 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(); }
protected abstract ItemArray <IItem> Relink(ItemArray <IItem> parents, PercentValue n);
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(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))); }
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); }