#region License Information /* HeuristicLab * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Text; using HeuristicLab.Core; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Common; using HeuristicLab.PDPSimulation.DomainModel; using System.Threading; using HeuristicLab.Problems.VehicleRouting.Interfaces; using HeuristicLab.Problems.VehicleRouting; using HeuristicLab.Problems.VehicleRouting.Variants; using HeuristicLab.Problems.VehicleRouting.ProblemInstances; using HeuristicLab.PDPSimulation.Operators; using HeuristicLab.Parameters; using HeuristicLab.Data; using System.Threading.Tasks; using HeuristicLab.Problems.VehicleRouting.Encodings.Potvin; namespace HeuristicLab.PDPSimulation { [Item("PFIHReoptimization", "A pickup and delivery PFIH optimization.")] [StorableClass] public class PFIHReoptimization : DynamicPDPOptimization { public IValueParameter Alpha { get { return (IValueParameter)Parameters["Alpha"]; } } public IValueParameter AlphaVariance { get { return (IValueParameter)Parameters["AlphaVariance"]; } } public IValueParameter Beta { get { return (IValueParameter)Parameters["Beta"]; } } public IValueParameter BetaVariance { get { return (IValueParameter)Parameters["BetaVariance"]; } } public IValueParameter Gamma { get { return (IValueParameter)Parameters["Gamma"]; } } public IValueParameter GammaVariance { get { return (IValueParameter)Parameters["GammaVariance"]; } } public ValueParameter SampleSizeParameter { get { return (ValueParameter)Parameters["SampleSize"]; } } public ValueParameter ComputeInParallelParameter { get { return (ValueParameter)Parameters["ComputeInParallel"]; } } public PFIHReoptimization(): base() { Parameters.Add(new ValueParameter("Alpha", "The alpha value.", new DoubleValue(0.7))); Parameters.Add(new ValueParameter("AlphaVariance", "The alpha variance.", new DoubleValue(0.5))); Parameters.Add(new ValueParameter("Beta", "The beta value.", new DoubleValue(0.1))); Parameters.Add(new ValueParameter("BetaVariance", "The beta variance.", new DoubleValue(0.07))); Parameters.Add(new ValueParameter("Gamma", "The gamma value.", new DoubleValue(0.2))); Parameters.Add(new ValueParameter("GammaVariance", "The gamma variance.", new DoubleValue(0.14))); Parameters.Add(new ValueParameter("SampleSize", "The sample size.", new IntValue(10))); Parameters.Add(new ValueParameter("ComputeInParallel", "Indicates if the samples should be computed in parallel.", new BoolValue(true))); } [StorableConstructor] private PFIHReoptimization(bool deserializing) : base(deserializing) { } private PFIHReoptimization(PFIHReoptimization original, Cloner cloner) : base(original, cloner) { } public override IDeepCloneable Clone(Cloner cloner) { return new PFIHReoptimization(this, cloner); } class PFIHResult { public PFIHResult() { bestFeasible = false; bestQuality = double.MaxValue; bestSolution = null; } public bool bestFeasible; public double bestQuality; public IVRPEncoding bestSolution; } private IVRPEncoding Optimize(DynamicPDProblemInstance instance) { List vehicleUsed = new List(); for (int i = 0; i < instance.StaticInstance.Vehicles.Value; i++) { Vehicle vehicle = GetVehicle(instance.GetVehicle(i)); vehicleUsed.Add(vehicle.Distance > 0); } int sampleSize = SampleSizeParameter.Value.Value; PFIHResult bestResult = new PFIHResult(); var options = new ParallelOptions(); if (ComputeInParallelParameter.Value.Value) options.MaxDegreeOfParallelism = Math.Max(Environment.ProcessorCount - 1, 1); else options.MaxDegreeOfParallelism = 1; IRandom random = new HeuristicLab.Random.MersenneTwister(1234); Parallel.For(0, sampleSize, options, () => new PFIHResult(), (i, loop, result) => { IVRPEncoding current = DynPushForwardInsertionCreator.CreateSolution(instance.StaticInstance, random, vehicleUsed, Alpha.Value.Value, Beta.Value.Value, Gamma.Value.Value, AlphaVariance.Value.Value, BetaVariance.Value.Value, GammaVariance.Value.Value); VRPEvaluation eval = instance.StaticInstance.Evaluate(current); double quality = eval.Quality; bool feasible = instance.StaticInstance.Feasible(eval); if ((feasible && !result.bestFeasible) || (feasible == result.bestFeasible && quality < result.bestQuality)) { result.bestQuality = quality; result.bestSolution = current; result.bestFeasible = feasible; } return result; }, (result) => { lock (bestResult) { if ((result.bestFeasible && !bestResult.bestFeasible) || (result.bestFeasible == bestResult.bestFeasible && result.bestQuality < bestResult.bestQuality)) { bestResult.bestQuality = result.bestQuality; bestResult.bestSolution = result.bestSolution; bestResult.bestFeasible = result.bestFeasible; } } } ); //Recourse if (!bestResult.bestFeasible) { PotvinEncoding currentPlan = (instance.StaticInstance as DynPDPProblemInstance).CurrentPlan; BestInsertion.RouteUnrouted(instance.StaticInstance, currentPlan); bestResult.bestSolution = currentPlan; } return bestResult.bestSolution; } protected override bool PerformOptimization(DynamicPDProblemInstance instance, ChangeInformation changeInformation) { IVRPEncoding solution = Optimize(instance); PerformPlan(solution); return true; } } }