[16955] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
| 3 | * Copyright (C) 2002-2018 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
|
---|
| 4 | *
|
---|
| 5 | * This file is part of HeuristicLab.
|
---|
| 6 | *
|
---|
| 7 | * HeuristicLab is free software: you can redistribute it and/or modify
|
---|
| 8 | * it under the terms of the GNU General Public License as published by
|
---|
| 9 | * the Free Software Foundation, either version 3 of the License, or
|
---|
| 10 | * (at your option) any later version.
|
---|
| 11 | *
|
---|
| 12 | * HeuristicLab is distributed in the hope that it will be useful,
|
---|
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
| 15 | * GNU General Public License for more details.
|
---|
| 16 | *
|
---|
| 17 | * You should have received a copy of the GNU General Public License
|
---|
| 18 | * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
|
---|
| 19 | */
|
---|
| 20 | #endregion
|
---|
| 21 |
|
---|
| 22 | using System;
|
---|
| 23 | using System.Collections.Generic;
|
---|
| 24 | using System.IO;
|
---|
| 25 | using System.Linq;
|
---|
| 26 | using System.Text.RegularExpressions;
|
---|
| 27 | using HeuristicLab.Random;
|
---|
| 28 | using ProtoBuf;
|
---|
| 29 | using static HeuristicLab.Analysis.FitnessLandscape.QAPDirectedWalk;
|
---|
| 30 |
|
---|
| 31 | namespace WalkExporter {
|
---|
| 32 | class Program {
|
---|
| 33 | public static readonly string[] SBF = new[] { "Sharpness", "Bumpiness", "Flatness" };
|
---|
| 34 | public static readonly string[] RUG = new[] {
|
---|
| 35 | "AC1", "CorrelationLength" };
|
---|
| 36 | public static readonly string[] IAL = new[] {
|
---|
| 37 | "InformationContent", "DensityBasinInformation", "PartialInformationContent",
|
---|
| 38 | "InformationStability", "Diversity", "Regularity", "TotalEntropy", "SymmetricInformationContent",
|
---|
| 39 | "SymmetricDensityBasinInformation", "SymmetricTotalEntropy", "PeakInformationContent", "PeakDensityBasinInformation",
|
---|
| 40 | "PeakTotalEntropy", "PeakSymmetricInformationContent", "PeakSymmetricDensityBasinInformation", "PeakSymmetricTotalEntropy" };
|
---|
| 41 | public static readonly string[] IALREG = new[] {
|
---|
| 42 | "InformationContent", "DensityBasinInformation", "PartialInformationContent",
|
---|
| 43 | "InformationStability", "Diversity", "Regularity", "TotalEntropy",
|
---|
| 44 | "PeakInformationContent", "PeakDensityBasinInformation", "PeakTotalEntropy"
|
---|
| 45 | };
|
---|
| 46 | public static readonly string[] IALSYM = new[] {
|
---|
| 47 | "PartialInformationContent", "InformationStability", "Diversity", "Regularity",
|
---|
| 48 | "SymmetricInformationContent", "SymmetricDensityBasinInformation", "SymmetricTotalEntropy",
|
---|
| 49 | "PeakSymmetricInformationContent", "PeakSymmetricDensityBasinInformation", "PeakSymmetricTotalEntropy"
|
---|
| 50 | };
|
---|
| 51 |
|
---|
| 52 |
|
---|
| 53 | static void Main(string[] args) {
|
---|
| 54 | //AnalyzeRandomWalkIdentification();
|
---|
| 55 | //AnalyzeDirectedWalkIdentification();
|
---|
| 56 | var provider = new HeuristicLab.Problems.Instances.QAPLIB.QAPLIBInstanceProvider();
|
---|
| 57 | var tai30a = provider.LoadData(provider.GetDataDescriptors().Single(x => x.Name == "tai30a"));
|
---|
| 58 | RandomWalk.ConfinedRandomWalkAnalysis(tai30a);
|
---|
| 59 | var esc32f = provider.LoadData(provider.GetDataDescriptors().Single(x => x.Name == "esc32f"));
|
---|
| 60 | RandomWalk.ConfinedRandomWalkAnalysis(esc32f);
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | private static void AnalyzeRandomWalkIdentification() {
|
---|
| 64 | string[] RUG_IAL = RUG.Concat(IAL).ToArray();
|
---|
| 65 |
|
---|
| 66 | var trainFiles = GetFiles(@"randwalk_kb_train_(?<eff>\d+)");
|
---|
| 67 | var testFiles = GetFiles(@"randwalk_kb_test_(?<eff>\d+)");
|
---|
| 68 |
|
---|
| 69 | var filename = "randwalk_results.csv";
|
---|
| 70 |
|
---|
| 71 | var features = new[] { (Name: "RUG", Set: RUG), (Name: "IAL", Set: IAL),
|
---|
| 72 | (Name: "IALREG", Set: IALREG), (Name: "IALSYM", Set: IALSYM), (Name: "RUG_IAL", Set: RUG_IAL) };
|
---|
| 73 |
|
---|
| 74 | using (var writer = File.CreateText(filename)) {
|
---|
| 75 | CompareMatching(trainFiles, testFiles, features, "randwalk", writer);
|
---|
| 76 | }
|
---|
| 77 | }
|
---|
| 78 |
|
---|
| 79 | private static void AnalyzeDirectedWalkIdentification() {
|
---|
| 80 | string[] RUG_IAL = RUG.Concat(IAL).ToArray();
|
---|
| 81 | string[] SBF_RUG = SBF.Concat(RUG).ToArray();
|
---|
| 82 | string[] SBF_IAL = SBF.Concat(IAL).ToArray();
|
---|
| 83 | string[] SBF_IALREG = SBF.Concat(IALREG).ToArray();
|
---|
| 84 | string[] SBF_IALSYM = SBF.Concat(IALSYM).ToArray();
|
---|
| 85 |
|
---|
| 86 | var features = new[] { (Name: "RUG", Set: RUG), (Name: "IAL", Set: IAL),
|
---|
| 87 | (Name: "IALREG", Set: IALREG), (Name: "IALSYM", Set: IALSYM), (Name: "SBF", Set: SBF),
|
---|
| 88 | (Name: "RUG_IAL", Set: RUG_IAL), (Name: "SBF_RUG", Set: SBF_RUG), (Name: "SBF_IAL", Set: SBF_IAL),
|
---|
| 89 | (Name: "SBF_IALREG", Set: SBF_IALREG), (Name: "SBF_IALSYM", Set: SBF_IALSYM) };
|
---|
| 90 |
|
---|
| 91 |
|
---|
| 92 | var trainFiles = GetFiles(@"rrdw_best_kb_train_(?<eff>\d+)_qap");
|
---|
| 93 | var testFiles = GetFiles(@"rrdw_best_kb_test_(?<eff>\d+)_qap");
|
---|
| 94 |
|
---|
| 95 | var filename = "rrdw_best_results.csv";
|
---|
| 96 |
|
---|
| 97 | //using (var writer = File.CreateText(filename)) {
|
---|
| 98 | // CompareMatching(trainFiles, testFiles, features, "(rr)-dw", writer);
|
---|
| 99 | //}
|
---|
| 100 | //trainFiles = GetFiles(@"rldw_best_kb_train_(?<eff>\d+)_qap");
|
---|
| 101 | //testFiles = GetFiles(@"rldw_best_kb_test_(?<eff>\d+)_qap");
|
---|
| 102 |
|
---|
| 103 | //filename = "rldw_best_results.csv";
|
---|
| 104 |
|
---|
| 105 | //using (var writer = File.CreateText(filename)) {
|
---|
| 106 | // CompareMatching(trainFiles, testFiles, features, "(rl)-dw", writer);
|
---|
| 107 | //}
|
---|
| 108 |
|
---|
| 109 | trainFiles = GetFiles(@"lldw_best_kb_train_(?<eff>\d+)_qap");
|
---|
| 110 | testFiles = GetFiles(@"lldw_best_kb_test_(?<eff>\d+)_qap");
|
---|
| 111 |
|
---|
| 112 | filename = "lldw_best_results.csv";
|
---|
| 113 |
|
---|
| 114 | using (var writer = File.CreateText(filename)) {
|
---|
| 115 | CompareMatching(trainFiles, testFiles, features, "(ll)-dw", writer);
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | trainFiles = GetFiles(@"lidw_best_kb_train_(?<eff>\d+)_qap");
|
---|
| 119 | testFiles = GetFiles(@"lidw_best_kb_test_(?<eff>\d+)_qap");
|
---|
| 120 |
|
---|
| 121 | filename = "lidw_best_results.csv";
|
---|
| 122 |
|
---|
| 123 | using (var writer = File.CreateText(filename)) {
|
---|
| 124 | CompareMatching(trainFiles, testFiles, features, "(li)-dw", writer);
|
---|
| 125 | }
|
---|
| 126 | }
|
---|
| 127 |
|
---|
| 128 | private static List<(string Filename, int Effort)> GetFiles(string pattern) {
|
---|
| 129 | // randwalk_kb_(train|test)_{n}.buf
|
---|
| 130 | // {type}dw_best_kb_(train|test)_{n}_qap.buf
|
---|
| 131 |
|
---|
| 132 | return Directory.EnumerateFiles(".").Where(x => x.EndsWith(".buf"))
|
---|
| 133 | .Select(x => {
|
---|
| 134 | var match = Regex.Match(Path.GetFileName(x), pattern);
|
---|
| 135 | if (match.Success) {
|
---|
| 136 | return (Filename: x, Effort: int.Parse(match.Groups["eff"].Value));
|
---|
| 137 | }
|
---|
| 138 | return (Filename: "", Effort: -1);
|
---|
| 139 | }).Where(x => !string.IsNullOrEmpty(x.Filename)).ToList();
|
---|
| 140 | }
|
---|
| 141 |
|
---|
| 142 | private static void CompareMatching(List<(string Filename, int Effort)> trainFiles,
|
---|
| 143 | List<(string Filename, int Effort)> testFiles, (string Name, string[] Set)[] featuresets,
|
---|
| 144 | string type,
|
---|
| 145 | StreamWriter writer) {
|
---|
| 146 | var random = new MersenneTwister(42);
|
---|
| 147 | var header = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\t{9}\t{10}\t{11}",
|
---|
| 148 | "Dimension", "FSet", "Type", "TrainEff", "TestEff", "ExCnt", "ExRnk", "ClsCnt", "ClsRnk", "TotCnt", "TrainEffSolEquiv", "TestEffSolEquiv");
|
---|
| 149 | writer.WriteLine(header);
|
---|
| 150 | Console.WriteLine(header);
|
---|
| 151 |
|
---|
| 152 | foreach (var features in featuresets) {
|
---|
| 153 | foreach (var dim in new[] { 20, 30, 40 }) {
|
---|
| 154 | foreach (var a in trainFiles) {
|
---|
| 155 | Knowledgebase train = null;
|
---|
| 156 | using (var stream = File.OpenRead(a.Filename))
|
---|
| 157 | train = Serializer.Deserialize<Knowledgebase>(stream);
|
---|
| 158 |
|
---|
| 159 | train.Problems.RemoveAll(x => x.Dimension != dim);
|
---|
| 160 | if (train.Problems.Count == 0) throw new InvalidOperationException("Dimension does not exist: " + dim);
|
---|
| 161 |
|
---|
| 162 | var standardizer = InstancesStandardizer.CreateAndApply(train.Problems, features.Set);
|
---|
| 163 |
|
---|
| 164 | foreach (var b in testFiles) {
|
---|
| 165 | Knowledgebase test = null;
|
---|
| 166 | using (var stream = File.OpenRead(b.Filename))
|
---|
| 167 | test = Serializer.Deserialize<Knowledgebase>(stream);
|
---|
| 168 |
|
---|
| 169 | test.Problems.RemoveAll(x => x.Dimension != dim);
|
---|
| 170 | standardizer.Apply(test.Problems);
|
---|
| 171 | // MATCH
|
---|
| 172 |
|
---|
| 173 | var match = EvaluateMatch(random, train, test, new HashSet<string>(features.Set));
|
---|
| 174 |
|
---|
| 175 | //correlation analysis
|
---|
| 176 | //var corr = AnalyzeFeatureCorrelation(features.Set, train, test);
|
---|
| 177 |
|
---|
| 178 | string output = string.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6:F2}\t{7}\t{8:F2}\t{9}\t{10:F2}\t{11:F2}",
|
---|
| 179 | dim, features.Name, type, a.Effort, b.Effort, match.ExactCount,
|
---|
| 180 | match.ExactAverageRank, match.ClsCount, match.ClsAverageRank, match.TotalCount,
|
---|
| 181 | match.TrainingDescriptionEffort, match.TestDescriptionEffort);
|
---|
| 182 | writer.WriteLine(output);
|
---|
| 183 | Console.WriteLine(output);
|
---|
| 184 | }
|
---|
| 185 | }
|
---|
| 186 | }
|
---|
| 187 | }
|
---|
| 188 | }
|
---|
| 189 |
|
---|
| 190 | private static MatchResult EvaluateMatch(MersenneTwister random, Knowledgebase train, Knowledgebase test, ISet<string> features) {
|
---|
| 191 | var result = new MatchResult();
|
---|
| 192 |
|
---|
| 193 | foreach (var x in train.Problems) {
|
---|
| 194 |
|
---|
| 195 | var ranked = test.Problems.Shuffle(random).Select(y => new {
|
---|
| 196 | Instance = y,
|
---|
| 197 | Distance = (from xx in x.Features.Where(f => features.Contains(f.Key))
|
---|
| 198 | from yy in y.Features.Where(f => features.Contains(f.Key))
|
---|
| 199 | where xx.Key == yy.Key
|
---|
| 200 | let vxx = xx.GetNumericValue()
|
---|
| 201 | let vyy = yy.GetNumericValue()
|
---|
| 202 | select (vxx - vyy) * (vxx - vyy)).Sum(),
|
---|
| 203 | }).OrderBy(xx => xx.Distance).ToList();
|
---|
| 204 |
|
---|
| 205 | var exactRank = -1;
|
---|
| 206 | var clsRank = -1;
|
---|
| 207 | var count = 1;
|
---|
| 208 | foreach (var r in ranked) {
|
---|
| 209 | result.TestDescriptionEffort += r.Instance.DescriptionEffort;
|
---|
| 210 | if (clsRank < 0 && r.Instance.Class == x.Class) {
|
---|
| 211 | clsRank = count;
|
---|
| 212 | }
|
---|
| 213 | if (r.Instance.Name == x.Name) {
|
---|
| 214 | exactRank = count;
|
---|
| 215 | break;
|
---|
| 216 | }
|
---|
| 217 | count++;
|
---|
| 218 | }
|
---|
| 219 | result.TestDescriptionEffort /= test.Problems.Count;
|
---|
| 220 | if (exactRank == 1) result.ExactCount++;
|
---|
| 221 | if (clsRank == 1) result.ClsCount++;
|
---|
| 222 | result.TotalCount++;
|
---|
| 223 |
|
---|
| 224 | result.TrainingDescriptionEffort += x.DescriptionEffort;
|
---|
| 225 | result.ExactAverageRank += exactRank;
|
---|
| 226 | result.ClsAverageRank += clsRank;
|
---|
| 227 |
|
---|
| 228 | }
|
---|
| 229 | result.TrainingDescriptionEffort /= train.Problems.Count;
|
---|
| 230 | result.ExactAverageRank /= train.Problems.Count;
|
---|
| 231 | result.ClsAverageRank /= train.Problems.Count;
|
---|
| 232 |
|
---|
| 233 | return result;
|
---|
| 234 | }
|
---|
| 235 |
|
---|
| 236 | private static double[,] AnalyzeFeatureCorrelation(string[] features, Knowledgebase train, Knowledgebase test) {
|
---|
| 237 | var trainMat = new double[train.Problems.Count, features.Length];
|
---|
| 238 | var testMat = new double[test.Problems.Count, features.Length];
|
---|
| 239 | int trainCount = 0, testCount = 0;
|
---|
| 240 |
|
---|
| 241 | foreach (var x in train.Problems) {
|
---|
| 242 | var xFeatures = x.GetNumericFeatures(features);
|
---|
| 243 | foreach (var f in xFeatures.Select((v, i) => new { Index = i, Value = v })) {
|
---|
| 244 | trainMat[trainCount, f.Index] = f.Value;
|
---|
| 245 | }
|
---|
| 246 | trainCount++;
|
---|
| 247 | }
|
---|
| 248 | foreach (var y in test.Problems) {
|
---|
| 249 | var yFeatures = y.GetNumericFeatures(features);
|
---|
| 250 | foreach (var f in yFeatures.Select((v, i) => new { Index = i, Value = v })) {
|
---|
| 251 | testMat[testCount, f.Index] = f.Value;
|
---|
| 252 | }
|
---|
| 253 | testCount++;
|
---|
| 254 | }
|
---|
| 255 |
|
---|
| 256 | double[,] corr;
|
---|
| 257 | alglib.pearsoncorrm2(trainMat, testMat, out corr);
|
---|
| 258 | return corr;
|
---|
| 259 | }
|
---|
| 260 |
|
---|
| 261 | private static void DoRandomWalk() {
|
---|
| 262 | var experiment = RandomWalk.PerformExperiment();
|
---|
| 263 | Serializer.Serialize(File.Create("randwalk_trials_qap.buf"), experiment);
|
---|
| 264 | foreach (var exp in Enumerable.Range(7, 18 - 6)) {
|
---|
| 265 | var len = (int)Math.Pow(2, exp);
|
---|
| 266 | var (training, test) = RandomWalk.GetKnowledgeBases(experiment, len);
|
---|
| 267 | Serializer.Serialize(File.Create($"randwalk_kb_train_{exp}.buf"), training);
|
---|
| 268 | Serializer.Serialize(File.Create($"randwalk_kb_test_{exp}.buf"), test);
|
---|
| 269 | }
|
---|
| 270 | }
|
---|
| 271 |
|
---|
| 272 | private static void DoDirectedWalk() {
|
---|
| 273 | var (exp, train, test) = DirectedWalk.PerformExperiment(WalkType.RandomRandom);
|
---|
| 274 | Save("rrdw_best", exp, train, test);
|
---|
| 275 | (exp, train, test) = DirectedWalk.PerformExperiment(WalkType.RandomLocal);
|
---|
| 276 | Save("rldw_best", exp, train, test);
|
---|
| 277 | (exp, train, test) = DirectedWalk.PerformExperiment(WalkType.LocalLocal);
|
---|
| 278 | Save("lldw_best", exp, train, test);
|
---|
| 279 | (exp, train, test) = DirectedWalk.PerformExperiment(WalkType.LocalInverse);
|
---|
| 280 | Save("lidw_best", exp, train, test);
|
---|
| 281 | }
|
---|
| 282 |
|
---|
| 283 | private static void Save(string v, Experiment exp, Dictionary<int, Knowledgebase> train, Dictionary<int, Knowledgebase> test) {
|
---|
| 284 | Serializer.Serialize(File.Create(v + "_experiment_qap.buf"), exp);
|
---|
| 285 | foreach (var t in train.Keys) {
|
---|
| 286 | Serializer.Serialize(File.Create(v + $"_kb_train_{t}_qap.buf"), train[t]);
|
---|
| 287 | Serializer.Serialize(File.Create(v + $"_kb_test_{t}_qap.buf"), test[t]);
|
---|
| 288 | }
|
---|
| 289 | }
|
---|
| 290 | }
|
---|
| 291 |
|
---|
| 292 | public class MatchResult {
|
---|
| 293 | public int ExactCount { get; set; }
|
---|
| 294 | public int ClsCount { get; set; }
|
---|
| 295 | public int TotalCount { get; set; }
|
---|
| 296 | public double ExactAverageRank { get; set; }
|
---|
| 297 | public double ClsAverageRank { get; set; }
|
---|
| 298 |
|
---|
| 299 | public double TrainingDescriptionEffort { get; set; }
|
---|
| 300 | public double TestDescriptionEffort { get; set; }
|
---|
| 301 | }
|
---|
| 302 | }
|
---|