#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
}
}