[17248] | 1 | #region License Information
|
---|
| 2 | /* HeuristicLab
|
---|
| 3 | * Copyright (C) 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;
|
---|
[17525] | 23 | using System.Collections.Generic;
|
---|
[17239] | 24 | using HEAL.Attic;
|
---|
| 25 | using HeuristicLab.Common;
|
---|
| 26 | using HeuristicLab.Core;
|
---|
| 27 | using HeuristicLab.Data;
|
---|
[17241] | 28 | using HeuristicLab.Encodings.PermutationEncoding;
|
---|
[17251] | 29 | using HeuristicLab.Problems.Instances;
|
---|
[17239] | 30 |
|
---|
| 31 | namespace HeuristicLab.Problems.TravelingSalesman {
|
---|
| 32 | [StorableType("1a9bf60c-b6a6-4c95-8e99-5a2dec0ee892")]
|
---|
[17251] | 33 | public interface ITSPData : INamedItem {
|
---|
[17253] | 34 | int Cities { get; }
|
---|
| 35 |
|
---|
[17239] | 36 | double GetDistance(int fromCity, int toCity);
|
---|
[17525] | 37 | double GetPathDistance(IEnumerable<int> path, bool closed = true);
|
---|
[17241] | 38 | ITSPSolution GetSolution(Permutation tspTour, double tourLength);
|
---|
[17251] | 39 | TSPData Export();
|
---|
[17239] | 40 | }
|
---|
| 41 |
|
---|
| 42 | [Item("Matrix-based TSP Data", "TSP that is representd by a distance matrix.")]
|
---|
| 43 | [StorableType("4df58a35-679d-4414-b815-9450ae100823")]
|
---|
[17335] | 44 | public sealed class MatrixTSPData : NamedItem, ITSPData {
|
---|
| 45 | [Storable] public DoubleMatrix Matrix { get; private set; }
|
---|
| 46 | [Storable] public DoubleMatrix DisplayCoordinates { get; private set; }
|
---|
[17248] | 47 |
|
---|
[17253] | 48 | public int Cities => Matrix.Rows;
|
---|
| 49 |
|
---|
[17239] | 50 | [StorableConstructor]
|
---|
[17335] | 51 | private MatrixTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 52 | private MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {
|
---|
[17239] | 53 | Matrix = original.Matrix;
|
---|
[17251] | 54 | DisplayCoordinates = original.DisplayCoordinates;
|
---|
[17239] | 55 | }
|
---|
| 56 | public MatrixTSPData() {
|
---|
[17251] | 57 | Name = TSPDefaultInstance.Name;
|
---|
| 58 | Matrix = TSPDefaultInstance.Distances;
|
---|
| 59 | DisplayCoordinates = TSPDefaultInstance.Coordinates;
|
---|
[17239] | 60 | }
|
---|
[17251] | 61 | public MatrixTSPData(string name, double[,] matrix, double[,] coordinates = null) {
|
---|
| 62 | if (coordinates != null && coordinates.GetLength(1) != 2)
|
---|
| 63 | throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
|
---|
| 64 | if (coordinates != null && coordinates.GetLength(0) != matrix.GetLength(0))
|
---|
| 65 | throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
|
---|
| 66 | Name = name;
|
---|
[17248] | 67 | Matrix = new DoubleMatrix(matrix, @readonly: true);
|
---|
[17251] | 68 | if (coordinates != null) DisplayCoordinates = new DoubleMatrix(coordinates, @readonly: true);
|
---|
| 69 | }
|
---|
| 70 | public MatrixTSPData(string name, DoubleMatrix matrix, DoubleMatrix coordinates = null) {
|
---|
| 71 | if (coordinates != null && coordinates.Columns != 2)
|
---|
[17239] | 72 | throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
|
---|
[17251] | 73 | if (coordinates != null && coordinates.Rows != matrix.Rows)
|
---|
[17239] | 74 | throw new ArgumentException("Unequal number of rows in " + nameof(matrix) + " and " + nameof(coordinates) + ".");
|
---|
[17251] | 75 | Name = name;
|
---|
[17253] | 76 | Matrix = matrix.AsReadOnly();
|
---|
| 77 | DisplayCoordinates = coordinates?.AsReadOnly();
|
---|
[17239] | 78 | }
|
---|
| 79 |
|
---|
[17335] | 80 | public ITSPSolution GetSolution(Permutation tour, double tourLength) {
|
---|
| 81 | return new TSPSolution(this, tour, new DoubleValue(tourLength));
|
---|
[17241] | 82 | }
|
---|
| 83 |
|
---|
[17239] | 84 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 85 | return new MatrixTSPData(this, cloner);
|
---|
| 86 | }
|
---|
| 87 |
|
---|
| 88 | public double GetDistance(int fromCity, int toCity) => Matrix[fromCity, toCity];
|
---|
[17525] | 89 | public double GetPathDistance(IEnumerable<int> path, bool closed = true) {
|
---|
| 90 | var iter = path.GetEnumerator();
|
---|
| 91 | if (!iter.MoveNext()) return 0;
|
---|
| 92 | var start = iter.Current;
|
---|
| 93 | var prev = start;
|
---|
| 94 | var distance = 0.0;
|
---|
| 95 | while (iter.MoveNext()) {
|
---|
| 96 | var cur = iter.Current;
|
---|
| 97 | distance += Matrix[prev, cur];
|
---|
| 98 | prev = cur;
|
---|
| 99 | }
|
---|
| 100 | if (closed) distance += Matrix[prev, start];
|
---|
| 101 | return distance;
|
---|
| 102 | }
|
---|
[17251] | 103 | public TSPData Export() {
|
---|
| 104 | return new TSPData() {
|
---|
| 105 | Name = name,
|
---|
| 106 | Description = description,
|
---|
| 107 | Coordinates = DisplayCoordinates?.CloneAsMatrix(),
|
---|
| 108 | Dimension = Matrix.Rows,
|
---|
| 109 | DistanceMeasure = DistanceMeasure.Direct,
|
---|
| 110 | Distances = Matrix.CloneAsMatrix()
|
---|
| 111 | };
|
---|
[17248] | 112 | }
|
---|
[17239] | 113 | }
|
---|
[17241] | 114 |
|
---|
| 115 | [Item("Coordinates-based TSP Data", "TSP that is represented by coordinates of locations.")]
|
---|
| 116 | [StorableType("3955d07a-d43c-4a01-9505-d2effb1ea865")]
|
---|
[17251] | 117 | public abstract class CoordinatesTSPData : NamedItem, ITSPData {
|
---|
[17253] | 118 | [Storable] public DoubleMatrix Coordinates { get; protected set; }
|
---|
[17241] | 119 |
|
---|
[17253] | 120 | public int Cities => Coordinates.Rows;
|
---|
| 121 |
|
---|
[17241] | 122 | [StorableConstructor]
|
---|
| 123 | protected CoordinatesTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 124 | protected CoordinatesTSPData(CoordinatesTSPData original, Cloner cloner) : base(original, cloner) {
|
---|
[17251] | 125 | Coordinates = original.Coordinates;
|
---|
[17241] | 126 | }
|
---|
| 127 | protected CoordinatesTSPData() : base() {
|
---|
[17251] | 128 | Name = TSPDefaultInstance.Name;
|
---|
| 129 | Coordinates = TSPDefaultInstance.Coordinates;
|
---|
[17241] | 130 | }
|
---|
[17251] | 131 | protected CoordinatesTSPData(string name, double[,] coordinates) : base() {
|
---|
[17241] | 132 | if (coordinates == null) throw new ArgumentNullException(nameof(coordinates));
|
---|
| 133 | if (coordinates.GetLength(1) != 2) throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
|
---|
[17251] | 134 | Name = name;
|
---|
| 135 | Coordinates = new DoubleMatrix(coordinates, @readonly: true);
|
---|
[17241] | 136 | }
|
---|
[17251] | 137 | protected CoordinatesTSPData(string name, DoubleMatrix coordinates) : base() {
|
---|
| 138 | if (coordinates == null) throw new ArgumentNullException(nameof(coordinates));
|
---|
| 139 | if (coordinates.Columns != 2) throw new ArgumentException("Argument must have exactly two columns.", nameof(coordinates));
|
---|
| 140 | Name = name;
|
---|
[17253] | 141 | Coordinates = coordinates.AsReadOnly();
|
---|
[17251] | 142 | }
|
---|
[17241] | 143 |
|
---|
| 144 | public double GetDistance(int fromCity, int toCity) {
|
---|
| 145 | return GetDistance(Coordinates[fromCity, 0], Coordinates[fromCity, 1],
|
---|
| 146 | Coordinates[toCity, 0], Coordinates[toCity, 1]);
|
---|
| 147 | }
|
---|
| 148 |
|
---|
| 149 | public abstract double GetDistance(double fromX, double fromY, double toX, double toY);
|
---|
[17525] | 150 | public double GetPathDistance(IEnumerable<int> path, bool closed = true) {
|
---|
| 151 | var iter = path.GetEnumerator();
|
---|
| 152 | if (!iter.MoveNext()) return 0;
|
---|
| 153 | var start = iter.Current;
|
---|
| 154 | var prev = start;
|
---|
| 155 | var distance = 0.0;
|
---|
| 156 | while (iter.MoveNext()) {
|
---|
| 157 | var cur = iter.Current;
|
---|
| 158 | distance += GetDistance(prev, cur);
|
---|
| 159 | prev = cur;
|
---|
| 160 | }
|
---|
| 161 | if (closed) distance += GetDistance(prev, start);
|
---|
| 162 | return distance;
|
---|
| 163 | }
|
---|
[17241] | 164 |
|
---|
[17529] | 165 | public double[,] CalculateDistanceMatrix() {
|
---|
| 166 | var matrix = new double[Cities, Cities];
|
---|
| 167 | for (var i = 0; i < Cities; i++) {
|
---|
| 168 | for (var j = 0; j < Cities; j++) {
|
---|
| 169 | matrix[i, j] = GetDistance(i, j);
|
---|
| 170 | }
|
---|
| 171 | }
|
---|
| 172 | return matrix;
|
---|
| 173 | }
|
---|
| 174 |
|
---|
[17253] | 175 | public virtual ITSPSolution GetSolution(Permutation tour, double tourLength) {
|
---|
[17335] | 176 | return new TSPSolution(this, tour, new DoubleValue(tourLength));
|
---|
[17241] | 177 | }
|
---|
[17251] | 178 |
|
---|
| 179 | public abstract TSPData Export();
|
---|
[17241] | 180 | }
|
---|
| 181 |
|
---|
| 182 | [Item("Euclidean TSP Data", "TSP that is represented by coordinates in an Euclidean plane.")]
|
---|
| 183 | [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")]
|
---|
[17335] | 184 | public sealed class EuclideanTSPData : CoordinatesTSPData {
|
---|
[17356] | 185 | [StorableType("be274140-e289-4125-ae3e-8c2f1d942f94")]
|
---|
[17251] | 186 | public enum DistanceRounding { None, Midpoint, Ceiling }
|
---|
[17241] | 187 |
|
---|
[17356] | 188 | [Storable] public DistanceRounding Rounding { get; private set; }
|
---|
[17241] | 189 |
|
---|
| 190 | [StorableConstructor]
|
---|
[17335] | 191 | private EuclideanTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 192 | private EuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) {
|
---|
[17241] | 193 | Rounding = original.Rounding;
|
---|
| 194 | }
|
---|
[17251] | 195 | public EuclideanTSPData()
|
---|
| 196 | : base() {
|
---|
| 197 | Rounding = DistanceRounding.Midpoint;
|
---|
| 198 | }
|
---|
| 199 | public EuclideanTSPData(string name, double[,] coordinates, DistanceRounding rounding = DistanceRounding.None)
|
---|
| 200 | : base(name, coordinates) {
|
---|
| 201 | Rounding = rounding;
|
---|
| 202 | }
|
---|
| 203 | public EuclideanTSPData(string name, DoubleMatrix coordinates, DistanceRounding rounding = DistanceRounding.None)
|
---|
| 204 | : base(name, coordinates) {
|
---|
| 205 | Rounding = rounding;
|
---|
| 206 | }
|
---|
[17241] | 207 |
|
---|
| 208 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 209 | return new EuclideanTSPData(this, cloner);
|
---|
| 210 | }
|
---|
| 211 |
|
---|
| 212 | public override double GetDistance(double fromX, double fromY, double toX, double toY) {
|
---|
[17253] | 213 | var dist = DistanceHelper.EuclideanDistance(fromX, fromY, toX, toY);
|
---|
[17241] | 214 | switch (Rounding) {
|
---|
[17251] | 215 | case DistanceRounding.None: return dist;
|
---|
| 216 | case DistanceRounding.Midpoint: return Math.Round(dist);
|
---|
| 217 | case DistanceRounding.Ceiling: return Math.Ceiling(dist);
|
---|
[17241] | 218 | default: throw new InvalidOperationException("Unknown rounding mode " + Rounding);
|
---|
| 219 | }
|
---|
| 220 | }
|
---|
[17251] | 221 |
|
---|
| 222 | public override TSPData Export() {
|
---|
| 223 | var data = new TSPData() {
|
---|
| 224 | Name = name,
|
---|
| 225 | Description = description,
|
---|
| 226 | Coordinates = Coordinates.CloneAsMatrix(),
|
---|
| 227 | Dimension = Coordinates.Rows
|
---|
| 228 | };
|
---|
| 229 | switch (Rounding) {
|
---|
| 230 | case DistanceRounding.None: data.DistanceMeasure = DistanceMeasure.Euclidean; break;
|
---|
| 231 | case DistanceRounding.Midpoint: data.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;
|
---|
| 232 | case DistanceRounding.Ceiling: data.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;
|
---|
| 233 | }
|
---|
| 234 | return data;
|
---|
| 235 | }
|
---|
[17241] | 236 | }
|
---|
| 237 |
|
---|
| 238 | [Item("Geo TSP Data", "TSP that is represented by geo coordinates.")]
|
---|
[17254] | 239 | [StorableType("dc859a89-e6c2-4af3-a3b6-9aa3041b14a9")]
|
---|
[17335] | 240 | public sealed class GeoTSPData : CoordinatesTSPData {
|
---|
[17241] | 241 | [StorableConstructor]
|
---|
[17335] | 242 | private GeoTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 243 | private GeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { }
|
---|
[17241] | 244 | public GeoTSPData() : base() { }
|
---|
[17251] | 245 | public GeoTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
|
---|
| 246 | public GeoTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
|
---|
[17241] | 247 |
|
---|
| 248 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 249 | return new GeoTSPData(this, cloner);
|
---|
| 250 | }
|
---|
| 251 |
|
---|
| 252 | public override double GetDistance(double fromX, double fromY, double toX, double toY) {
|
---|
[17253] | 253 | return DistanceHelper.GeoDistance(fromX, fromY, toX, toY);
|
---|
| 254 | }
|
---|
[17241] | 255 |
|
---|
[17253] | 256 | public override TSPData Export() {
|
---|
| 257 | return new TSPData() {
|
---|
| 258 | Name = name,
|
---|
| 259 | Description = description,
|
---|
| 260 | Coordinates = Coordinates.CloneAsMatrix(),
|
---|
| 261 | Dimension = Coordinates.Rows,
|
---|
| 262 | DistanceMeasure = DistanceMeasure.Geo
|
---|
| 263 | };
|
---|
| 264 | }
|
---|
| 265 | }
|
---|
[17241] | 266 |
|
---|
[17253] | 267 | [Item("ATT TSP Data", "TSP that is represented by ATT coordinates.")]
|
---|
| 268 | [StorableType("d7a0add3-6ec1-42e0-b1d7-b6454694d485")]
|
---|
[17335] | 269 | public sealed class AttTSPData : CoordinatesTSPData {
|
---|
[17253] | 270 | [StorableConstructor]
|
---|
[17335] | 271 | private AttTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 272 | private AttTSPData(AttTSPData original, Cloner cloner) : base(original, cloner) { }
|
---|
[17253] | 273 | public AttTSPData() : base() { }
|
---|
| 274 | public AttTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
|
---|
| 275 | public AttTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
|
---|
[17241] | 276 |
|
---|
[17253] | 277 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 278 | return new AttTSPData(this, cloner);
|
---|
[17241] | 279 | }
|
---|
| 280 |
|
---|
[17253] | 281 | public override double GetDistance(double fromX, double fromY, double toX, double toY) {
|
---|
| 282 | return DistanceHelper.AttDistance(fromX, fromY, toX, toY);
|
---|
[17241] | 283 | }
|
---|
[17251] | 284 |
|
---|
| 285 | public override TSPData Export() {
|
---|
| 286 | return new TSPData() {
|
---|
| 287 | Name = name,
|
---|
| 288 | Description = description,
|
---|
| 289 | Coordinates = Coordinates.CloneAsMatrix(),
|
---|
| 290 | Dimension = Coordinates.Rows,
|
---|
[17253] | 291 | DistanceMeasure = DistanceMeasure.Att
|
---|
[17251] | 292 | };
|
---|
| 293 | }
|
---|
[17241] | 294 | }
|
---|
[17251] | 295 |
|
---|
[17253] | 296 | [Item("Manhattan TSP Data", "TSP that is represented by Manhattan coordinates.")]
|
---|
| 297 | [StorableType("5f1ef9e2-cbd1-400e-8f87-6855f091fc9e")]
|
---|
[17335] | 298 | public sealed class ManhattanTSPData : CoordinatesTSPData {
|
---|
[17253] | 299 | [StorableConstructor]
|
---|
[17335] | 300 | private ManhattanTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 301 | private ManhattanTSPData(ManhattanTSPData original, Cloner cloner) : base(original, cloner) { }
|
---|
[17253] | 302 | public ManhattanTSPData() : base() { }
|
---|
| 303 | public ManhattanTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
|
---|
| 304 | public ManhattanTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
|
---|
| 305 |
|
---|
| 306 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 307 | return new ManhattanTSPData(this, cloner);
|
---|
| 308 | }
|
---|
| 309 |
|
---|
| 310 | public override double GetDistance(double fromX, double fromY, double toX, double toY) {
|
---|
| 311 | return DistanceHelper.ManhattanDistance(fromX, fromY, toX, toY);
|
---|
| 312 | }
|
---|
| 313 |
|
---|
| 314 | public override TSPData Export() {
|
---|
| 315 | return new TSPData() {
|
---|
| 316 | Name = name,
|
---|
| 317 | Description = description,
|
---|
| 318 | Coordinates = Coordinates.CloneAsMatrix(),
|
---|
| 319 | Dimension = Coordinates.Rows,
|
---|
| 320 | DistanceMeasure = DistanceMeasure.Manhattan
|
---|
| 321 | };
|
---|
| 322 | }
|
---|
| 323 | }
|
---|
| 324 |
|
---|
| 325 | [Item("Manhattan TSP Data", "TSP that is represented by the maximum absolute distance in either x or y coordinates.")]
|
---|
| 326 | [StorableType("c6294a6c-fe62-4906-9765-4bc306d3e4a8")]
|
---|
[17335] | 327 | public sealed class MaximumTSPData : CoordinatesTSPData {
|
---|
[17253] | 328 | [StorableConstructor]
|
---|
[17335] | 329 | private MaximumTSPData(StorableConstructorFlag _) : base(_) { }
|
---|
| 330 | private MaximumTSPData(MaximumTSPData original, Cloner cloner) : base(original, cloner) { }
|
---|
[17253] | 331 | public MaximumTSPData() : base() { }
|
---|
| 332 | public MaximumTSPData(string name, double[,] coordinates) : base(name, coordinates) { }
|
---|
| 333 | public MaximumTSPData(string name, DoubleMatrix coordinates) : base(name, coordinates) { }
|
---|
| 334 |
|
---|
| 335 | public override IDeepCloneable Clone(Cloner cloner) {
|
---|
| 336 | return new MaximumTSPData(this, cloner);
|
---|
| 337 | }
|
---|
| 338 |
|
---|
| 339 | public override double GetDistance(double fromX, double fromY, double toX, double toY) {
|
---|
| 340 | return DistanceHelper.MaximumDistance(fromX, fromY, toX, toY);
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | public override TSPData Export() {
|
---|
| 344 | return new TSPData() {
|
---|
| 345 | Name = name,
|
---|
| 346 | Description = description,
|
---|
| 347 | Coordinates = Coordinates.CloneAsMatrix(),
|
---|
| 348 | Dimension = Coordinates.Rows,
|
---|
| 349 | DistanceMeasure = DistanceMeasure.Maximum
|
---|
| 350 | };
|
---|
| 351 | }
|
---|
| 352 | }
|
---|
| 353 |
|
---|
[17251] | 354 | internal static class TSPDefaultInstance {
|
---|
| 355 | internal static readonly DoubleMatrix Distances = new DoubleMatrix(new double[,] {
|
---|
| 356 | { 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361, 300, 316, 361, 424 },
|
---|
| 357 | { 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283, 316, 300, 316, 361 },
|
---|
| 358 | { 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224, 361, 316, 300, 316 },
|
---|
| 359 | { 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200, 424, 361, 316, 300 },
|
---|
| 360 | { 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361 },
|
---|
| 361 | { 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283 },
|
---|
| 362 | { 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224 },
|
---|
| 363 | { 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200 },
|
---|
| 364 | { 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316 },
|
---|
| 365 | { 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224 },
|
---|
| 366 | { 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141 },
|
---|
| 367 | { 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100 },
|
---|
| 368 | { 300, 316, 361, 424, 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300 },
|
---|
| 369 | { 316, 300, 316, 361, 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200 },
|
---|
| 370 | { 361, 316, 300, 316, 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100 },
|
---|
| 371 | { 424, 361, 316, 300, 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0 },
|
---|
| 372 | }, @readonly: true);
|
---|
| 373 | internal static readonly DoubleMatrix Coordinates = new DoubleMatrix(new double[,] {
|
---|
| 374 | { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },
|
---|
| 375 | { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },
|
---|
| 376 | { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },
|
---|
| 377 | { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }
|
---|
| 378 | }, @readonly: true);
|
---|
| 379 | internal static readonly string Name = "HL TSP Default";
|
---|
| 380 | }
|
---|
[17239] | 381 | }
|
---|