#region License Information
/* HeuristicLab
* Copyright (C) 2002-2016 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 HeuristicLab.Common;
using HeuristicLab.Core;
using HeuristicLab.Data;
using HeuristicLab.Optimization;
using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
using HeuristicLab.Problems.GeneralizedQuadraticAssignment;
namespace HeuristicLab.Analysis.FitnessLandscape {
[Item("GQAP Characteristic Calculator", "")]
[StorableClass]
public sealed class GQAPCharacteristicCalculator : CharacteristicCalculator {
[StorableConstructor]
private GQAPCharacteristicCalculator(bool deserializing) : base(deserializing) { }
private GQAPCharacteristicCalculator(GQAPCharacteristicCalculator original, Cloner cloner) : base(original, cloner) { }
public GQAPCharacteristicCalculator() {
characteristics.AddRange(new[] {
"Dimension", "MNRatio",
"FlowDominance", "DistanceDominance",
"FlowSparsity", "DistanceSparsity",
"DemandDominance", "CapacityDominance",
"Utilization", "BasicFeasibility",
}.Select(x => new StringValue(x)).ToList());
}
public override IDeepCloneable Clone(Cloner cloner) {
return new GQAPCharacteristicCalculator(this, cloner);
}
public override bool CanCalculate() {
return Problem is GQAP;
}
public override IEnumerable Calculate() {
var gqap = Problem as GQAP;
if (gqap == null) throw new ArgumentException("Instance is not of type GQAP");
var inst = gqap.ProblemInstance;
foreach (var chara in characteristics.CheckedItems.Select(x => x.Value.Value)) {
if (chara == "Dimension")
yield return new Result(chara, new IntValue(inst.Demands.Length));
if (chara == "MNRatio")
yield return new Result(chara, new DoubleValue(inst.Capacities.Length / (double)inst.Demands.Length));
if (chara == "FlowDominance")
yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariationNonZeroes(inst.Weights)));
if (chara == "DistanceDominance")
yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.CoeffVariationNonZeroes(inst.Distances)));
if (chara == "FlowSparsity")
yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(inst.Weights)));
if (chara == "DistanceSparsity")
yield return new Result(chara, new DoubleValue(DoubleMatrixCharacteristicCalculator.Sparsity(inst.Distances)));
if (chara == "DemandDominance")
yield return new Result(chara, new DoubleValue(inst.Demands.StandardDeviation() / inst.Demands.Average()));
if (chara == "CapacityDominance")
yield return new Result(chara, new DoubleValue(inst.Capacities.StandardDeviation() / inst.Capacities.Average()));
if (chara == "Utilization")
yield return new Result(chara, new DoubleValue(inst.Demands.Sum() / inst.Capacities.Sum()));
if (chara == "BasicFeasibility")
yield return new Result(chara, new DoubleValue(inst.Demands.Select(d => inst.Capacities.Count(c => d <= c)).Average() / inst.Capacities.Length));
}
}
}
}