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