using System; using System.Collections.Generic; using System.Linq; using HeuristicLab.Analysis.FitnessLandscape; using HeuristicLab.Common; using HeuristicLab.Data; using HeuristicLab.Encodings.PermutationEncoding; using HeuristicLab.Problems.QuadraticAssignment; namespace ProblemInstanceIdentifier { public class InstanceDescriptor { public string Name { get; set; } public string Cls { get; private set; } public int Dimension { get; set; } public string[] FeatureNames { get; set; } public double[] FeatureValues { get; set; } private InstanceDescriptor() { } public InstanceDescriptor(string name, string cls, int dimension, string[] names, double[] values) { Name = name; Cls = cls; Dimension = dimension; FeatureNames = names; FeatureValues = values; } public InstanceDescriptor(InstanceDescriptor other) { Name = other.Name; Cls = other.Cls; Dimension = other.Dimension; FeatureNames = (string[])other.FeatureNames.Clone(); FeatureValues = (double[]) other.FeatureValues.Clone(); } public static InstanceDescriptor FromProblemOnly(QuadraticAssignmentProblem qap) { return new InstanceDescriptor() { Name = qap.Name, Cls = GetClass(qap.Name), Dimension = qap.Weights.Rows, FeatureNames = new string[0], FeatureValues = new double[0] }; } public static InstanceDescriptor FromPaths(QuadraticAssignmentProblem qap, List>> trajectories) { var result = PermutationPathAnalysis.GetCharacteristics(trajectories); return new InstanceDescriptor() { Name = qap.Name, Cls = GetClass(qap.Name), Dimension = qap.Weights.Rows, FeatureNames = result.GetNames(), FeatureValues = result.GetValues() }; } public static string GetClass(string name) { var cls = name.Substring(0, 3); var subCls = name.Last(); switch (cls) { case "lip": cls = name.Substring(0, 4) + "-" + subCls; break; case "RAN": cls = name.Substring(0, 4) + "-" + name[name.Length - 2] + name[name.Length - 1]; break; case "tai": if (char.IsLetter(subCls)) cls += "-" + subCls; break; } return cls; } public double CalculateSimilarity(InstanceDescriptor other) { return FeatureValues.Select((v, i) => (v - other.FeatureValues[i]) * (v - other.FeatureValues[i])).Sum(); } public override string ToString() { return Name; } } public class InstancesStandardizer { private double[] featureMeans; private double[] featureStdevs; public IEnumerable GetMeans() { return featureMeans; } public IEnumerable GetStdevs() { return featureStdevs; } private InstancesStandardizer() { } public static InstancesStandardizer Create(IList instances) { var standardizer = new InstancesStandardizer(); var featureLength = instances.First().FeatureValues.Length; standardizer.featureMeans = Enumerable.Range(0, featureLength) .Select(x => instances.Select(y => y.FeatureValues[x]).Average()).ToArray(); standardizer.featureStdevs = Enumerable.Range(0, featureLength) .Select(x => instances.Select(y => y.FeatureValues[x]).StandardDeviation()).ToArray(); return standardizer; } public static InstancesStandardizer CreateAndApply(IList instances) { var standardizer = Create(instances); standardizer.Apply(instances); return standardizer; } public void Apply(IList instances) { for (var i = 0; i < instances.Count; i++) { var inst = instances[i]; for (var x = 0; x < featureMeans.Length; x++) inst.FeatureValues[x] = (inst.FeatureValues[x] - featureMeans[x]) / featureStdevs[x]; } } } }