#region License Information /* HeuristicLab * Copyright (C) 2002-2013 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.Data; using HeuristicLab.Encodings.PermutationEncoding; namespace HeuristicLab.Analysis.AlgorithmBehavior { public static class AlgorithmBehaviorHelpers { public static bool IsSubtour(IntArray tour, Permutation permutation) { // determine starting position for subtour match int idx = permutation.Select((x, index) => new { Value = x, Index = index }).Single(x => x.Value == tour[0]).Index; bool isSubtour = true; for (int i = 1; i < tour.Length; i++) { if (tour[i] == permutation[(idx + 1) % permutation.Length]) { // check right side idx = (idx + 1) % permutation.Length; } else if (tour[i] == permutation[(idx - 1 + permutation.Length) % permutation.Length]) { // check left side idx = (idx - 1 + permutation.Length) % permutation.Length; } else { isSubtour = false; break; } } return isSubtour; } public static List ExtractSubtours(Permutation permutation) { var subtours = new List(); for (int i = 2; i <= permutation.Count() / 2; i++) { // increase schema length from 2 to n/2 for (int j = 0; j < permutation.Count(); j++) { // visit all positions in the permutation var schema = new IntArray(i); for (int k = 0; k < i; k++) schema[k] = permutation[(j + k) % permutation.Length]; // copy edge to schema subtours.Add(schema); } } return subtours; } public static List ExtractSubtours(Permutation permutation, int length) { var subtours = new List(); int i = 2; for (int j = 0; j < permutation.Count(); j++) { // visit all positions in the permutation var schema = new IntArray(i); for (int k = 0; k < i; k++) schema[k] = permutation[(j + k) % permutation.Length]; // copy edge to schema subtours.Add(schema); } return subtours; } public static IList GenerateWildcardSchemata(IntArray schema) { string formatString = "{0:d" + schema.Length + "}"; var combs = new List(); string comb = string.Empty; // create all desired wildcard combinations long i = 0; int wildcardCount = 0; // first wildcard combination contains no wildcards while (wildcardCount < schema.Length) { wildcardCount = (comb = Convert.ToString(i++, 2)).PadLeft(schema.Length, '0').Count(x => x == '1'); if (wildcardCount > (schema.Length / 8) && wildcardCount < (schema.Length / 2)) // only include wildcards within certain limits combs.Add(comb.Select(x => x == '1').ToArray()); // '1' becomes true which indicates a wildcard } // create all desired wildcard instances var wildcardSchemata = new List(); foreach (var c in combs) { wildcardSchemata.Add(new IntArray(schema.Select((x, index) => c[index] ? -1 : x).ToArray())); // -1 is a wildcard in the schema } return wildcardSchemata; } // attention: brute force matching // should be replaced with KMP, BM or RK public static bool IsMatch(IntArray pattern, int[] tour) { bool match = false; for (int i = 0; i <= tour.Length - pattern.Length && !match; i++) { for (int j = 0; j < pattern.Length && (match = pattern[j] == tour[i + j] || pattern[j] == -1); j++) ; } return match; } } }