#region License Information /* HeuristicLab * Copyright (C) 2002-2010 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.Problems.VehicleRouting.Interfaces; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.Core; using HeuristicLab.Parameters; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.PluginInfrastructure; using HeuristicLab.Common; namespace HeuristicLab.Problems.VehicleRouting.ProblemInstances { [Item("VRPProblemInstance", "Represents a VRP instance.")] [StorableClass] public abstract class VRPProblemInstance: ParameterizedNamedItem, IVRPProblemInstance { public IValueParameter EvaluatorParameter { get { return (ValueParameter)Parameters["Evaluator"]; } } public IValueParameter SolutionCreatorParameter { get { return (ValueParameter)Parameters["SolutionCreator"]; } } protected abstract IEnumerable GetOperators(); protected abstract IEnumerable GetAnalyzers(); public IEnumerable Operators { get { return GetOperators().Union(GetAnalyzers()); } } protected ValueParameter CoordinatesParameter { get { return (ValueParameter)Parameters["Coordinates"]; } } protected OptionalValueParameter DistanceMatrixParameter { get { return (OptionalValueParameter)Parameters["DistanceMatrix"]; } } protected ValueParameter UseDistanceMatrixParameter { get { return (ValueParameter)Parameters["UseDistanceMatrix"]; } } protected ValueParameter VehiclesParameter { get { return (ValueParameter)Parameters["Vehicles"]; } } protected ValueParameter DemandParameter { get { return (ValueParameter)Parameters["Demand"]; } } protected IValueParameter FleetUsageFactorParameter { get { return (IValueParameter)Parameters["EvalFleetUsageFactor"]; } } protected IValueParameter DistanceFactorParameter { get { return (IValueParameter)Parameters["EvalDistanceFactor"]; } } protected OptionalValueParameter BestKnownQualityParameter { get { return (OptionalValueParameter)Parameters["BestKnownQuality"]; } } protected OptionalValueParameter BestKnownSolutionParameter { get { return (OptionalValueParameter)Parameters["BestKnownSolution"]; } } IValueParameter IVRPProblemInstance.BestKnownQualityParameter { get { return BestKnownQualityParameter; } } IValueParameter IVRPProblemInstance.BestKnownSolutionParameter { get { return BestKnownSolutionParameter; } } public DoubleMatrix Coordinates { get { return CoordinatesParameter.Value; } set { CoordinatesParameter.Value = value; } } public DoubleMatrix DistanceMatrix { get { return DistanceMatrixParameter.Value; } set { DistanceMatrixParameter.Value = value; } } public BoolValue UseDistanceMatrix { get { return UseDistanceMatrixParameter.Value; } set { UseDistanceMatrixParameter.Value = value; } } public IntValue Vehicles { get { return VehiclesParameter.Value; } set { VehiclesParameter.Value = value; } } public DoubleArray Demand { get { return DemandParameter.Value; } set { DemandParameter.Value = value; } } public virtual IntValue Cities { get { return new IntValue(Demand.Length); } } public DoubleValue FleetUsageFactor { get { return FleetUsageFactorParameter.Value; } set { FleetUsageFactorParameter.Value = value; } } public DoubleValue DistanceFactor { get { return DistanceFactorParameter.Value; } set { DistanceFactorParameter.Value = value; } } public DoubleValue BestKnownQuality { get { return BestKnownQualityParameter.Value; } set { BestKnownQualityParameter.Value = value; } } public VRPSolution BestKnownSolution { get { return BestKnownSolutionParameter.Value; } set { BestKnownSolutionParameter.Value = value; } } private double CalculateDistance(int start, int end) { double distance = 0.0; distance = Math.Sqrt( Math.Pow(Coordinates[start, 0] - Coordinates[end, 0], 2) + Math.Pow(Coordinates[start, 1] - Coordinates[end, 1], 2)); return distance; } private DoubleMatrix CreateDistanceMatrix() { DoubleMatrix distanceMatrix = new DoubleMatrix(Coordinates.Rows, Coordinates.Rows); for (int i = 0; i < distanceMatrix.Rows; i++) { for (int j = i; j < distanceMatrix.Columns; j++) { double distance = CalculateDistance(i, j); distanceMatrix[i, j] = distance; distanceMatrix[j, i] = distance; } } return distanceMatrix; } public double GetDistance(int start, int end) { double distance = 0.0; DoubleMatrix distanceMatrix = DistanceMatrix; if (distanceMatrix == null && UseDistanceMatrix.Value) { distanceMatrix = DistanceMatrix = CreateDistanceMatrix(); } if (distanceMatrix != null) distance = distanceMatrix[start, end]; else distance = CalculateDistance(start, end); return distance; } public bool Feasible(IVRPEncoding solution) { return EvaluatorParameter.Value.Feasible( EvaluatorParameter.Value.Evaluate( this, solution)); } public bool Feasible(Tour tour) { return EvaluatorParameter.Value.Feasible( EvaluatorParameter.Value.Evaluate( this, tour)); } public double Evaluate(IVRPEncoding solution) { return EvaluatorParameter.Value.Evaluate(this, solution).Quality; } public double Evaluate(Tour tour) { return EvaluatorParameter.Value.Evaluate(this, tour).Quality; } protected void EvalBestKnownSolution() { if (BestKnownSolution != null) { //call evaluator BestKnownQuality = new DoubleValue(Evaluate(BestKnownSolution.Solution)); BestKnownSolution.Quality = BestKnownQuality; } else { BestKnownQuality = null; } } protected abstract IVRPEvaluator Evaluator { get; } protected abstract IVRPCreator Creator { get; } [StorableConstructor] protected VRPProblemInstance(bool deserializing) : base(deserializing) { } public VRPProblemInstance() : base() { Parameters.Add(new ValueParameter("Coordinates", "The x- and y-Coordinates of the cities.", new DoubleMatrix())); Parameters.Add(new OptionalValueParameter("DistanceMatrix", "The matrix which contains the distances between the cities.")); Parameters.Add(new ValueParameter("UseDistanceMatrix", "True if a distance matrix should be calculated and used for evaluation, otherwise false.", new BoolValue(true))); Parameters.Add(new ValueParameter("Vehicles", "The number of vehicles.", new IntValue(0))); Parameters.Add(new ValueParameter("Demand", "The demand of each customer.", new DoubleArray())); Parameters.Add(new ValueParameter("EvalFleetUsageFactor", "The fleet usage factor considered in the evaluation.", new DoubleValue(100))); Parameters.Add(new ValueParameter("EvalDistanceFactor", "The distance factor considered in the evaluation.", new DoubleValue(1))); Parameters.Add(new ValueParameter("SolutionCreator", "The operator which should be used to create new VRP solutions.", Creator)); Parameters.Add(new ValueParameter("Evaluator", "The operator which should be used to evaluate VRP solutions.", Evaluator)); Parameters.Add(new OptionalValueParameter("BestKnownQuality", "The quality of the best known solution of this VRP instance.")); Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution of this VRP instance.")); AttachEventHandlers(); } protected VRPProblemInstance(VRPProblemInstance original, Cloner cloner) : base(original, cloner) { AttachEventHandlers(); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserializationHook() { #region Backwards Compatibility if (!Parameters.ContainsKey("BestKnownSolution")) { Parameters.Add(new OptionalValueParameter("BestKnownSolution", "The best known solution of this TSP instance.")); } if (!Parameters.ContainsKey("BestKnownQuality")) { Parameters.Add(new OptionalValueParameter("BestKnownQuality", "The quality of the best known solution of this VRP instance.")); } #endregion AttachEventHandlers(); } private void AttachEventHandlers() { BestKnownSolutionParameter.ValueChanged += new EventHandler(BestKnownSolutionParameter_ValueChanged); DistanceFactorParameter.ValueChanged += new EventHandler(DistanceFactorParameter_ValueChanged); DistanceFactorParameter.Value.ValueChanged += new EventHandler(DistanceFactor_ValueChanged); FleetUsageFactorParameter.ValueChanged += new EventHandler(FleetUsageFactorParameter_ValueChanged); FleetUsageFactorParameter.Value.ValueChanged += new EventHandler(FleetUsageFactor_ValueChanged); DistanceMatrixParameter.ValueChanged += new EventHandler(DistanceMatrixParameter_ValueChanged); if (DistanceMatrix != null) { DistanceMatrix.ItemChanged += new EventHandler>(DistanceMatrix_ItemChanged); DistanceMatrix.Reset += new EventHandler(DistanceMatrix_Reset); } UseDistanceMatrixParameter.ValueChanged += new EventHandler(UseDistanceMatrixParameter_ValueChanged); UseDistanceMatrix.ValueChanged += new EventHandler(UseDistanceMatrix_ValueChanged); } #region Event handlers void BestKnownSolutionParameter_ValueChanged(object sender, EventArgs e) { EvalBestKnownSolution(); } void DistanceFactorParameter_ValueChanged(object sender, EventArgs e) { DistanceFactorParameter.Value.ValueChanged += new EventHandler(DistanceFactor_ValueChanged); EvalBestKnownSolution(); } void DistanceFactor_ValueChanged(object sender, EventArgs e) { EvalBestKnownSolution(); } void FleetUsageFactorParameter_ValueChanged(object sender, EventArgs e) { FleetUsageFactorParameter.Value.ValueChanged += new EventHandler(FleetUsageFactor_ValueChanged); EvalBestKnownSolution(); } void FleetUsageFactor_ValueChanged(object sender, EventArgs e) { EvalBestKnownSolution(); } void DistanceMatrixParameter_ValueChanged(object sender, EventArgs e) { if (DistanceMatrix != null) { DistanceMatrix.ItemChanged += new EventHandler>(DistanceMatrix_ItemChanged); DistanceMatrix.Reset += new EventHandler(DistanceMatrix_Reset); } EvalBestKnownSolution(); } void DistanceMatrix_Reset(object sender, EventArgs e) { EvalBestKnownSolution(); } void DistanceMatrix_ItemChanged(object sender, EventArgs e) { EvalBestKnownSolution(); } void UseDistanceMatrixParameter_ValueChanged(object sender, EventArgs e) { UseDistanceMatrix.ValueChanged += new EventHandler(UseDistanceMatrix_ValueChanged); EvalBestKnownSolution(); } void UseDistanceMatrix_ValueChanged(object sender, EventArgs e) { EvalBestKnownSolution(); } #endregion } }