Changeset 14471


Ignore:
Timestamp:
12/09/16 15:56:22 (4 years ago)
Author:
abeham
Message:

#2701:

  • Updated GraphColoringProblem and Problems.Instances
    • Added new fitness function from literature
    • Added DIMACS benchmark instances
  • Updated LinearLinkageEncoding
    • Added HammingSimilarityCalculator
Location:
branches/MemPRAlgorithm
Files:
13 added
7 edited
4 copied

Legend:

Unmodified
Added
Removed
  • branches/MemPRAlgorithm/HeuristicLab 3.3.sln

    r14466 r14471  
    3535    {E0B45023-CB84-48A1-A1B7-8295B64B7BAD} = {E0B45023-CB84-48A1-A1B7-8295B64B7BAD}
    3636    {C633FB23-BAE6-448E-BF5D-E1F9A839B5ED} = {C633FB23-BAE6-448E-BF5D-E1F9A839B5ED}
     37    {9943FF23-8619-459C-B84A-E7FBDCBA04E6} = {9943FF23-8619-459C-B84A-E7FBDCBA04E6}
    3738    {CDA28124-ACD0-4231-8EB0-C510B361F84E} = {CDA28124-ACD0-4231-8EB0-C510B361F84E}
    3839    {14AB8D24-25BC-400C-A846-4627AA945192} = {14AB8D24-25BC-400C-A846-4627AA945192}
     
    132133    {BBF2CCC8-4D87-4297-8E18-8241FF93F966} = {BBF2CCC8-4D87-4297-8E18-8241FF93F966}
    133134    {59F354CB-FE13-4253-AED2-AD86372BEC27} = {59F354CB-FE13-4253-AED2-AD86372BEC27}
     135    {4B76E2CB-A990-4959-B080-1D81D418D325} = {4B76E2CB-A990-4959-B080-1D81D418D325}
    134136    {D1EFA4CC-909F-41D5-9C1F-C3AF1957A372} = {D1EFA4CC-909F-41D5-9C1F-C3AF1957A372}
    135137    {7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086} = {7A2531CE-3F7C-4F13-BCCA-ED6DC27A7086}
     
    454456EndProject
    455457Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.GraphColoring-3.3", "HeuristicLab.Problems.GraphColoring\3.3\HeuristicLab.Problems.GraphColoring-3.3.csproj", "{4B76E2CB-A990-4959-B080-1D81D418D325}"
     458EndProject
     459Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Problems.Instances.DIMACS-3.3", "HeuristicLab.Problems.Instances.DIMACS\3.3\HeuristicLab.Problems.Instances.DIMACS-3.3.csproj", "{9943FF23-8619-459C-B84A-E7FBDCBA04E6}"
    456460EndProject
    457461Global
     
    22172221    {4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.ActiveCfg = Release|Any CPU
    22182222    {4B76E2CB-A990-4959-B080-1D81D418D325}.Release|x86.Build.0 = Release|Any CPU
     2223    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
     2224    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
     2225    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|x64.ActiveCfg = Debug|Any CPU
     2226    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|x64.Build.0 = Debug|Any CPU
     2227    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|x86.ActiveCfg = Debug|Any CPU
     2228    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Debug|x86.Build.0 = Debug|Any CPU
     2229    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
     2230    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|Any CPU.Build.0 = Release|Any CPU
     2231    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|x64.ActiveCfg = Release|Any CPU
     2232    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|x64.Build.0 = Release|Any CPU
     2233    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|x86.ActiveCfg = Release|Any CPU
     2234    {9943FF23-8619-459C-B84A-E7FBDCBA04E6}.Release|x86.Build.0 = Release|Any CPU
    22192235  EndGlobalSection
    22202236  GlobalSection(SolutionProperties) = preSolution
  • branches/MemPRAlgorithm/HeuristicLab.Algorithms.MemPR/3.3/LinearLinkage/LinearLinkageMemPR.cs

    r14466 r14471  
    5858
    5959    protected override bool Eq(ISingleObjectiveSolutionScope<Encodings.LinearLinkageEncoding.LinearLinkage> a, ISingleObjectiveSolutionScope<Encodings.LinearLinkageEncoding.LinearLinkage> b) {
    60       return a.Solution.SequenceEqual(b.Solution);
     60      var s1 = a.Solution;
     61      var s2 = b.Solution;
     62      if (s1.Length != s2.Length) return false;
     63      for (var i = 0; i < s1.Length; i++)
     64        if (s1[i] != s2[i]) return false;
     65      return true;
    6166    }
    6267
    6368    protected override double Dist(ISingleObjectiveSolutionScope<Encodings.LinearLinkageEncoding.LinearLinkage> a, ISingleObjectiveSolutionScope<Encodings.LinearLinkageEncoding.LinearLinkage> b) {
    64       if (a.Solution.Length != b.Solution.Length) throw new ArgumentException("Comparing encodings of unequal length");
    65       var dist = 0;
    66       for (var i = 0; i < a.Solution.Length; i++) {
    67         if (a.Solution[i] != b.Solution[i]) dist++;
    68       }
    69       return dist / (double)a.Solution.Length;
     69      return HammingSimilarityCalculator.CalculateSimilarity(a.Solution, b.Solution);
    7070    }
    7171
     
    9494    protected override int TabuWalk(ISingleObjectiveSolutionScope<Encodings.LinearLinkageEncoding.LinearLinkage> scope, int maxEvals, CancellationToken token, ISolutionSubspace<Encodings.LinearLinkageEncoding.LinearLinkage> subspace = null) {
    9595      return 0;
     96      /*Func<Encodings.LinearLinkageEncoding.LinearLinkage, IRandom, double> eval = new EvaluationWrapper<Encodings.LinearLinkageEncoding.LinearLinkage>(Context.Problem, scope).Evaluate;
     97      var quality = scope.Fitness;
     98      var lle = scope.Solution;
     99      var random = Context.Random;
     100      var evaluations = 0;
     101      var maximization = Context.Problem.Maximization;
     102      if (double.IsNaN(quality)) {
     103        quality = eval(lle, random);
     104        evaluations++;
     105      }
     106      Encodings.LinearLinkageEncoding.LinearLinkage bestOfTheWalk = null;
     107      double bestOfTheWalkF = double.NaN;
     108      var current = (Encodings.LinearLinkageEncoding.LinearLinkage)lle.Clone();
     109      var currentF = quality;
     110      var overallImprovement = false;
     111      var tabu = new double[current.Length, current.Length];
     112      for (var i = 0; i < current.Length; i++) {
     113        for (var j = i; j < current.Length; j++) {
     114          tabu[i, j] = tabu[j, i] = double.MaxValue;
     115        }
     116        tabu[i, current[i]] = currentF;
     117      }
     118
     119      var steps = 0;
     120      var stepsUntilBestOfWalk = 0;
     121      for (var iter = 0; iter < int.MaxValue; iter++) {
     122        var allTabu = true;
     123        var bestOfTheRestF = double.NaN;
     124        object bestOfTheRest = null;
     125        var improved = false;
     126        foreach () {
     127          if (subspace != null && !(subspace[swap.Index1, 0] && subspace[swap.Index2, 0]))
     128            continue;
     129
     130
     131          var q = eval(current, random);
     132          evaluations++;
     133          if (FitnessComparer.IsBetter(maximization, q, quality)) {
     134            overallImprovement = true;
     135            quality = q;
     136            for (var i = 0; i < current.Length; i++) lle[i] = current[i];
     137          }
     138          // check if it would not be an improvement to swap these into their positions
     139          var isTabu = !FitnessComparer.IsBetter(maximization, q, tabu[swap.Index1, current[swap.Index1]])
     140                    && !FitnessComparer.IsBetter(maximization, q, tabu[swap.Index2, current[swap.Index2]]);
     141          if (!isTabu) allTabu = false;
     142          if (FitnessComparer.IsBetter(maximization, q, currentF) && !isTabu) {
     143            if (FitnessComparer.IsBetter(maximization, q, bestOfTheWalkF)) {
     144              bestOfTheWalk = (Encodings.LinearLinkageEncoding.LinearLinkage)current.Clone();
     145              bestOfTheWalkF = q;
     146              stepsUntilBestOfWalk = steps;
     147            }
     148            steps++;
     149            improved = true;
     150            // perform the move
     151            currentF = q;
     152            // mark that to move them to their previous position requires to make an improvement
     153            tabu[swap.Index1, current[swap.Index2]] = maximization ? Math.Max(q, tabu[swap.Index1, current[swap.Index2]])
     154                                                                   : Math.Min(q, tabu[swap.Index1, current[swap.Index2]]);
     155            tabu[swap.Index2, current[swap.Index1]] = maximization ? Math.Max(q, tabu[swap.Index2, current[swap.Index1]])
     156                                                                   : Math.Min(q, tabu[swap.Index2, current[swap.Index1]]);
     157          } else { // undo the move
     158            if (!isTabu && FitnessComparer.IsBetter(maximization, q, bestOfTheRestF)) {
     159              bestOfTheRest = swap;
     160              bestOfTheRestF = q;
     161            }
     162            current[swap.Index2] = current[swap.Index1];
     163            current[swap.Index1] = h;
     164          }
     165          if (evaluations >= maxEvals) break;
     166        }
     167        if (!allTabu && !improved && bestOfTheRest != null) {
     168          tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]] = maximization ? Math.Max(currentF, tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]])
     169                                                                                   : Math.Min(currentF, tabu[bestOfTheRest.Index1, current[bestOfTheRest.Index1]]);
     170          tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]] = maximization ? Math.Max(currentF, tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]])
     171                                                                                   : Math.Min(currentF, tabu[bestOfTheRest.Index2, current[bestOfTheRest.Index2]]);
     172
     173          var h = current[bestOfTheRest.Index1];
     174          current[bestOfTheRest.Index1] = current[bestOfTheRest.Index2];
     175          current[bestOfTheRest.Index2] = h;
     176
     177          currentF = bestOfTheRestF;
     178          steps++;
     179        } else if (allTabu) break;
     180        if (evaluations >= maxEvals) break;
     181      }
     182      Context.IncrementEvaluatedSolutions(evaluations);
     183      if (!overallImprovement && bestOfTheWalk != null) {
     184        quality = bestOfTheWalkF;
     185        for (var i = 0; i < current.Length; i++) lle[i] = bestOfTheWalk[i];
     186      }
     187      return stepsUntilBestOfWalk;*/
    96188    }
    97189
  • branches/MemPRAlgorithm/HeuristicLab.Encodings.LinearLinkageEncoding/3.3/HeuristicLab.Encodings.LinearLinkageEncoding-3.3.csproj

    r12650 r14471  
    182182    <Compile Include="Moves\Swap\Swap2MoveMaker.cs" />
    183183    <Compile Include="ShakingOperators\LLEShakingOperator.cs" />
     184    <Compile Include="SimilarityCalculators\HammingSimilarityCalculator.cs" />
    184185    <None Include="HeuristicLab.snk" />
    185186    <None Include="Plugin.cs.frame" />
  • branches/MemPRAlgorithm/HeuristicLab.Problems.GraphColoring/3.3/GraphColoringProblem.cs

    r14466 r14471  
    2121
    2222using System;
     23using System.Linq;
     24using HeuristicLab.Analysis;
    2325using HeuristicLab.Common;
    2426using HeuristicLab.Core;
     
    2628using HeuristicLab.Encodings.LinearLinkageEncoding;
    2729using HeuristicLab.Optimization;
     30using HeuristicLab.Optimization.Operators;
    2831using HeuristicLab.Parameters;
    2932using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     33using HeuristicLab.Problems.Instances;
    3034
    3135namespace HeuristicLab.Problems.GraphColoring {
     36  public enum FitnessFunction { Prioritized, Penalized }
    3237  [Item("Graph Coloring Problem (GCP)", "Attempts to find a coloring using a minimal number of colors that doesn't produce a conflict.")]
     38  [Creatable(CreatableAttribute.Categories.CombinatorialProblems, Priority = 135)]
    3339  [StorableClass]
    34   public sealed class GraphColoringProblem : SingleObjectiveBasicProblem<LinearLinkageEncoding> {
     40  public sealed class GraphColoringProblem : SingleObjectiveBasicProblem<LinearLinkageEncoding>, IProblemInstanceConsumer<GCPData> {
    3541
    3642    public override bool Maximization {
     
    3844    }
    3945
    40     private IValueParameter<BoolMatrix> adjacencyMatrixParameter;
    41     public IValueParameter<BoolMatrix> AdjacencyMatrixParameter {
    42       get { return adjacencyMatrixParameter; }
     46    [Storable]
     47    private IValueParameter<IntMatrix> adjacencyListParameter;
     48    public IValueParameter<IntMatrix> AdjacencyListParameter {
     49      get { return adjacencyListParameter; }
     50    }
     51    [Storable]
     52    private IValueParameter<EnumValue<FitnessFunction>> fitnessFunctionParameter;
     53    public IValueParameter<EnumValue<FitnessFunction>> FitnessFunctionParameter {
     54      get { return fitnessFunctionParameter; }
    4355    }
    4456
     
    4759    private GraphColoringProblem(GraphColoringProblem original, Cloner cloner)
    4860      : base(original, cloner) {
    49       adjacencyMatrixParameter = cloner.Clone(original.adjacencyMatrixParameter);
     61      adjacencyListParameter = cloner.Clone(original.adjacencyListParameter);
     62      fitnessFunctionParameter = cloner.Clone(original.fitnessFunctionParameter);
     63      RegisterEventHandlers();
    5064    }
    5165    public GraphColoringProblem() {
    52       Encoding = new LinearLinkageEncoding("lle") { Length = 32 };
    53       Parameters.Add(adjacencyMatrixParameter = new ValueParameter<BoolMatrix>("AdjacencyMatrix", "The matrix that describes whether two nodes are linked."));
    54      
    55       var rand = new System.Random(0);
    56       var matrix = new BoolMatrix(32, 32);
    57       for (var i = 0; i < 31; i++) {
    58         for (var j = i + 1; j < 32; j++) {
    59           matrix[i, j] = rand.NextDouble() < 0.2;
    60           matrix[j, i] = matrix[i, j];
    61         }
     66      Encoding = new LinearLinkageEncoding("lle");
     67      Parameters.Add(adjacencyListParameter = new ValueParameter<IntMatrix>("Adjacency List", "The adjacency list that describes the (symmetric) edges in the graph with nodes from 0 to N-1."));
     68      Parameters.Add(fitnessFunctionParameter = new ValueParameter<EnumValue<FitnessFunction>>("Fitness Function", "The function to use for evaluating the quality of a solution.", new EnumValue<FitnessFunction>(FitnessFunction.Prioritized)));
     69
     70      var imat = new IntMatrix(defaultInstance.Length, 2);
     71      for (var i = 0; i < defaultInstance.Length; i++) {
     72        imat[i, 0] = defaultInstance[i].Item1 - 1;
     73        imat[i, 1] = defaultInstance[i].Item2 - 1;
    6274      }
    63       AdjacencyMatrixParameter.Value = matrix;
     75      Encoding.Length = defaultInstanceNodes;
     76      AdjacencyListParameter.Value = imat;
     77      BestKnownQuality = 7;
     78
     79      InitializeOperators();
     80      RegisterEventHandlers();
    6481    }
    6582
     
    6885    }
    6986
     87    protected override void OnEncodingChanged() {
     88      base.OnEncodingChanged();
     89
     90      Parameterize();
     91    }
     92
     93    [StorableHook(HookType.AfterDeserialization)]
     94    private void AfterDeserialization() {
     95      RegisterEventHandlers();
     96    }
     97
     98    private void RegisterEventHandlers() {
     99      fitnessFunctionParameter.ValueChanged += FitnessFunctionParameterOnValueChanged;
     100      fitnessFunctionParameter.Value.ValueChanged += FitnessFunctionOnValueChanged;
     101    }
     102
     103    private void FitnessFunctionParameterOnValueChanged(object sender, EventArgs eventArgs) {
     104      fitnessFunctionParameter.Value.ValueChanged += FitnessFunctionOnValueChanged;
     105      OnReset();
     106    }
     107
     108    private void FitnessFunctionOnValueChanged(object sender, EventArgs eventArgs) {
     109      BestKnownQualityParameter.Value = null;
     110      OnReset();
     111    }
     112
    70113    public override double Evaluate(Individual individual, IRandom random) {
    71       var matrix = adjacencyMatrixParameter.Value;
    72       var lle = individual.LinearLinkage("lle");
    73       var groups = lle.GetGroups();
     114      var fitFun = FitnessFunctionParameter.Value.Value;
     115      var adjList = adjacencyListParameter.Value;
     116      var lle = individual.LinearLinkage(Encoding.Name).ToLLEe(); // LLE-e encoding uses the highest indexed member as group number
     117
     118      switch (fitFun) {
     119        case FitnessFunction.Prioritized: {
     120            var conflicts = 0;
     121            var colors = lle.Distinct().Count();
     122            for (var r = 0; r < adjList.Rows; r++) {
     123              if (lle[adjList[r, 0]] == lle[adjList[r, 1]]) conflicts++; // both nodes are adjacent and have the same color (are in the same group)
     124            }
     125            // number of conflicts is the integer part of the quality
     126            // number of colors constitutes the fractional part
     127            // the number of fractional digits is defined by the maximum number of possible colors (each node its own color)
     128            var mag = Math.Pow(10, -(int)Math.Ceiling(Math.Log10(lle.Length)));
     129            // the value is e.g. 4.03 for 4 conflicts with 3 colors (and less than 100 nodes)
     130            return conflicts + colors * mag;
     131          }
     132        case FitnessFunction.Penalized: {
     133            // Fitness function from
     134            // David S. Johnson, Cecilia R. Aragon, Lyle A. McGeoch, and Catherine Schevon. 1991.
     135            // Optimization by simulated annealing: An experimental evaluation; part II, graph coloring and number partitioning.
     136            // Operations Research 39(3), pp. 378–406.
     137            // All local optima of this function correspond to legal colorings.
     138            var colors = lle.GroupBy(x => x).ToDictionary(x => x.Key, x => new EvaluationHelper() { ColorCount = x.Count() });
     139            for (var r = 0; r < adjList.Rows; r++) {
     140              var color1 = lle[adjList[r, 0]];
     141              var color2 = lle[adjList[r, 1]];
     142              if (color1 == color2) colors[color1].ConflictCount++;
     143            }
     144            return 2 * colors.Sum(x => x.Value.ColorCount * x.Value.ConflictCount) - colors.Sum(x => x.Value.ColorCount * x.Value.ColorCount);
     145          }
     146        default: throw new InvalidOperationException(string.Format("Unknown fitness function {0}.", fitFun));
     147      }
     148    }
     149
     150    private class EvaluationHelper {
     151      public int ColorCount { get; set; }
     152      public int ConflictCount { get; set; }
     153    }
     154
     155    public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) {
     156      var orderedIndividuals = individuals.Zip(qualities, (i, q) => new { Individual = i, Quality = q }).OrderBy(z => z.Quality);
     157      var best = Maximization ? orderedIndividuals.Last().Individual.LinearLinkage(Encoding.Name) : orderedIndividuals.First().Individual.LinearLinkage(Encoding.Name);
     158
     159      var adjList = AdjacencyListParameter.Value;
     160      var lle = best.ToLLEe();
    74161      var conflicts = 0;
    75       var colors = 0;
    76       foreach (var g in groups) {
    77         colors++;
    78         for (var i = 0; i < g.Count - 1; i++) {
    79           for (var j = i + 1; j < g.Count; j++) {
    80             if (matrix[g[i], g[j]]) conflicts++; // both nodes are adjacent and have the same color (are in the same group)
    81           }
    82         }
     162      var colors = lle.Distinct().Count();
     163      for (var r = 0; r < adjList.Rows; r++) {
     164        if (lle[adjList[r, 0]] == lle[adjList[r, 1]]) conflicts++; // both nodes are adjacent and have the same color (are in the same group)
    83165      }
    84166
    85       var mag = Math.Pow(10, -(int)Math.Ceiling(Math.Log10(matrix.Rows)));
    86       return conflicts + colors * mag;
    87     }
     167      IResult res;
     168      if (!results.TryGetValue("Best Solution Colors", out res)) {
     169        res = new Result("Best Solution Colors", new IntValue(colors));
     170        results.Add(res);
     171      } else ((IntValue)res.Value).Value = colors;
     172      if (!results.TryGetValue("Best Solution Conflicts", out res)) {
     173        res = new Result("Best Solution Conflicts", new IntValue(conflicts));
     174        results.Add(res);
     175      } else ((IntValue)res.Value).Value = conflicts;
     176    }
     177
     178    public void Load(GCPData data) {
     179      Encoding.Length = data.Nodes;
     180      AdjacencyListParameter.Value = new IntMatrix(data.Adjacencies);
     181      if (FitnessFunctionParameter.Value.Value == FitnessFunction.Prioritized && data.BestKnownColors.HasValue) {
     182        var mag = Math.Pow(10, -(int)Math.Ceiling(Math.Log10(data.Nodes)));
     183        // the value is e.g. 4.03 for 4 conflicts with 3 colors (and less than 100 nodes)
     184        BestKnownQuality = data.BestKnownColors.Value * mag;
     185      } else BestKnownQualityParameter.Value = null;
     186      Name = data.Name;
     187      Description = data.Description;
     188      OnReset();
     189    }
     190
     191    private void InitializeOperators() {
     192      Operators.Add(new HammingSimilarityCalculator());
     193      Operators.Add(new QualitySimilarityCalculator());
     194      Operators.Add(new PopulationSimilarityAnalyzer(Operators.OfType<ISolutionSimilarityCalculator>()));
     195
     196      Parameterize();
     197    }
     198
     199    private void Parameterize() {
     200      foreach (var simCalc in Operators.OfType<ISolutionSimilarityCalculator>()) {
     201        simCalc.SolutionVariableName = Encoding.Name;
     202        simCalc.QualityVariableName = Evaluator.QualityParameter.ActualName;
     203      }
     204    }
     205
     206    #region Default Instance (myciel6.col)
     207    private static readonly int defaultInstanceNodes = 95;
     208    private static readonly Tuple<int, int>[] defaultInstance = {
     209Tuple.Create(1, 2),
     210Tuple.Create(1, 4),
     211Tuple.Create(1, 7),
     212Tuple.Create(1, 9),
     213Tuple.Create(1, 13),
     214Tuple.Create(1, 15),
     215Tuple.Create(1, 18),
     216Tuple.Create(1, 20),
     217Tuple.Create(1, 25),
     218Tuple.Create(1, 27),
     219Tuple.Create(1, 30),
     220Tuple.Create(1, 32),
     221Tuple.Create(1, 36),
     222Tuple.Create(1, 38),
     223Tuple.Create(1, 41),
     224Tuple.Create(1, 43),
     225Tuple.Create(1, 49),
     226Tuple.Create(1, 51),
     227Tuple.Create(1, 54),
     228Tuple.Create(1, 56),
     229Tuple.Create(1, 60),
     230Tuple.Create(1, 62),
     231Tuple.Create(1, 65),
     232Tuple.Create(1, 67),
     233Tuple.Create(1, 72),
     234Tuple.Create(1, 74),
     235Tuple.Create(1, 77),
     236Tuple.Create(1, 79),
     237Tuple.Create(1, 83),
     238Tuple.Create(1, 85),
     239Tuple.Create(1, 88),
     240Tuple.Create(1, 90),
     241Tuple.Create(2, 3),
     242Tuple.Create(2, 6),
     243Tuple.Create(2, 8),
     244Tuple.Create(2, 12),
     245Tuple.Create(2, 14),
     246Tuple.Create(2, 17),
     247Tuple.Create(2, 19),
     248Tuple.Create(2, 24),
     249Tuple.Create(2, 26),
     250Tuple.Create(2, 29),
     251Tuple.Create(2, 31),
     252Tuple.Create(2, 35),
     253Tuple.Create(2, 37),
     254Tuple.Create(2, 40),
     255Tuple.Create(2, 42),
     256Tuple.Create(2, 48),
     257Tuple.Create(2, 50),
     258Tuple.Create(2, 53),
     259Tuple.Create(2, 55),
     260Tuple.Create(2, 59),
     261Tuple.Create(2, 61),
     262Tuple.Create(2, 64),
     263Tuple.Create(2, 66),
     264Tuple.Create(2, 71),
     265Tuple.Create(2, 73),
     266Tuple.Create(2, 76),
     267Tuple.Create(2, 78),
     268Tuple.Create(2, 82),
     269Tuple.Create(2, 84),
     270Tuple.Create(2, 87),
     271Tuple.Create(2, 89),
     272Tuple.Create(3, 5),
     273Tuple.Create(3, 7),
     274Tuple.Create(3, 10),
     275Tuple.Create(3, 13),
     276Tuple.Create(3, 16),
     277Tuple.Create(3, 18),
     278Tuple.Create(3, 21),
     279Tuple.Create(3, 25),
     280Tuple.Create(3, 28),
     281Tuple.Create(3, 30),
     282Tuple.Create(3, 33),
     283Tuple.Create(3, 36),
     284Tuple.Create(3, 39),
     285Tuple.Create(3, 41),
     286Tuple.Create(3, 44),
     287Tuple.Create(3, 49),
     288Tuple.Create(3, 52),
     289Tuple.Create(3, 54),
     290Tuple.Create(3, 57),
     291Tuple.Create(3, 60),
     292Tuple.Create(3, 63),
     293Tuple.Create(3, 65),
     294Tuple.Create(3, 68),
     295Tuple.Create(3, 72),
     296Tuple.Create(3, 75),
     297Tuple.Create(3, 77),
     298Tuple.Create(3, 80),
     299Tuple.Create(3, 83),
     300Tuple.Create(3, 86),
     301Tuple.Create(3, 88),
     302Tuple.Create(3, 91),
     303Tuple.Create(4, 5),
     304Tuple.Create(4, 6),
     305Tuple.Create(4, 10),
     306Tuple.Create(4, 12),
     307Tuple.Create(4, 16),
     308Tuple.Create(4, 17),
     309Tuple.Create(4, 21),
     310Tuple.Create(4, 24),
     311Tuple.Create(4, 28),
     312Tuple.Create(4, 29),
     313Tuple.Create(4, 33),
     314Tuple.Create(4, 35),
     315Tuple.Create(4, 39),
     316Tuple.Create(4, 40),
     317Tuple.Create(4, 44),
     318Tuple.Create(4, 48),
     319Tuple.Create(4, 52),
     320Tuple.Create(4, 53),
     321Tuple.Create(4, 57),
     322Tuple.Create(4, 59),
     323Tuple.Create(4, 63),
     324Tuple.Create(4, 64),
     325Tuple.Create(4, 68),
     326Tuple.Create(4, 71),
     327Tuple.Create(4, 75),
     328Tuple.Create(4, 76),
     329Tuple.Create(4, 80),
     330Tuple.Create(4, 82),
     331Tuple.Create(4, 86),
     332Tuple.Create(4, 87),
     333Tuple.Create(4, 91),
     334Tuple.Create(5, 8),
     335Tuple.Create(5, 9),
     336Tuple.Create(5, 14),
     337Tuple.Create(5, 15),
     338Tuple.Create(5, 19),
     339Tuple.Create(5, 20),
     340Tuple.Create(5, 26),
     341Tuple.Create(5, 27),
     342Tuple.Create(5, 31),
     343Tuple.Create(5, 32),
     344Tuple.Create(5, 37),
     345Tuple.Create(5, 38),
     346Tuple.Create(5, 42),
     347Tuple.Create(5, 43),
     348Tuple.Create(5, 50),
     349Tuple.Create(5, 51),
     350Tuple.Create(5, 55),
     351Tuple.Create(5, 56),
     352Tuple.Create(5, 61),
     353Tuple.Create(5, 62),
     354Tuple.Create(5, 66),
     355Tuple.Create(5, 67),
     356Tuple.Create(5, 73),
     357Tuple.Create(5, 74),
     358Tuple.Create(5, 78),
     359Tuple.Create(5, 79),
     360Tuple.Create(5, 84),
     361Tuple.Create(5, 85),
     362Tuple.Create(5, 89),
     363Tuple.Create(5, 90),
     364Tuple.Create(6, 11),
     365Tuple.Create(6, 13),
     366Tuple.Create(6, 15),
     367Tuple.Create(6, 22),
     368Tuple.Create(6, 25),
     369Tuple.Create(6, 27),
     370Tuple.Create(6, 34),
     371Tuple.Create(6, 36),
     372Tuple.Create(6, 38),
     373Tuple.Create(6, 45),
     374Tuple.Create(6, 49),
     375Tuple.Create(6, 51),
     376Tuple.Create(6, 58),
     377Tuple.Create(6, 60),
     378Tuple.Create(6, 62),
     379Tuple.Create(6, 69),
     380Tuple.Create(6, 72),
     381Tuple.Create(6, 74),
     382Tuple.Create(6, 81),
     383Tuple.Create(6, 83),
     384Tuple.Create(6, 85),
     385Tuple.Create(6, 92),
     386Tuple.Create(7, 11),
     387Tuple.Create(7, 12),
     388Tuple.Create(7, 14),
     389Tuple.Create(7, 22),
     390Tuple.Create(7, 24),
     391Tuple.Create(7, 26),
     392Tuple.Create(7, 34),
     393Tuple.Create(7, 35),
     394Tuple.Create(7, 37),
     395Tuple.Create(7, 45),
     396Tuple.Create(7, 48),
     397Tuple.Create(7, 50),
     398Tuple.Create(7, 58),
     399Tuple.Create(7, 59),
     400Tuple.Create(7, 61),
     401Tuple.Create(7, 69),
     402Tuple.Create(7, 71),
     403Tuple.Create(7, 73),
     404Tuple.Create(7, 81),
     405Tuple.Create(7, 82),
     406Tuple.Create(7, 84),
     407Tuple.Create(7, 92),
     408Tuple.Create(8, 11),
     409Tuple.Create(8, 13),
     410Tuple.Create(8, 16),
     411Tuple.Create(8, 22),
     412Tuple.Create(8, 25),
     413Tuple.Create(8, 28),
     414Tuple.Create(8, 34),
     415Tuple.Create(8, 36),
     416Tuple.Create(8, 39),
     417Tuple.Create(8, 45),
     418Tuple.Create(8, 49),
     419Tuple.Create(8, 52),
     420Tuple.Create(8, 58),
     421Tuple.Create(8, 60),
     422Tuple.Create(8, 63),
     423Tuple.Create(8, 69),
     424Tuple.Create(8, 72),
     425Tuple.Create(8, 75),
     426Tuple.Create(8, 81),
     427Tuple.Create(8, 83),
     428Tuple.Create(8, 86),
     429Tuple.Create(8, 92),
     430Tuple.Create(9, 11),
     431Tuple.Create(9, 12),
     432Tuple.Create(9, 16),
     433Tuple.Create(9, 22),
     434Tuple.Create(9, 24),
     435Tuple.Create(9, 28),
     436Tuple.Create(9, 34),
     437Tuple.Create(9, 35),
     438Tuple.Create(9, 39),
     439Tuple.Create(9, 45),
     440Tuple.Create(9, 48),
     441Tuple.Create(9, 52),
     442Tuple.Create(9, 58),
     443Tuple.Create(9, 59),
     444Tuple.Create(9, 63),
     445Tuple.Create(9, 69),
     446Tuple.Create(9, 71),
     447Tuple.Create(9, 75),
     448Tuple.Create(9, 81),
     449Tuple.Create(9, 82),
     450Tuple.Create(9, 86),
     451Tuple.Create(9, 92),
     452Tuple.Create(10, 11),
     453Tuple.Create(10, 14),
     454Tuple.Create(10, 15),
     455Tuple.Create(10, 22),
     456Tuple.Create(10, 26),
     457Tuple.Create(10, 27),
     458Tuple.Create(10, 34),
     459Tuple.Create(10, 37),
     460Tuple.Create(10, 38),
     461Tuple.Create(10, 45),
     462Tuple.Create(10, 50),
     463Tuple.Create(10, 51),
     464Tuple.Create(10, 58),
     465Tuple.Create(10, 61),
     466Tuple.Create(10, 62),
     467Tuple.Create(10, 69),
     468Tuple.Create(10, 73),
     469Tuple.Create(10, 74),
     470Tuple.Create(10, 81),
     471Tuple.Create(10, 84),
     472Tuple.Create(10, 85),
     473Tuple.Create(10, 92),
     474Tuple.Create(11, 17),
     475Tuple.Create(11, 18),
     476Tuple.Create(11, 19),
     477Tuple.Create(11, 20),
     478Tuple.Create(11, 21),
     479Tuple.Create(11, 29),
     480Tuple.Create(11, 30),
     481Tuple.Create(11, 31),
     482Tuple.Create(11, 32),
     483Tuple.Create(11, 33),
     484Tuple.Create(11, 40),
     485Tuple.Create(11, 41),
     486Tuple.Create(11, 42),
     487Tuple.Create(11, 43),
     488Tuple.Create(11, 44),
     489Tuple.Create(11, 53),
     490Tuple.Create(11, 54),
     491Tuple.Create(11, 55),
     492Tuple.Create(11, 56),
     493Tuple.Create(11, 57),
     494Tuple.Create(11, 64),
     495Tuple.Create(11, 65),
     496Tuple.Create(11, 66),
     497Tuple.Create(11, 67),
     498Tuple.Create(11, 68),
     499Tuple.Create(11, 76),
     500Tuple.Create(11, 77),
     501Tuple.Create(11, 78),
     502Tuple.Create(11, 79),
     503Tuple.Create(11, 80),
     504Tuple.Create(11, 87),
     505Tuple.Create(11, 88),
     506Tuple.Create(11, 89),
     507Tuple.Create(11, 90),
     508Tuple.Create(11, 91),
     509Tuple.Create(12, 23),
     510Tuple.Create(12, 25),
     511Tuple.Create(12, 27),
     512Tuple.Create(12, 30),
     513Tuple.Create(12, 32),
     514Tuple.Create(12, 46),
     515Tuple.Create(12, 49),
     516Tuple.Create(12, 51),
     517Tuple.Create(12, 54),
     518Tuple.Create(12, 56),
     519Tuple.Create(12, 70),
     520Tuple.Create(12, 72),
     521Tuple.Create(12, 74),
     522Tuple.Create(12, 77),
     523Tuple.Create(12, 79),
     524Tuple.Create(12, 93),
     525Tuple.Create(13, 23),
     526Tuple.Create(13, 24),
     527Tuple.Create(13, 26),
     528Tuple.Create(13, 29),
     529Tuple.Create(13, 31),
     530Tuple.Create(13, 46),
     531Tuple.Create(13, 48),
     532Tuple.Create(13, 50),
     533Tuple.Create(13, 53),
     534Tuple.Create(13, 55),
     535Tuple.Create(13, 70),
     536Tuple.Create(13, 71),
     537Tuple.Create(13, 73),
     538Tuple.Create(13, 76),
     539Tuple.Create(13, 78),
     540Tuple.Create(13, 93),
     541Tuple.Create(14, 23),
     542Tuple.Create(14, 25),
     543Tuple.Create(14, 28),
     544Tuple.Create(14, 30),
     545Tuple.Create(14, 33),
     546Tuple.Create(14, 46),
     547Tuple.Create(14, 49),
     548Tuple.Create(14, 52),
     549Tuple.Create(14, 54),
     550Tuple.Create(14, 57),
     551Tuple.Create(14, 70),
     552Tuple.Create(14, 72),
     553Tuple.Create(14, 75),
     554Tuple.Create(14, 77),
     555Tuple.Create(14, 80),
     556Tuple.Create(14, 93),
     557Tuple.Create(15, 23),
     558Tuple.Create(15, 24),
     559Tuple.Create(15, 28),
     560Tuple.Create(15, 29),
     561Tuple.Create(15, 33),
     562Tuple.Create(15, 46),
     563Tuple.Create(15, 48),
     564Tuple.Create(15, 52),
     565Tuple.Create(15, 53),
     566Tuple.Create(15, 57),
     567Tuple.Create(15, 70),
     568Tuple.Create(15, 71),
     569Tuple.Create(15, 75),
     570Tuple.Create(15, 76),
     571Tuple.Create(15, 80),
     572Tuple.Create(15, 93),
     573Tuple.Create(16, 23),
     574Tuple.Create(16, 26),
     575Tuple.Create(16, 27),
     576Tuple.Create(16, 31),
     577Tuple.Create(16, 32),
     578Tuple.Create(16, 46),
     579Tuple.Create(16, 50),
     580Tuple.Create(16, 51),
     581Tuple.Create(16, 55),
     582Tuple.Create(16, 56),
     583Tuple.Create(16, 70),
     584Tuple.Create(16, 73),
     585Tuple.Create(16, 74),
     586Tuple.Create(16, 78),
     587Tuple.Create(16, 79),
     588Tuple.Create(16, 93),
     589Tuple.Create(17, 23),
     590Tuple.Create(17, 25),
     591Tuple.Create(17, 27),
     592Tuple.Create(17, 34),
     593Tuple.Create(17, 46),
     594Tuple.Create(17, 49),
     595Tuple.Create(17, 51),
     596Tuple.Create(17, 58),
     597Tuple.Create(17, 70),
     598Tuple.Create(17, 72),
     599Tuple.Create(17, 74),
     600Tuple.Create(17, 81),
     601Tuple.Create(17, 93),
     602Tuple.Create(18, 23),
     603Tuple.Create(18, 24),
     604Tuple.Create(18, 26),
     605Tuple.Create(18, 34),
     606Tuple.Create(18, 46),
     607Tuple.Create(18, 48),
     608Tuple.Create(18, 50),
     609Tuple.Create(18, 58),
     610Tuple.Create(18, 70),
     611Tuple.Create(18, 71),
     612Tuple.Create(18, 73),
     613Tuple.Create(18, 81),
     614Tuple.Create(18, 93),
     615Tuple.Create(19, 23),
     616Tuple.Create(19, 25),
     617Tuple.Create(19, 28),
     618Tuple.Create(19, 34),
     619Tuple.Create(19, 46),
     620Tuple.Create(19, 49),
     621Tuple.Create(19, 52),
     622Tuple.Create(19, 58),
     623Tuple.Create(19, 70),
     624Tuple.Create(19, 72),
     625Tuple.Create(19, 75),
     626Tuple.Create(19, 81),
     627Tuple.Create(19, 93),
     628Tuple.Create(20, 23),
     629Tuple.Create(20, 24),
     630Tuple.Create(20, 28),
     631Tuple.Create(20, 34),
     632Tuple.Create(20, 46),
     633Tuple.Create(20, 48),
     634Tuple.Create(20, 52),
     635Tuple.Create(20, 58),
     636Tuple.Create(20, 70),
     637Tuple.Create(20, 71),
     638Tuple.Create(20, 75),
     639Tuple.Create(20, 81),
     640Tuple.Create(20, 93),
     641Tuple.Create(21, 23),
     642Tuple.Create(21, 26),
     643Tuple.Create(21, 27),
     644Tuple.Create(21, 34),
     645Tuple.Create(21, 46),
     646Tuple.Create(21, 50),
     647Tuple.Create(21, 51),
     648Tuple.Create(21, 58),
     649Tuple.Create(21, 70),
     650Tuple.Create(21, 73),
     651Tuple.Create(21, 74),
     652Tuple.Create(21, 81),
     653Tuple.Create(21, 93),
     654Tuple.Create(22, 23),
     655Tuple.Create(22, 29),
     656Tuple.Create(22, 30),
     657Tuple.Create(22, 31),
     658Tuple.Create(22, 32),
     659Tuple.Create(22, 33),
     660Tuple.Create(22, 46),
     661Tuple.Create(22, 53),
     662Tuple.Create(22, 54),
     663Tuple.Create(22, 55),
     664Tuple.Create(22, 56),
     665Tuple.Create(22, 57),
     666Tuple.Create(22, 70),
     667Tuple.Create(22, 76),
     668Tuple.Create(22, 77),
     669Tuple.Create(22, 78),
     670Tuple.Create(22, 79),
     671Tuple.Create(22, 80),
     672Tuple.Create(22, 93),
     673Tuple.Create(23, 35),
     674Tuple.Create(23, 36),
     675Tuple.Create(23, 37),
     676Tuple.Create(23, 38),
     677Tuple.Create(23, 39),
     678Tuple.Create(23, 40),
     679Tuple.Create(23, 41),
     680Tuple.Create(23, 42),
     681Tuple.Create(23, 43),
     682Tuple.Create(23, 44),
     683Tuple.Create(23, 45),
     684Tuple.Create(23, 59),
     685Tuple.Create(23, 60),
     686Tuple.Create(23, 61),
     687Tuple.Create(23, 62),
     688Tuple.Create(23, 63),
     689Tuple.Create(23, 64),
     690Tuple.Create(23, 65),
     691Tuple.Create(23, 66),
     692Tuple.Create(23, 67),
     693Tuple.Create(23, 68),
     694Tuple.Create(23, 69),
     695Tuple.Create(23, 82),
     696Tuple.Create(23, 83),
     697Tuple.Create(23, 84),
     698Tuple.Create(23, 85),
     699Tuple.Create(23, 86),
     700Tuple.Create(23, 87),
     701Tuple.Create(23, 88),
     702Tuple.Create(23, 89),
     703Tuple.Create(23, 90),
     704Tuple.Create(23, 91),
     705Tuple.Create(23, 92),
     706Tuple.Create(24, 47),
     707Tuple.Create(24, 49),
     708Tuple.Create(24, 51),
     709Tuple.Create(24, 54),
     710Tuple.Create(24, 56),
     711Tuple.Create(24, 60),
     712Tuple.Create(24, 62),
     713Tuple.Create(24, 65),
     714Tuple.Create(24, 67),
     715Tuple.Create(24, 94),
     716Tuple.Create(25, 47),
     717Tuple.Create(25, 48),
     718Tuple.Create(25, 50),
     719Tuple.Create(25, 53),
     720Tuple.Create(25, 55),
     721Tuple.Create(25, 59),
     722Tuple.Create(25, 61),
     723Tuple.Create(25, 64),
     724Tuple.Create(25, 66),
     725Tuple.Create(25, 94),
     726Tuple.Create(26, 47),
     727Tuple.Create(26, 49),
     728Tuple.Create(26, 52),
     729Tuple.Create(26, 54),
     730Tuple.Create(26, 57),
     731Tuple.Create(26, 60),
     732Tuple.Create(26, 63),
     733Tuple.Create(26, 65),
     734Tuple.Create(26, 68),
     735Tuple.Create(26, 94),
     736Tuple.Create(27, 47),
     737Tuple.Create(27, 48),
     738Tuple.Create(27, 52),
     739Tuple.Create(27, 53),
     740Tuple.Create(27, 57),
     741Tuple.Create(27, 59),
     742Tuple.Create(27, 63),
     743Tuple.Create(27, 64),
     744Tuple.Create(27, 68),
     745Tuple.Create(27, 94),
     746Tuple.Create(28, 47),
     747Tuple.Create(28, 50),
     748Tuple.Create(28, 51),
     749Tuple.Create(28, 55),
     750Tuple.Create(28, 56),
     751Tuple.Create(28, 61),
     752Tuple.Create(28, 62),
     753Tuple.Create(28, 66),
     754Tuple.Create(28, 67),
     755Tuple.Create(28, 94),
     756Tuple.Create(29, 47),
     757Tuple.Create(29, 49),
     758Tuple.Create(29, 51),
     759Tuple.Create(29, 58),
     760Tuple.Create(29, 60),
     761Tuple.Create(29, 62),
     762Tuple.Create(29, 69),
     763Tuple.Create(29, 94),
     764Tuple.Create(30, 47),
     765Tuple.Create(30, 48),
     766Tuple.Create(30, 50),
     767Tuple.Create(30, 58),
     768Tuple.Create(30, 59),
     769Tuple.Create(30, 61),
     770Tuple.Create(30, 69),
     771Tuple.Create(30, 94),
     772Tuple.Create(31, 47),
     773Tuple.Create(31, 49),
     774Tuple.Create(31, 52),
     775Tuple.Create(31, 58),
     776Tuple.Create(31, 60),
     777Tuple.Create(31, 63),
     778Tuple.Create(31, 69),
     779Tuple.Create(31, 94),
     780Tuple.Create(32, 47),
     781Tuple.Create(32, 48),
     782Tuple.Create(32, 52),
     783Tuple.Create(32, 58),
     784Tuple.Create(32, 59),
     785Tuple.Create(32, 63),
     786Tuple.Create(32, 69),
     787Tuple.Create(32, 94),
     788Tuple.Create(33, 47),
     789Tuple.Create(33, 50),
     790Tuple.Create(33, 51),
     791Tuple.Create(33, 58),
     792Tuple.Create(33, 61),
     793Tuple.Create(33, 62),
     794Tuple.Create(33, 69),
     795Tuple.Create(33, 94),
     796Tuple.Create(34, 47),
     797Tuple.Create(34, 53),
     798Tuple.Create(34, 54),
     799Tuple.Create(34, 55),
     800Tuple.Create(34, 56),
     801Tuple.Create(34, 57),
     802Tuple.Create(34, 64),
     803Tuple.Create(34, 65),
     804Tuple.Create(34, 66),
     805Tuple.Create(34, 67),
     806Tuple.Create(34, 68),
     807Tuple.Create(34, 94),
     808Tuple.Create(35, 47),
     809Tuple.Create(35, 49),
     810Tuple.Create(35, 51),
     811Tuple.Create(35, 54),
     812Tuple.Create(35, 56),
     813Tuple.Create(35, 70),
     814Tuple.Create(35, 94),
     815Tuple.Create(36, 47),
     816Tuple.Create(36, 48),
     817Tuple.Create(36, 50),
     818Tuple.Create(36, 53),
     819Tuple.Create(36, 55),
     820Tuple.Create(36, 70),
     821Tuple.Create(36, 94),
     822Tuple.Create(37, 47),
     823Tuple.Create(37, 49),
     824Tuple.Create(37, 52),
     825Tuple.Create(37, 54),
     826Tuple.Create(37, 57),
     827Tuple.Create(37, 70),
     828Tuple.Create(37, 94),
     829Tuple.Create(38, 47),
     830Tuple.Create(38, 48),
     831Tuple.Create(38, 52),
     832Tuple.Create(38, 53),
     833Tuple.Create(38, 57),
     834Tuple.Create(38, 70),
     835Tuple.Create(38, 94),
     836Tuple.Create(39, 47),
     837Tuple.Create(39, 50),
     838Tuple.Create(39, 51),
     839Tuple.Create(39, 55),
     840Tuple.Create(39, 56),
     841Tuple.Create(39, 70),
     842Tuple.Create(39, 94),
     843Tuple.Create(40, 47),
     844Tuple.Create(40, 49),
     845Tuple.Create(40, 51),
     846Tuple.Create(40, 58),
     847Tuple.Create(40, 70),
     848Tuple.Create(40, 94),
     849Tuple.Create(41, 47),
     850Tuple.Create(41, 48),
     851Tuple.Create(41, 50),
     852Tuple.Create(41, 58),
     853Tuple.Create(41, 70),
     854Tuple.Create(41, 94),
     855Tuple.Create(42, 47),
     856Tuple.Create(42, 49),
     857Tuple.Create(42, 52),
     858Tuple.Create(42, 58),
     859Tuple.Create(42, 70),
     860Tuple.Create(42, 94),
     861Tuple.Create(43, 47),
     862Tuple.Create(43, 48),
     863Tuple.Create(43, 52),
     864Tuple.Create(43, 58),
     865Tuple.Create(43, 70),
     866Tuple.Create(43, 94),
     867Tuple.Create(44, 47),
     868Tuple.Create(44, 50),
     869Tuple.Create(44, 51),
     870Tuple.Create(44, 58),
     871Tuple.Create(44, 70),
     872Tuple.Create(44, 94),
     873Tuple.Create(45, 47),
     874Tuple.Create(45, 53),
     875Tuple.Create(45, 54),
     876Tuple.Create(45, 55),
     877Tuple.Create(45, 56),
     878Tuple.Create(45, 57),
     879Tuple.Create(45, 70),
     880Tuple.Create(45, 94),
     881Tuple.Create(46, 47),
     882Tuple.Create(46, 59),
     883Tuple.Create(46, 60),
     884Tuple.Create(46, 61),
     885Tuple.Create(46, 62),
     886Tuple.Create(46, 63),
     887Tuple.Create(46, 64),
     888Tuple.Create(46, 65),
     889Tuple.Create(46, 66),
     890Tuple.Create(46, 67),
     891Tuple.Create(46, 68),
     892Tuple.Create(46, 69),
     893Tuple.Create(46, 94),
     894Tuple.Create(47, 71),
     895Tuple.Create(47, 72),
     896Tuple.Create(47, 73),
     897Tuple.Create(47, 74),
     898Tuple.Create(47, 75),
     899Tuple.Create(47, 76),
     900Tuple.Create(47, 77),
     901Tuple.Create(47, 78),
     902Tuple.Create(47, 79),
     903Tuple.Create(47, 80),
     904Tuple.Create(47, 81),
     905Tuple.Create(47, 82),
     906Tuple.Create(47, 83),
     907Tuple.Create(47, 84),
     908Tuple.Create(47, 85),
     909Tuple.Create(47, 86),
     910Tuple.Create(47, 87),
     911Tuple.Create(47, 88),
     912Tuple.Create(47, 89),
     913Tuple.Create(47, 90),
     914Tuple.Create(47, 91),
     915Tuple.Create(47, 92),
     916Tuple.Create(47, 93),
     917Tuple.Create(48, 95),
     918Tuple.Create(49, 95),
     919Tuple.Create(50, 95),
     920Tuple.Create(51, 95),
     921Tuple.Create(52, 95),
     922Tuple.Create(53, 95),
     923Tuple.Create(54, 95),
     924Tuple.Create(55, 95),
     925Tuple.Create(56, 95),
     926Tuple.Create(57, 95),
     927Tuple.Create(58, 95),
     928Tuple.Create(59, 95),
     929Tuple.Create(60, 95),
     930Tuple.Create(61, 95),
     931Tuple.Create(62, 95),
     932Tuple.Create(63, 95),
     933Tuple.Create(64, 95),
     934Tuple.Create(65, 95),
     935Tuple.Create(66, 95),
     936Tuple.Create(67, 95),
     937Tuple.Create(68, 95),
     938Tuple.Create(69, 95),
     939Tuple.Create(70, 95),
     940Tuple.Create(71, 95),
     941Tuple.Create(72, 95),
     942Tuple.Create(73, 95),
     943Tuple.Create(74, 95),
     944Tuple.Create(75, 95),
     945Tuple.Create(76, 95),
     946Tuple.Create(77, 95),
     947Tuple.Create(78, 95),
     948Tuple.Create(79, 95),
     949Tuple.Create(80, 95),
     950Tuple.Create(81, 95),
     951Tuple.Create(82, 95),
     952Tuple.Create(83, 95),
     953Tuple.Create(84, 95),
     954Tuple.Create(85, 95),
     955Tuple.Create(86, 95),
     956Tuple.Create(87, 95),
     957Tuple.Create(88, 95),
     958Tuple.Create(89, 95),
     959Tuple.Create(90, 95),
     960Tuple.Create(91, 95),
     961Tuple.Create(92, 95),
     962Tuple.Create(93, 95),
     963Tuple.Create(94, 95)
     964    };
     965    #endregion
    88966  }
    89967}
  • branches/MemPRAlgorithm/HeuristicLab.Problems.GraphColoring/3.3/HeuristicLab.Problems.GraphColoring-3.3.csproj

    r14466 r14471  
    5858  </ItemGroup>
    5959  <ItemGroup>
     60    <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj">
     61      <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project>
     62      <Name>HeuristicLab.Analysis-3.3</Name>
     63      <Private>False</Private>
     64    </ProjectReference>
    6065    <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj">
    6166      <Project>{958b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>
     
    9196      <Project>{23da7ff4-d5b8-41b6-aa96-f0561d24f3ee}</Project>
    9297      <Name>HeuristicLab.Operators-3.3</Name>
     98      <Private>False</Private>
     99    </ProjectReference>
     100    <ProjectReference Include="..\..\HeuristicLab.Optimization.Operators\3.3\HeuristicLab.Optimization.Operators-3.3.csproj">
     101      <Project>{25087811-f74c-4128-bc86-8324271da13e}</Project>
     102      <Name>HeuristicLab.Optimization.Operators-3.3</Name>
    93103      <Private>False</Private>
    94104    </ProjectReference>
  • branches/MemPRAlgorithm/HeuristicLab.Problems.GraphColoring/3.3/Plugin.cs.frame

    r14466 r14471  
    2525  [Plugin("HeuristicLab.Problems.GraphColoring", "3.3.14.$WCREV$")]
    2626  [PluginFile("HeuristicLab.Problems.GraphColoring-3.3.dll", PluginFileType.Assembly)]
     27  [PluginDependency("HeuristicLab.Analysis", "3.3")]
    2728  [PluginDependency("HeuristicLab.Collections", "3.3")]
    2829  [PluginDependency("HeuristicLab.Common", "3.3")]
     
    3334  [PluginDependency("HeuristicLab.Operators", "3.3")]
    3435  [PluginDependency("HeuristicLab.Optimization", "3.3")]
     36  [PluginDependency("HeuristicLab.Optimization.Operators", "3.3")]
    3537  [PluginDependency("HeuristicLab.Parameters", "3.3")]
     38  [PluginDependency("HeuristicLab.Problems.Instances", "3.3")]
    3639  [PluginDependency("HeuristicLab.Persistence", "3.3")]
    3740  public class HeuristicLabProblemsGraphColoringPlugin : PluginBase {
  • branches/MemPRAlgorithm/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolDataDescriptor.cs

    r14429 r14471  
    2020#endregion
    2121
    22 namespace HeuristicLab.Problems.Instances.QAPLIB {
    23   internal class QAPLIBDataDescriptor : IDataDescriptor {
     22namespace HeuristicLab.Problems.Instances.DIMACS {
     23  internal class GcolDataDescriptor : IDataDescriptor {
    2424    public string Name { get; internal set; }
    2525    public string Description { get; internal set; }
    2626
    2727    internal string InstanceIdentifier { get; set; }
    28     internal string SolutionIdentifier { get; set; }
    2928
    30     internal QAPLIBDataDescriptor(string name, string description, string instanceIdentifier, string solutionIdentifier) {
     29    internal GcolDataDescriptor(string name, string description, string instanceIdentifier) {
    3130      this.Name = name;
    3231      this.Description = description;
    3332      this.InstanceIdentifier = instanceIdentifier;
    34       this.SolutionIdentifier = solutionIdentifier;
    3533    }
    3634  }
  • branches/MemPRAlgorithm/HeuristicLab.Problems.Instances.DIMACS/3.3/GcolInstanceProvider.cs

    r14429 r14471  
    2828using System.Text.RegularExpressions;
    2929
    30 namespace HeuristicLab.Problems.Instances.QAPLIB {
    31   public class QAPLIBInstanceProvider : ProblemInstanceProvider<QAPData> {
    32     #region Reversed instances
    33     // These instances specified their best known solution in the wrong order
    34     protected virtual HashSet<string> ReversedSolutions {
    35       get {
    36         return new HashSet<string>(new string[] {
    37               "bur26a",
    38               "bur26b",
    39               "bur26c",
    40               "bur26d",
    41               "bur26e",
    42               "bur26f",
    43               "bur26g",
    44               "bur26h",
    45               "chr12a",
    46               "chr12b",
    47               "chr12c",
    48               "chr15a",
    49               "chr15b",
    50               "chr15c",
    51               "chr18a",
    52               "chr18b",
    53               "chr20a",
    54               "chr20b",
    55               "chr20c",
    56               "chr22a",
    57               "chr22b",
    58               "chr25a",
    59               "esc16a",
    60               "esc16b",
    61               "esc16c",
    62               "esc16d",
    63               "esc16e",
    64               "esc16g",
    65               "esc16h",
    66               "esc16i",
    67               "esc16j",
    68               "esc32a",
    69               "esc32b",
    70               "esc32c",
    71               "esc32d",
    72               "esc32e",
    73               "esc32f",
    74               "esc32g",
    75               "esc32h",
    76               "had12",
    77               "had14",
    78               "had16",
    79               "had18",
    80               "had20",
    81               "kra32",
    82               "lipa20a",
    83               "lipa30a",
    84               "lipa40a",
    85               "lipa50a",
    86               "lipa60a",
    87               "lipa70a",
    88               "lipa80a",
    89               "lipa90a",
    90               "nug12",
    91               "nug14",
    92               "nug15",
    93               "nug16a",
    94               "nug16b",
    95               "nug17",
    96               "nug18",
    97               "nug20",
    98               "nug21",
    99               "nug22",
    100               "nug24",
    101               "nug25",
    102               "nug27",
    103               "nug28",
    104               "rou12",
    105               "rou15",
    106               "rou20",
    107               "scr12",
    108               "scr15",
    109               "scr20",
    110               "sko100a",
    111               "sko100b",
    112               "sko100c",
    113               "sko100d",
    114               "sko100e",
    115               "sko100f",
    116               "sko49",
    117               "sko81",
    118               "sko90",
    119               "ste36a",
    120               "ste36b",
    121               "tai100a",
    122               "tai100b",
    123               "tai12a",
    124               "tai12b",
    125               "tai150b",
    126               "tai15a",
    127               "tai15b",
    128               "tai17a",
    129               "tai20a",
    130               "tai20b",
    131               "tai256c",
    132               "tai25a",
    133               "tai25b",
    134               "tai30a",
    135               "tai30b",
    136               "tai35a",
    137               "tai35b",
    138               "tai40a",
    139               "tai40b",
    140               "tai50a",
    141               "tai50b",
    142               "tai60a",
    143               "tai60b",
    144               "tai64c",
    145               "tai80a",
    146               "tai80b",
    147               "wil100"
    148         });
    149       }
    150     }
    151     #endregion
     30namespace HeuristicLab.Problems.Instances.DIMACS {
     31  public class GcolInstanceProvider : ProblemInstanceProvider<GCPData> {
    15232
    15333    public override string Name {
    154       get { return "QAPLIB"; }
     34      get { return "DIMACS Graph Coloring"; }
    15535    }
    15636
    15737    public override string Description {
    158       get { return "Quadratic Assignment Problem Library"; }
     38      get { return "Graph Coloring problem instance library"; }
    15939    }
    16040
    16141    public override Uri WebLink {
    162       get { return new Uri("http://www.seas.upenn.edu/qaplib/"); }
     42      get { return new Uri("https://turing.cs.hbg.psu.edu/txn131/graphcoloring.html"); }
    16343    }
    16444
    16545    public override string ReferencePublication {
    16646      get {
    167         return @"R. E. Burkard, S. E. Karisch, and F. Rendl. 1997.
    168 QAPLIB - A Quadratic Assignment Problem Library.
    169 Journal of Global Optimization, 10, pp. 391-403.";
     47        return string.Empty;
    17048      }
    17149    }
    17250
    173     protected virtual string FileName { get { return "qap"; } }
     51    protected virtual string FileName { get { return "col"; } }
    17452
    17553    public override IEnumerable<IDataDescriptor> GetDataDescriptors() {
    176       Dictionary<string, string> solutions = new Dictionary<string, string>();
    177       var solutionsArchiveName = GetResourceName(FileName + @"\.sln\.zip");
    178       if (!String.IsNullOrEmpty(solutionsArchiveName)) {
    179         using (var solutionsZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(solutionsArchiveName), ZipArchiveMode.Read)) {
    180           foreach (var entry in solutionsZipFile.Entries)
    181             solutions.Add(Path.GetFileNameWithoutExtension(entry.Name) + ".dat", entry.Name);
    182         }
    183       }
    184       var instanceArchiveName = GetResourceName(FileName + @"\.dat\.zip");
     54      var instanceArchiveName = GetResourceName(FileName + @"\.zip");
    18555      if (String.IsNullOrEmpty(instanceArchiveName)) yield break;
    18656
    18757      using (var instanceStream = new ZipArchive(GetType().Assembly.GetManifestResourceStream(instanceArchiveName), ZipArchiveMode.Read)) {
    18858        foreach (var entry in instanceStream.Entries.Select(x => x.Name).OrderBy(x => x)) {
    189           yield return new QAPLIBDataDescriptor(Path.GetFileNameWithoutExtension(entry), GetDescription(), entry, solutions.ContainsKey(entry) ? solutions[entry] : String.Empty);
     59          yield return new GcolDataDescriptor(Path.GetFileNameWithoutExtension(entry), GetDescription(), entry);
    19060        }
    19161      }
    19262    }
    19363
    194     public override QAPData LoadData(IDataDescriptor id) {
    195       var descriptor = (QAPLIBDataDescriptor)id;
    196       var instanceArchiveName = GetResourceName(FileName + @"\.dat\.zip");
     64    public override GCPData LoadData(IDataDescriptor id) {
     65      var descriptor = (GcolDataDescriptor)id;
     66      var instanceArchiveName = GetResourceName(FileName + @"\.zip");
    19767      using (var instancesZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(instanceArchiveName), ZipArchiveMode.Read)) {
    19868        var entry = instancesZipFile.GetEntry(descriptor.InstanceIdentifier);
    19969
    20070        using (var stream = entry.Open()) {
    201           var parser = new QAPLIBParser();
     71          var parser = new Parser();
    20272          parser.Parse(stream);
    20373          var instance = Load(parser);
    20474          instance.Name = id.Name;
    20575          instance.Description = id.Description;
    206 
    207           if (!String.IsNullOrEmpty(descriptor.SolutionIdentifier)) {
    208             var solutionsArchiveName = GetResourceName(FileName + @"\.sln\.zip");
    209             using (var solutionsZipFile = new ZipArchive(GetType().Assembly.GetManifestResourceStream(solutionsArchiveName), ZipArchiveMode.Read)) {
    210               entry = solutionsZipFile.GetEntry(descriptor.SolutionIdentifier);
    211               using (var solStream = entry.Open()) {
    212                 var slnParser = new QAPLIBSolutionParser();
    213                 slnParser.Parse(solStream, true);
    214                 if (slnParser.Error != null) throw slnParser.Error;
    215 
    216                 int[] assignment = slnParser.Assignment;
    217                 if (assignment != null && ReversedSolutions.Contains(instance.Name)) {
    218                   assignment = (int[])slnParser.Assignment.Clone();
    219                   for (int i = 0; i < assignment.Length; i++)
    220                     assignment[slnParser.Assignment[i]] = i;
    221                 }
    222                 instance.BestKnownAssignment = assignment;
    223                 instance.BestKnownQuality = slnParser.Quality;
    224               }
    225             }
    226           }
     76          int bestknown;
     77          if (bkq.TryGetValue(instance.Name, out bestknown))
     78            instance.BestKnownColors = bestknown;
    22779          return instance;
    22880        }
     
    23385      get { return true; }
    23486    }
    235     public override QAPData ImportData(string path) {
    236       var parser = new QAPLIBParser();
     87    public override GCPData ImportData(string path) {
     88      var parser = new Parser();
    23789      parser.Parse(path);
    23890      var instance = Load(parser);
     
    24294    }
    24395
    244     private QAPData Load(QAPLIBParser parser) {
    245       var instance = new QAPData();
    246       instance.Dimension = parser.Size;
    247       instance.Distances = parser.Distances;
    248       instance.Weights = parser.Weights;
     96    private GCPData Load(Parser parser) {
     97      var instance = new GCPData();
     98      instance.Nodes = parser.Nodes;
     99      var adjacencies = new int[parser.Edges, 2];
     100      var i = 0;
     101      foreach (var a in parser.AdjacencyList) {
     102        adjacencies[i, 0] = a.Item1 - 1;
     103        adjacencies[i, 1] = a.Item2 - 1;
     104        i++;
     105      }
     106      instance.Adjacencies = adjacencies;
    249107      return instance;
    250108    }
     
    258116              .Where(x => Regex.Match(x, @".*\.Data\." + fileName).Success).SingleOrDefault();
    259117    }
     118
     119    private Dictionary<string, int> bkq = new Dictionary<string, int> {
     120      { "fpsol2.i.1", 65 },
     121      { "fpsol2.i.2", 30 },
     122      { "fpsol2.i.3", 30 },
     123      { "inithx.i.1", 54 },
     124      { "inithx.i.2", 31 },
     125      { "inithx.i.3", 31 },
     126      { "le450_5a", 5 },
     127      { "le450_5b", 5 },
     128      { "le450_5c", 5 },
     129      { "le450_5d", 5 },
     130      { "le450_15a", 15 },
     131      { "le450_15b", 15 },
     132      { "le450_15c", 15 },
     133      { "le450_15d", 15 },
     134      { "le450_25a", 25 },
     135      { "le450_25b", 25 },
     136      { "le450_25c", 25 },
     137      { "le450_25d", 25 },
     138      { "mulsol.i.1", 49 },
     139      { "mulsol.i.2", 31 },
     140      { "mulsol.i.3", 31 },
     141      { "mulsol.i.4", 31 },
     142      { "mulsol.i.5", 31 },
     143      { "zeroin.i.1", 49 },
     144      { "zeroin.i.2", 30 },
     145      { "zeroin.i.3", 30 },
     146      { "anna", 11 },
     147      { "david", 11 },
     148      { "homer", 13 },
     149      { "huck", 11 },
     150      { "jean", 10 },
     151      { "games120", 9 },
     152      { "miles250", 8 },
     153      { "miles500", 20 },
     154      { "miles750", 31 },
     155      { "miles1000", 42 },
     156      { "miles1500", 73 },
     157      { "queen5_5", 5 },
     158      { "queen6_6", 7 },
     159      { "queen7_7", 7 },
     160      { "queen8_8", 9 },
     161      { "queen8_12", 12 },
     162      { "queen9_9", 10 },
     163      { "queen11_11", 11 },
     164      { "queen13_13", 13 },
     165      { "myciel3", 4 },
     166      { "myciel4", 5 },
     167      { "myciel5", 6 },
     168      { "myciel6", 7 },
     169      { "myciel7", 8 },
     170      { "mugg88_1", 4 },
     171      { "mugg88_25", 4 },
     172      { "mugg100_1", 4 },
     173      { "mugg100_25", 4 },
     174      { "1-Insertions_4", 4 },
     175      { "2-Insertions_3", 4 },
     176      { "2-Insertions_4", 4 },
     177      { "3-Insertions_3", 4 },
     178      { "4-Insertions_3", 3 },
     179      { "qg.order30", 30 },
     180      { "qg.order40", 40 },
     181      { "qg.order60", 60 },
     182      { "qg.order100", 100 }
     183    };
    260184  }
    261185}
  • branches/MemPRAlgorithm/HeuristicLab.Problems.Instances.DIMACS/3.3/Parser.cs

    r14429 r14471  
    2121
    2222using System;
     23using System.Collections.Generic;
    2324using System.IO;
    2425
    25 namespace HeuristicLab.Problems.Instances.QAPLIB {
    26   public class QAPLIBParser {
    27     public int Size { get; private set; }
    28     public double[,] Distances { get; private set; }
    29     public double[,] Weights { get; private set; }
     26namespace HeuristicLab.Problems.Instances.DIMACS {
     27  public class Parser {
     28    public int Nodes { get; private set; }
     29    public int Edges { get; private set; }
     30    public ICollection<Tuple<int, int>> AdjacencyList { get { return edges; } }
     31    private HashSet<Tuple<int, int>> edges;
    3032
    31     public QAPLIBParser() {
     33    public Parser() {
    3234      Reset();
    3335    }
    3436
    3537    public void Reset() {
    36       Size = 0;
    37       Distances = null;
    38       Weights = null;
     38      Nodes = 0;
     39      Edges = 0;
     40      edges = new HashSet<Tuple<int, int>>();
    3941    }
    4042
     
    5456    /// <returns>True if the file was successfully read or false otherwise.</returns>
    5557    public void Parse(Stream stream) {
     58      char[] delim = new char[] { ' ', '\t' };
    5659      var reader = new StreamReader(stream);
    57       Size = int.Parse(reader.ReadLine());
    58       Distances = new double[Size, Size];
    59       Weights = new double[Size, Size];
    60       char[] delim = new char[] { ' ', '\t' };
     60      var line = reader.ReadLine().Trim();
     61      // skip comments
     62      while (line.StartsWith("c", StringComparison.InvariantCultureIgnoreCase)) line = reader.ReadLine().Trim();
    6163
    62       Weights = ParseMatrix(reader, delim);
    63       Distances = ParseMatrix(reader, delim);
    64     }
    65 
    66     private double[,] ParseMatrix(StreamReader reader, char[] delim) {
    67       int read = 0, k = 0;
    68       double[,] result = new double[Size, Size];
    69       while (k < Size) {
    70         if (reader.EndOfStream) throw new InvalidDataException("Reached end of stream while reading second matrix.");
    71         string valLine = reader.ReadLine();
    72         while (String.IsNullOrWhiteSpace(valLine)) valLine = reader.ReadLine();
    73         string[] vals = valLine.Split(delim, StringSplitOptions.RemoveEmptyEntries);
    74         foreach (string val in vals) {
    75           result[k, read++] = double.Parse(val);
    76           if (read == Size) {
    77             read = 0;
    78             k++;
    79           }
    80         }
    81       }
    82       return result;
     64      // p edge NODES EDGES
     65      var split = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
     66      Nodes = int.Parse(split[2]);
     67      do {
     68        line = reader.ReadLine();
     69        if (string.IsNullOrEmpty(line)) break;
     70        // e XX YY
     71        split = line.Split(delim, StringSplitOptions.RemoveEmptyEntries);
     72        var src = int.Parse(split[1]);
     73        var tgt = int.Parse(split[2]);
     74        Tuple<int, int> e = null;
     75        if (src < tgt) e = Tuple.Create(src, tgt);
     76        else if (src > tgt) e = Tuple.Create(tgt, src);
     77        else continue; // src == tgt
     78        if (edges.Add(e)) Edges++;
     79      } while (!reader.EndOfStream);
    8380    }
    8481  }
  • branches/MemPRAlgorithm/HeuristicLab.Problems.Instances/3.3/HeuristicLab.Problems.Instances-3.3.csproj

    r13484 r14471  
    128128    <Compile Include="Types\DistanceHelper.cs" />
    129129    <Compile Include="Types\OPData.cs" />
     130    <Compile Include="Types\GCPData.cs" />
    130131    <Compile Include="Types\VRP\MDCVRPTWData.cs" />
    131132    <Compile Include="Types\VRP\MDCVRPData.cs" />
  • branches/MemPRAlgorithm/HeuristicLab.Problems.Instances/3.3/Types/GCPData.cs

    r14429 r14471  
    2222namespace HeuristicLab.Problems.Instances {
    2323  /// <summary>
    24   /// Describes instances of the Quadratic Assignment Problem (QAP).
     24  /// Describes instances of the graph coloring problem (GCP).
    2525  /// </summary>
    26   public class QAPData {
     26  public class GCPData {
    2727    /// <summary>
    2828    /// The name of the instance
     
    3535
    3636    /// <summary>
    37     /// The number of facilities (and also the number of locations)
     37    /// The number of nodes in the graph
    3838    /// </summary>
    39     public int Dimension { get; set; }
     39    public int Nodes { get; set; }
    4040    /// <summary>
    41     /// An NxN Matrix with N = |Faciliies|
     41    /// An Nx2 adjacency list with N = Nodes
    4242    /// </summary>
    43     public double[,] Distances { get; set; }
    44     /// <summary>
    45     /// An NxN Matrix with N = |Faciliies|
    46     /// </summary>
    47     public double[,] Weights { get; set; }
     43    public int[,] Adjacencies { get; set; }
    4844
    4945    /// <summary>
    50     /// Optional! An array of length N with N = |Facilities|
     46    /// Optional! An array of length N with N = |Nodes|
    5147    /// </summary>
    52     public int[] BestKnownAssignment { get; set; }
     48    public int[] BestKnownColoring { get; set; }
    5349    /// <summary>
    54     /// Optional! The quality value of the <see cref="BestKnownAssignment"/>
     50    /// Optional! The quality value of the <see cref="BestKnownColoring"/>
    5551    /// </summary>
    56     public double? BestKnownQuality { get; set; }
     52    public double? BestKnownColors { get; set; }
    5753  }
    5854}
Note: See TracChangeset for help on using the changeset viewer.