Changeset 17335 for branches/2521_ProblemRefactoring
- Timestamp:
- 10/17/19 21:40:30 (5 years ago)
- Location:
- branches/2521_ProblemRefactoring
- Files:
-
- 5 added
- 16 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP.Views/3.3/HeuristicLab.Problems.PTSP.Views-3.3.csproj
r17320 r17335 172 172 </ItemGroup> 173 173 <ItemGroup> 174 <Compile Include=" CoordinatesPTSPDataView.cs">174 <Compile Include="ProbabilisticTSPDataView.cs"> 175 175 <SubType>UserControl</SubType> 176 176 </Compile> 177 <Compile Include="CoordinatesPTSPDataView.Designer.cs"> 178 <DependentUpon>CoordinatesPTSPDataView.cs</DependentUpon> 179 </Compile> 180 <Compile Include="EuclideanPTSPDataView.cs"> 181 <SubType>UserControl</SubType> 182 </Compile> 183 <Compile Include="EuclideanPTSPDataView.Designer.cs"> 184 <DependentUpon>EuclideanPTSPDataView.cs</DependentUpon> 185 </Compile> 186 <Compile Include="MatrixPTSPDataView.cs"> 187 <SubType>UserControl</SubType> 188 </Compile> 189 <Compile Include="MatrixPTSPDataView.Designer.cs"> 190 <DependentUpon>MatrixPTSPDataView.cs</DependentUpon> 177 <Compile Include="ProbabilisticTSPDataView.Designer.cs"> 178 <DependentUpon>ProbabilisticTSPDataView.cs</DependentUpon> 191 179 </Compile> 192 180 <Compile Include="ProbabilisticTSPSolutionView.cs"> … … 198 186 <Compile Include="Plugin.cs" /> 199 187 <Compile Include="Properties\AssemblyInfo.cs" /> 188 <Compile Include="ProbabilisticTSPVisualizer.cs" /> 200 189 </ItemGroup> 201 190 <ItemGroup> -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP.Views/3.3/ProbabilisticTSPSolutionView.cs
r17260 r17335 22 22 using System; 23 23 using System.Drawing; 24 using HeuristicLab.Core.Views; 24 25 using HeuristicLab.Data; 25 26 using HeuristicLab.Encodings.PermutationEncoding; … … 31 32 /// The base class for visual representations of a path tour for a PTSP. 32 33 /// </summary> 33 [View(" PathPTSPTourView")]34 [View("pTSP Solution View")] 34 35 [Content(typeof(IProbabilisticTSPSolution), true)] 35 public sealed partial class ProbabilisticTSPSolutionView : TSPSolutionView { 36 public sealed partial class ProbabilisticTSPSolutionView : ItemView { 37 public TSPVisualizer Visualizer { get; set; } 38 36 39 public new IProbabilisticTSPSolution Content { 37 40 get { return (IProbabilisticTSPSolution)base.Content; } … … 44 47 public ProbabilisticTSPSolutionView() { 45 48 InitializeComponent(); 46 } 47 48 protected override void GenerateImage() { 49 if ((pictureBox.Width > 0) && (pictureBox.Height > 0)) { 50 if (Content == null) { 51 pictureBox.Image = null; 52 } else { 53 DoubleMatrix coordinates = Content.Coordinates; 54 Permutation permutation = Content.Tour; 55 DoubleArray probabilities = Content.Probabilities; 56 Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height); 57 58 if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2) && (probabilities.Length == coordinates.Rows)) { 59 double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue; 60 for (int i = 0; i < coordinates.Rows; i++) { 61 if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0]; 62 if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1]; 63 if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0]; 64 if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1]; 65 } 66 67 int border = 20; 68 double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1; 69 double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1; 70 71 Point[] points = new Point[coordinates.Rows]; 72 for (int i = 0; i < coordinates.Rows; i++) 73 points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)), 74 bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep)))); 75 76 using (Graphics graphics = Graphics.FromImage(bitmap)) { 77 if (permutation != null && permutation.Length > 1) { 78 Point[] tour = new Point[permutation.Length]; 79 for (int i = 0; i < permutation.Length; i++) { 80 if (permutation[i] >= 0 && permutation[i] < points.Length) 81 tour[i] = points[permutation[i]]; 82 } 83 graphics.DrawPolygon(Pens.Black, tour); 84 } 85 for (int i = 0; i < points.Length; i++) 86 graphics.FillRectangle(Brushes.Red, points[i].X - 2, points[i].Y - 2, Convert.ToInt32(probabilities[i] * 20), Convert.ToInt32(probabilities[i] * 20)); 87 } 88 } else { 89 using (Graphics graphics = Graphics.FromImage(bitmap)) { 90 graphics.Clear(Color.White); 91 Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular); 92 string text = "No coordinates defined or in wrong format."; 93 SizeF strSize = graphics.MeasureString(text, font); 94 graphics.DrawString(text, font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f); 95 } 96 } 97 pictureBox.Image = bitmap; 98 } 99 } 49 Visualizer = new ProbabilisticTSPVisualizer(); 100 50 } 101 51 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/AnalyticalPTSP.cs
r17320 r17335 69 69 for (var i = 0; i < tour.Length - 1; i++) { 70 70 for (var j = i + 1; j < tour.Length; j++) { 71 var prod1 = data. GetDistance(tour[i], tour[j]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]);71 var prod1 = data.TSPData.GetDistance(tour[i], tour[j]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]); 72 72 for (var k = i + 1; k < j; k++) { 73 73 prod1 *= (1 - data.GetProbability(tour[k])); … … 79 79 for (var j = 0; j < tour.Length; j++) { 80 80 for (var i = 0; i < j; i++) { 81 var prod2 = data. GetDistance(tour[j], tour[i]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]);81 var prod2 = data.TSPData.GetDistance(tour[j], tour[i]) * data.GetProbability(tour[i]) * data.GetProbability(tour[j]); 82 82 for (var k = j + 1; k < tour.Length; k++) { 83 83 prod2 *= (1 - data.GetProbability(tour[k])); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/EstimatedPTSP.cs
r17320 r17335 117 117 foreach (var r in realizations) { 118 118 int singleRealization = -1, firstNode = -1; 119 for (var j = 0; j < data. Cities; j++) {119 for (var j = 0; j < data.TSPData.Cities; j++) { 120 120 if (r[tour[j]]) { 121 121 if (singleRealization != -1) { 122 estimatedSum += data. GetDistance(singleRealization, tour[j]);122 estimatedSum += data.TSPData.GetDistance(singleRealization, tour[j]); 123 123 } else { 124 124 firstNode = tour[j]; … … 128 128 } 129 129 if (singleRealization != -1) 130 estimatedSum += data. GetDistance(singleRealization, firstNode);130 estimatedSum += data.TSPData.GetDistance(singleRealization, firstNode); 131 131 count++; 132 132 } … … 151 151 var pSum = 0.0; 152 152 int singleRealization = -1, firstNode = -1; 153 for (var j = 0; j < data. Cities; j++) {153 for (var j = 0; j < data.TSPData.Cities; j++) { 154 154 if (r[tour[j]]) { 155 155 if (singleRealization != -1) { 156 pSum += data. GetDistance(singleRealization, tour[j]);156 pSum += data.TSPData.GetDistance(singleRealization, tour[j]); 157 157 } else { 158 158 firstNode = tour[j]; … … 162 162 } 163 163 if (singleRealization != -1) { 164 pSum += data. GetDistance(singleRealization, firstNode);164 pSum += data.TSPData.GetDistance(singleRealization, firstNode); 165 165 } 166 166 estimatedSum += pSum; … … 199 199 var data = new List<BoolArray>(Realizations); 200 200 var rng = new MersenneTwister((uint)RealizationsSeed); 201 if (Enumerable.Range(0, ProbabilisticTSPData. Cities).All(c => ProbabilisticTSPData.GetProbability(c) <= 0))201 if (Enumerable.Range(0, ProbabilisticTSPData.TSPData.Cities).All(c => ProbabilisticTSPData.GetProbability(c) <= 0)) 202 202 throw new InvalidOperationException("All probabilities are zero."); 203 203 while (data.Count < Realizations) { 204 204 var cities = 0; 205 var r = new bool[ProbabilisticTSPData. Cities];206 for (var j = 0; j < ProbabilisticTSPData. Cities; j++) {205 var r = new bool[ProbabilisticTSPData.TSPData.Cities]; 206 for (var j = 0; j < ProbabilisticTSPData.TSPData.Cities; j++) { 207 207 if (rng.NextDouble() < ProbabilisticTSPData.GetProbability(j)) { 208 208 r[j] = true; -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/OneShift/PTSPEstimatedInsertionMoveEvaluator.cs
r17253 r17335 126 126 !(aPosteriori[2] == aPosteriori[4] && aPosteriori[3] == aPosteriori[5])) { 127 127 // compute cost difference between the two a posteriori solutions 128 moveQuality = moveQuality + data. GetDistance(aPosteriori[6], aPosteriori[7]) + data.GetDistance(aPosteriori[8], aPosteriori[9]) + data.GetDistance(aPosteriori[10], aPosteriori[11]);129 moveQuality = moveQuality - data. GetDistance(aPosteriori[0], aPosteriori[1]) - data.GetDistance(aPosteriori[2], aPosteriori[3]) - data.GetDistance(aPosteriori[4], aPosteriori[5]);128 moveQuality = moveQuality + data.TSPData.GetDistance(aPosteriori[6], aPosteriori[7]) + data.TSPData.GetDistance(aPosteriori[8], aPosteriori[9]) + data.TSPData.GetDistance(aPosteriori[10], aPosteriori[11]); 129 moveQuality = moveQuality - data.TSPData.GetDistance(aPosteriori[0], aPosteriori[1]) - data.TSPData.GetDistance(aPosteriori[2], aPosteriori[3]) - data.TSPData.GetDistance(aPosteriori[4], aPosteriori[5]); 130 130 } 131 131 Array.Clear(aPosteriori, 0, aPosteriori.Length); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/Moves/TwoOpt/PTSPEstimatedInversionMoveEvaluator.cs
r17253 r17335 89 89 // compute cost difference between the two a posteriori solutions 90 90 if (!(aPosteriori[0] == aPosteriori[2] && aPosteriori[1] == aPosteriori[3])) { 91 moveQuality = moveQuality + data. GetDistance(aPosteriori[0], aPosteriori[2]) + data.GetDistance(aPosteriori[1], aPosteriori[3])92 - data. GetDistance(aPosteriori[0], aPosteriori[1]) - data.GetDistance(aPosteriori[2], aPosteriori[3]);91 moveQuality = moveQuality + data.TSPData.GetDistance(aPosteriori[0], aPosteriori[2]) + data.TSPData.GetDistance(aPosteriori[1], aPosteriori[3]) 92 - data.TSPData.GetDistance(aPosteriori[0], aPosteriori[1]) - data.TSPData.GetDistance(aPosteriori[2], aPosteriori[3]); 93 93 } 94 94 Array.Clear(aPosteriori, 0, aPosteriori.Length); -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSP.cs
r17270 r17335 25 25 using HeuristicLab.Common; 26 26 using HeuristicLab.Core; 27 using HeuristicLab.Data;28 27 using HeuristicLab.Encodings.PermutationEncoding; 29 28 using HeuristicLab.Optimization; … … 70 69 Parameters.Add(BestKnownSolutionParameter = new OptionalValueParameter<IProbabilisticTSPSolution>("BestKnownSolution", "The best known solution of this pTSP instance.")); 71 70 72 ProbabilisticTSPData = new MatrixPTSPData();73 Encoding.Length = ProbabilisticTSPData. Cities;71 ProbabilisticTSPData = new ProbabilisticTSPData(); 72 Encoding.Length = ProbabilisticTSPData.TSPData.Cities; 74 73 } 75 74 76 75 protected override void OnEncodingChanged() { 77 76 base.OnEncodingChanged(); 78 Encoding.Length = ProbabilisticTSPData. Cities;77 Encoding.Length = ProbabilisticTSPData.TSPData.Cities; 79 78 } 80 79 … … 117 116 Description = data.Description; 118 117 119 if (data.Dimension <= DistanceMatrixSizeLimit) { 120 ProbabilisticTSPData = new MatrixPTSPData(data.Name, data.GetDistanceMatrix(), data.Probabilities, data.Coordinates) { Description = data.Description }; 121 } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) { 122 ProbabilisticTSPData = new MatrixPTSPData(data.Name, data.Distances, data.Probabilities, data.Coordinates) { Description = data.Description }; 123 } else { 124 switch (data.DistanceMeasure) { 125 case DistanceMeasure.Att: 126 ProbabilisticTSPData = new AttPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description }; 127 break; 128 case DistanceMeasure.Euclidean: 129 ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.None) { Description = data.Description }; 130 break; 131 case DistanceMeasure.RoundedEuclidean: 132 ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Midpoint) { Description = data.Description }; 133 break; 134 case DistanceMeasure.UpperEuclidean: 135 ProbabilisticTSPData = new EuclideanPTSPData(data.Name, data.Coordinates, data.Probabilities, EuclideanTSPData.DistanceRounding.Ceiling) { Description = data.Description }; 136 break; 137 case DistanceMeasure.Geo: 138 ProbabilisticTSPData = new GeoPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description }; 139 break; 140 case DistanceMeasure.Manhattan: 141 ProbabilisticTSPData = new ManhattanPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description }; 142 break; 143 case DistanceMeasure.Maximum: 144 ProbabilisticTSPData = new MaximumPTSPData(data.Name, data.Coordinates, data.Probabilities) { Description = data.Description }; 145 break; 146 default: 147 throw new System.IO.InvalidDataException("An unknown distance measure is given in the instance!"); 148 } 149 } 118 var tspData = TSP.GetDataFromInstance(data); 119 ProbabilisticTSPData = new ProbabilisticTSPData(tspData, data.Probabilities); 150 120 BestKnownSolution = null; 151 121 BestKnownQuality = double.NaN; … … 154 124 try { 155 125 var tour = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour); 156 var tourLength = Evaluate(tour, new MersenneTwister(1)); 157 BestKnownSolution = new ProbabilisticTSPSolution(data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null, new PercentArray(data.Probabilities), tour, new DoubleValue(tourLength));126 var tourLength = Evaluate(tour, new MersenneTwister(1)); 127 BestKnownSolution = ProbabilisticTSPData.GetSolution(tour, tourLength); 158 128 BestKnownQuality = tourLength; 159 129 } catch (InvalidOperationException) { -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSPData.cs
r17260 r17335 21 21 22 22 using System; 23 using System.Linq; 23 24 using HEAL.Attic; 24 25 using HeuristicLab.Common; … … 31 32 namespace HeuristicLab.Problems.PTSP { 32 33 [StorableType("dd2d0ecc-372e-46f1-846f-fb4ca2afa124")] 33 public interface IProbabilisticTSPData : ITSPData { 34 public interface IProbabilisticTSPData : INamedItem { 35 ITSPData TSPData { get; } 36 34 37 double GetProbability(int city); 35 newIProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength);36 newPTSPData Export();38 IProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength); 39 PTSPData Export(); 37 40 } 38 41 39 [Item("Matrix-based pTSP Data", "pTSP that is representd by a distance matrix.")] 40 [StorableType("30ebade1-d28c-4e45-b195-c7fa32a15df5")] 41 public class MatrixPTSPData : MatrixTSPData, IProbabilisticTSPData { 42 [Item("Probabilistic TSP Data", "An extension to the TSP where customers have to be served with a certain probability only.")] 43 [StorableType("b79f0ad6-b7f7-49c5-9a62-8089db6af1aa")] 44 public class ProbabilisticTSPData : NamedItem, IProbabilisticTSPData { 45 [Storable] public ITSPData TSPData { get; protected set; } 42 46 [Storable] public PercentArray Probabilities { get; protected set; } 43 47 44 48 [StorableConstructor] 45 protected MatrixPTSPData(StorableConstructorFlag _) : base(_) { } 46 protected MatrixPTSPData(MatrixPTSPData original, Cloner cloner) : base(original, cloner) { 49 protected ProbabilisticTSPData(StorableConstructorFlag _) : base(_) { } 50 protected ProbabilisticTSPData(ProbabilisticTSPData original, Cloner cloner) : base(original, cloner) { 51 TSPData = original.TSPData; 47 52 Probabilities = original.Probabilities; 48 53 } 49 public MatrixPTSPData() { 50 Name = PTSPDefaultInstance.Name; 51 Matrix = PTSPDefaultInstance.Distances; 52 Probabilities = PTSPDefaultInstance.Probabilities; 53 DisplayCoordinates = PTSPDefaultInstance.Coordinates; 54 public ProbabilisticTSPData() { 55 TSPData = new EuclideanTSPData(); 56 Name = TSPData.Name; 57 Probabilities = new PercentArray(Enumerable.Repeat(0.5, TSPData.Cities).ToArray(), @readonly: true); 54 58 } 55 public MatrixPTSPData(string name, double[,] matrix, double[] probabilities, double[,] coordinates = null) 56 : base(name, matrix, coordinates) { 59 public ProbabilisticTSPData(ITSPData tspData, double[] probabilities) 60 : base(tspData.Name, tspData.Description) { 61 if (tspData.Cities != probabilities.Length) throw new ArgumentException("Unequal number of cities and probabilities."); 62 TSPData = tspData; 57 63 Probabilities = new PercentArray(probabilities, @readonly: true); 58 64 } 59 public MatrixPTSPData(string name, DoubleMatrix matrix, PercentArray probabilities, DoubleMatrix coordinates = null) 60 : base(name, matrix, coordinates) { 65 public ProbabilisticTSPData(ITSPData tspData, PercentArray probabilities) 66 : base(tspData.Name, tspData.Description) { 67 if (tspData.Cities != probabilities.Length) throw new ArgumentException("Unequal number of cities and probabilities."); 68 TSPData = tspData; 61 69 Probabilities = probabilities.AsReadOnly(); 62 70 } 63 71 64 72 public override IDeepCloneable Clone(Cloner cloner) { 65 return new MatrixPTSPData(this, cloner);73 return new ProbabilisticTSPData(this, cloner); 66 74 } 67 75 68 76 public double GetProbability(int city) => Probabilities[city]; 69 77 70 public new IProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength) { 71 return new ProbabilisticTSPSolution(DisplayCoordinates, Probabilities, tspTour, new DoubleValue(tourLength)); 78 public IProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength) { 79 var tspSolution = TSPData.GetSolution(tspTour, tourLength); 80 return new ProbabilisticTSPSolution(tspSolution, Probabilities); 72 81 } 73 82 74 public new PTSPData Export() { 83 public PTSPData Export() { 84 var tspExport = TSPData.Export(); 75 85 return new PTSPData() { 76 Name = name,77 Description = description,78 Coordinates = DisplayCoordinates?.CloneAsMatrix(),79 Dimension = Matrix.Rows,80 DistanceMeasure = DistanceMeasure.Direct,81 Distances = Matrix.CloneAsMatrix(),86 Name = tspExport.Name, 87 Description = tspExport.Description, 88 Coordinates = tspExport.Coordinates, 89 Dimension = tspExport.Dimension, 90 DistanceMeasure = tspExport.DistanceMeasure, 91 Distances = tspExport.Distances, 82 92 Probabilities = Probabilities.CloneAsArray() 83 93 }; 84 94 } 85 95 } 86 87 [Item("Euclidean pTSP Data", "pTSP that is represented by coordinates in an Euclidean plane.")]88 [StorableType("8d4cf257-9013-4746-bc6c-37615954c3fb")]89 public class EuclideanPTSPData : EuclideanTSPData, IProbabilisticTSPData {90 [Storable] public PercentArray Probabilities { get; protected set; }91 92 [StorableConstructor]93 protected EuclideanPTSPData(StorableConstructorFlag _) : base(_) { }94 protected EuclideanPTSPData(EuclideanPTSPData original, Cloner cloner) : base(original, cloner) {95 Probabilities = original.Probabilities;96 }97 public EuclideanPTSPData() : base() {98 Name = PTSPDefaultInstance.Name;99 Coordinates = PTSPDefaultInstance.Coordinates;100 Probabilities = PTSPDefaultInstance.Probabilities;101 Rounding = DistanceRounding.Midpoint;102 }103 public EuclideanPTSPData(string name, double[,] coordinates, double[] probabilities, DistanceRounding rounding = DistanceRounding.None)104 : base(name, coordinates) {105 if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");106 Probabilities = new PercentArray(probabilities, @readonly: true);107 }108 public EuclideanPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities, DistanceRounding rounding = DistanceRounding.None)109 : base(name, coordinates, rounding) {110 if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");111 Probabilities = probabilities.AsReadOnly();112 }113 114 public override IDeepCloneable Clone(Cloner cloner) {115 return new EuclideanPTSPData(this, cloner);116 }117 118 public double GetProbability(int city) => Probabilities[city];119 120 public new IProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength) {121 return new ProbabilisticTSPSolution(Coordinates, Probabilities, tspTour, new DoubleValue(tourLength));122 }123 124 public new PTSPData Export() {125 var data = new PTSPData() {126 Name = name,127 Description = description,128 Coordinates = Coordinates.CloneAsMatrix(),129 Probabilities = Probabilities.CloneAsArray(),130 Dimension = Coordinates.Rows,131 };132 switch (Rounding) {133 case DistanceRounding.None: data.DistanceMeasure = DistanceMeasure.Euclidean; break;134 case DistanceRounding.Midpoint: data.DistanceMeasure = DistanceMeasure.RoundedEuclidean; break;135 case DistanceRounding.Ceiling: data.DistanceMeasure = DistanceMeasure.UpperEuclidean; break;136 }137 return data;138 }139 }140 141 [Item("Coordinates pTSP Data", "pTSP that is represented by a distance between coordinates.")]142 [StorableType("db0ff368-23cf-4a28-bd82-5979c6a93ee5")]143 public abstract class CoordinatesPTSPData : CoordinatesTSPData, IProbabilisticTSPData {144 [Storable] public PercentArray Probabilities { get; protected set; }145 146 [StorableConstructor]147 protected CoordinatesPTSPData(StorableConstructorFlag _) : base(_) { }148 protected CoordinatesPTSPData(CoordinatesPTSPData original, Cloner cloner)149 : base(original, cloner) {150 Probabilities = original.Probabilities;151 }152 protected CoordinatesPTSPData() : base() {153 Name = PTSPDefaultInstance.Name;154 Coordinates = PTSPDefaultInstance.Coordinates;155 Probabilities = PTSPDefaultInstance.Probabilities;156 }157 protected CoordinatesPTSPData(string name, double[,] coordinates, double[] probabilities)158 : base(name, coordinates) {159 if (coordinates.GetLength(0) != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");160 Probabilities = new PercentArray(probabilities, @readonly: true);161 }162 protected CoordinatesPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities)163 : base(name, coordinates) {164 if (coordinates.Rows != probabilities.Length) throw new InvalidOperationException("Number of cities is ambiguous between " + nameof(coordinates) + " and " + nameof(probabilities) + ".");165 Probabilities = probabilities.AsReadOnly();166 }167 168 public double GetProbability(int city) => Probabilities[city];169 170 public new IProbabilisticTSPSolution GetSolution(Permutation tspTour, double tourLength) {171 return new ProbabilisticTSPSolution(Coordinates, Probabilities, tspTour, new DoubleValue(tourLength));172 }173 174 PTSPData IProbabilisticTSPData.Export() {175 return (PTSPData)Export();176 }177 }178 179 [Item("Geo pTSP Data", "pTSP that is represented by geo coordinates.")]180 [StorableType("b175e0be-5706-4c44-b3f0-dcb948d5c47a")]181 public class GeoPTSPData : CoordinatesPTSPData {182 183 [StorableConstructor]184 protected GeoPTSPData(StorableConstructorFlag _) : base(_) { }185 protected GeoPTSPData(GeoPTSPData original, Cloner cloner) : base(original, cloner) { }186 public GeoPTSPData() : base() { }187 public GeoPTSPData(string name, double[,] coordinates, double[] probabilities) : base(name, coordinates, probabilities) { }188 public GeoPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities) : base(name, coordinates, probabilities) { }189 190 public override IDeepCloneable Clone(Cloner cloner) {191 return new GeoPTSPData(this, cloner);192 }193 194 public override double GetDistance(double fromX, double fromY, double toX, double toY) {195 return DistanceHelper.GeoDistance(fromX, fromY, toX, toY);196 }197 198 public override TSPData Export() {199 return new PTSPData() {200 Name = name,201 Description = description,202 Coordinates = Coordinates.CloneAsMatrix(),203 Probabilities = Probabilities.CloneAsArray(),204 Dimension = Coordinates.Rows,205 DistanceMeasure = DistanceMeasure.Geo,206 };207 }208 }209 210 [Item("ATT pTSP Data", "pTSP that is represented by ATT distance.")]211 [StorableType("7a2aa605-58d2-4533-a763-3d474e185460")]212 public class AttPTSPData : CoordinatesPTSPData {213 214 [StorableConstructor]215 protected AttPTSPData(StorableConstructorFlag _) : base(_) { }216 protected AttPTSPData(AttPTSPData original, Cloner cloner) : base(original, cloner) { }217 public AttPTSPData() : base() { }218 public AttPTSPData(string name, double[,] coordinates, double[] probabilities) : base(name, coordinates, probabilities) { }219 public AttPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities) : base(name, coordinates, probabilities) { }220 221 public override IDeepCloneable Clone(Cloner cloner) {222 return new AttPTSPData(this, cloner);223 }224 225 public override double GetDistance(double fromX, double fromY, double toX, double toY) {226 return DistanceHelper.AttDistance(fromX, fromY, toX, toY);227 }228 229 public override TSPData Export() {230 return new PTSPData() {231 Name = name,232 Description = description,233 Coordinates = Coordinates.CloneAsMatrix(),234 Probabilities = Probabilities.CloneAsArray(),235 Dimension = Coordinates.Rows,236 DistanceMeasure = DistanceMeasure.Att,237 };238 }239 }240 241 [Item("Manhattan pTSP Data", "pTSP that is represented by Manhattan distance.")]242 [StorableType("cc43d1db-3da9-4d6e-becb-6b475b42fc59")]243 public class ManhattanPTSPData : CoordinatesPTSPData {244 245 [StorableConstructor]246 protected ManhattanPTSPData(StorableConstructorFlag _) : base(_) { }247 protected ManhattanPTSPData(ManhattanPTSPData original, Cloner cloner) : base(original, cloner) { }248 public ManhattanPTSPData() : base() { }249 public ManhattanPTSPData(string name, double[,] coordinates, double[] probabilities) : base(name, coordinates, probabilities) { }250 public ManhattanPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities) : base(name, coordinates, probabilities) { }251 252 public override IDeepCloneable Clone(Cloner cloner) {253 return new ManhattanPTSPData(this, cloner);254 }255 256 public override double GetDistance(double fromX, double fromY, double toX, double toY) {257 return DistanceHelper.ManhattanDistance(fromX, fromY, toX, toY);258 }259 260 public override TSPData Export() {261 return new PTSPData() {262 Name = name,263 Description = description,264 Coordinates = Coordinates.CloneAsMatrix(),265 Probabilities = Probabilities.CloneAsArray(),266 Dimension = Coordinates.Rows,267 DistanceMeasure = DistanceMeasure.Manhattan,268 };269 }270 }271 272 [Item("Maximum pTSP Data", "pTSP that is represented by maximum absolute distance in either the x or y coordinates.")]273 [StorableType("82e9cde2-a942-403a-80ff-8deae4fa8214")]274 public class MaximumPTSPData : CoordinatesPTSPData {275 276 [StorableConstructor]277 protected MaximumPTSPData(StorableConstructorFlag _) : base(_) { }278 protected MaximumPTSPData(MaximumPTSPData original, Cloner cloner) : base(original, cloner) { }279 public MaximumPTSPData() : base() { }280 public MaximumPTSPData(string name, double[,] coordinates, double[] probabilities) : base(name, coordinates, probabilities) { }281 public MaximumPTSPData(string name, DoubleMatrix coordinates, PercentArray probabilities) : base(name, coordinates, probabilities) { }282 283 public override IDeepCloneable Clone(Cloner cloner) {284 return new MaximumPTSPData(this, cloner);285 }286 287 public override double GetDistance(double fromX, double fromY, double toX, double toY) {288 return DistanceHelper.MaximumDistance(fromX, fromY, toX, toY);289 }290 291 public override TSPData Export() {292 return new PTSPData() {293 Name = name,294 Description = description,295 Coordinates = Coordinates.CloneAsMatrix(),296 Probabilities = Probabilities.CloneAsArray(),297 Dimension = Coordinates.Rows,298 DistanceMeasure = DistanceMeasure.Maximum,299 };300 }301 }302 303 internal static class PTSPDefaultInstance {304 internal static readonly DoubleMatrix Distances = new DoubleMatrix(new double[,] {305 { 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361, 300, 316, 361, 424 },306 { 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283, 316, 300, 316, 361 },307 { 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224, 361, 316, 300, 316 },308 { 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200, 424, 361, 316, 300 },309 { 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316, 200, 224, 283, 361 },310 { 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224, 224, 200, 224, 283 },311 { 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141, 283, 224, 200, 224 },312 { 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100, 361, 283, 224, 200 },313 { 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300, 100, 141, 224, 316 },314 { 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200, 141, 100, 141, 224 },315 { 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100, 224, 141, 100, 141 },316 { 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0, 316, 224, 141, 100 },317 { 300, 316, 361, 424, 200, 224, 283, 361, 100, 141, 224, 316, 0, 100, 200, 300 },318 { 316, 300, 316, 361, 224, 200, 224, 283, 141, 100, 141, 224, 100, 0, 100, 200 },319 { 361, 316, 300, 316, 283, 224, 200, 224, 224, 141, 100, 141, 200, 100, 0, 100 },320 { 424, 361, 316, 300, 361, 283, 224, 200, 316, 224, 141, 100, 300, 200, 100, 0 },321 }, @readonly: true);322 internal static readonly DoubleMatrix Coordinates = new DoubleMatrix(new double[,] {323 { 100, 100 }, { 100, 200 }, { 100, 300 }, { 100, 400 },324 { 200, 100 }, { 200, 200 }, { 200, 300 }, { 200, 400 },325 { 300, 100 }, { 300, 200 }, { 300, 300 }, { 300, 400 },326 { 400, 100 }, { 400, 200 }, { 400, 300 }, { 400, 400 }327 }, @readonly: true);328 internal static readonly PercentArray Probabilities = new PercentArray(new double[] {329 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.3, 0.4, 0.5330 }, @readonly: true);331 internal static readonly string Name = "HL PTSP Default";332 }333 96 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.PTSP/3.3/ProbabilisticTSPSolution.cs
r17260 r17335 20 20 #endregion 21 21 22 using System.ComponentModel; 22 23 using System.Drawing; 23 24 using HEAL.Attic; … … 25 26 using HeuristicLab.Core; 26 27 using HeuristicLab.Data; 27 using HeuristicLab.Encodings.PermutationEncoding;28 28 using HeuristicLab.Problems.TravelingSalesman; 29 29 30 30 namespace HeuristicLab.Problems.PTSP { 31 31 [StorableType("596f52b5-b2c8-45a0-a7bd-e5b9c787c960")] 32 public interface IProbabilisticTSPSolution : ITSPSolution { 32 public interface IProbabilisticTSPSolution : IItem, INotifyPropertyChanged { 33 ITSPSolution TSPSolution { get; } 33 34 DoubleArray Probabilities { get; } 34 35 } … … 39 40 [Item("pTSP Solution", "Represents a tour of a Probabilistic Traveling Salesman Problem given in path representation which can be visualized in the GUI.")] 40 41 [StorableType("ea784622-41e5-493e-a1f3-4c38fed99216")] 41 public sealed class ProbabilisticTSPSolution : TSPSolution, IProbabilisticTSPSolution {42 public sealed class ProbabilisticTSPSolution : Item, IProbabilisticTSPSolution { 42 43 public static new Image StaticItemImage { 43 44 get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; } 45 } 46 47 [Storable] 48 private ITSPSolution tspSolution; 49 public ITSPSolution TSPSolution { 50 get { return tspSolution; } 51 set { 52 if (tspSolution == value) return; 53 tspSolution = value; 54 OnPropertyChanged(nameof(TSPSolution)); 55 } 44 56 } 45 57 … … 59 71 private ProbabilisticTSPSolution(ProbabilisticTSPSolution original, Cloner cloner) 60 72 : base(original, cloner) { 73 this.tspSolution = cloner.Clone(original.tspSolution); 61 74 this.probabilities = cloner.Clone(original.probabilities); 62 75 } 63 76 public ProbabilisticTSPSolution() : base() { } 64 public ProbabilisticTSPSolution(DoubleMatrix coordinates, PercentArray probabilities) 65 : base(coordinates) { 66 this.probabilities = probabilities; 67 } 68 public ProbabilisticTSPSolution(DoubleMatrix coordinates, PercentArray probabilities, Permutation permutation) 69 : base(coordinates, permutation) { 70 this.probabilities = probabilities; 71 } 72 public ProbabilisticTSPSolution(DoubleMatrix coordinates, PercentArray probabilities, Permutation permutation, DoubleValue quality) 73 : base(coordinates, permutation, quality) { 77 public ProbabilisticTSPSolution(ITSPSolution tspSolution, PercentArray probabilities) 78 : base() { 79 this.tspSolution = tspSolution; 74 80 this.probabilities = probabilities; 75 81 } … … 78 84 return new ProbabilisticTSPSolution(this, cloner); 79 85 } 86 87 public event PropertyChangedEventHandler PropertyChanged; 88 private void OnPropertyChanged(string property) { 89 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 90 } 80 91 } 81 92 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/CoordinatesTSPDataView.cs
r17260 r17335 20 20 #endregion 21 21 22 using System.Drawing;23 22 using System.Windows.Forms; 24 23 using HeuristicLab.Core.Views; 25 using HeuristicLab.Data;26 24 using HeuristicLab.MainForm; 27 25 using HeuristicLab.MainForm.WindowsForms; … … 30 28 [View("Coordinates TSP Data View")] 31 29 [Content(typeof(CoordinatesTSPData), IsDefaultView = true)] 32 public partial class CoordinatesTSPDataView : NamedItemView { 30 public partial class CoordinatesTSPDataView : NamedItemView, ITSPVisualizerView { 31 32 private TSPVisualizer visualizer; 33 public TSPVisualizer Visualizer { 34 get => visualizer; 35 set { 36 if (visualizer == value) return; 37 visualizer = value; 38 if (Content != null) { 39 visualizer.Coordinates = Content.Coordinates; 40 } 41 GenerateImage(); 42 } 43 } 33 44 34 45 public new CoordinatesTSPData Content { … … 39 50 public CoordinatesTSPDataView() { 40 51 InitializeComponent(); 52 visualizer = new TSPVisualizer(); 41 53 } 42 54 … … 46 58 coordinatesMatrixView.Content = null; 47 59 coordinatesPictureBox.Image = null; 60 Visualizer.Coordinates = null; 48 61 } else { 49 62 coordinatesMatrixView.Content = Content.Coordinates; 63 Visualizer.Coordinates = Content.Coordinates; 50 64 GenerateImage(); 51 65 } … … 58 72 59 73 protected virtual void GenerateImage() { 60 if (coordinatesPictureBox.Width > 0 && coordinatesPictureBox.Height > 0) { 61 DoubleMatrix coordinates = Content.Coordinates; 62 var xAxis = Content is GeoTSPData ? 1 : 0; 63 var yAxis = 1 - xAxis; 64 var bitmap = new Bitmap(coordinatesPictureBox.Width, coordinatesPictureBox.Height); 65 66 if (coordinates.Rows > 0 && coordinates.Columns == 2) { 67 double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue; 68 for (int i = 0; i < coordinates.Rows; i++) { 69 if (xMin > coordinates[i, xAxis]) xMin = coordinates[i, xAxis]; 70 if (yMin > coordinates[i, yAxis]) yMin = coordinates[i, yAxis]; 71 if (xMax < coordinates[i, xAxis]) xMax = coordinates[i, xAxis]; 72 if (yMax < coordinates[i, yAxis]) yMax = coordinates[i, yAxis]; 73 } 74 75 int border = 20; 76 double xStep = xMax != xMin ? (coordinatesPictureBox.Width - 2 * border) / (xMax - xMin) : 1; 77 double yStep = yMax != yMin ? (coordinatesPictureBox.Height - 2 * border) / (yMax - yMin) : 1; 78 79 Point[] points = new Point[coordinates.Rows]; 80 for (int i = 0; i < coordinates.Rows; i++) 81 points[i] = new Point(border + ((int)((coordinates[i, xAxis] - xMin) * xStep)), 82 bitmap.Height - (border + ((int)((coordinates[i, yAxis] - yMin) * yStep)))); 83 84 using (Graphics graphics = Graphics.FromImage(bitmap)) { 85 for (int i = 0; i < points.Length; i++) 86 graphics.FillRectangle(Brushes.Red, points[i].X - 2, points[i].Y - 2, 6, 6); 87 } 88 } else { 89 using (Graphics graphics = Graphics.FromImage(bitmap)) { 90 graphics.Clear(Color.White); 91 Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular); 92 string text = "No coordinates defined or in wrong format."; 93 SizeF strSize = graphics.MeasureString(text, font); 94 graphics.DrawString(text, font, Brushes.Black, (float)(coordinatesPictureBox.Width - strSize.Width) / 2.0f, (float)(coordinatesPictureBox.Height - strSize.Height) / 2.0f); 95 } 96 } 97 coordinatesPictureBox.Image = bitmap; 98 } 74 coordinatesPictureBox.Image = Visualizer.Draw(coordinatesPictureBox.Width, coordinatesPictureBox.Height); 99 75 } 100 76 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/HeuristicLab.Problems.TravelingSalesman.Views-3.3.csproj
r17251 r17335 135 135 <DependentUpon>EuclideanTSPDataView.cs</DependentUpon> 136 136 </Compile> 137 <Compile Include="ITSPDataView.cs" /> 137 138 <Compile Include="MatrixTSPDataView.cs"> 138 139 <SubType>UserControl</SubType> … … 149 150 <Compile Include="Plugin.cs" /> 150 151 <Compile Include="Properties\AssemblyInfo.cs" /> 152 <Compile Include="TSPVisualizer.cs" /> 151 153 </ItemGroup> 152 154 <ItemGroup> -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/MatrixTSPDataView.cs
r17260 r17335 20 20 #endregion 21 21 22 using System.Drawing;23 22 using System.Windows.Forms; 24 23 using HeuristicLab.Core.Views; 25 using HeuristicLab.Data;26 24 using HeuristicLab.MainForm; 27 25 using HeuristicLab.MainForm.WindowsForms; … … 30 28 [View("Matrix TSP Data View")] 31 29 [Content(typeof(MatrixTSPData), IsDefaultView = true)] 32 public partial class MatrixTSPDataView : NamedItemView { 30 public partial class MatrixTSPDataView : NamedItemView, ITSPVisualizerView { 31 32 private TSPVisualizer visualizer; 33 public TSPVisualizer Visualizer { 34 get => visualizer; 35 set { 36 if (visualizer == value) return; 37 visualizer = value; 38 if (Content != null) { 39 visualizer.Coordinates = Content.DisplayCoordinates; 40 } 41 GenerateImage(); 42 } 43 } 33 44 34 45 public new MatrixTSPData Content { … … 39 50 public MatrixTSPDataView() { 40 51 InitializeComponent(); 52 visualizer = new TSPVisualizer(); 41 53 } 42 54 … … 47 59 coordinatesMatrixView.Content = null; 48 60 coordinatesPictureBox.Image = null; 61 Visualizer.Coordinates = null; 49 62 } else { 50 63 distanceMatrixView.Content = Content.Matrix; 51 64 coordinatesMatrixView.Content = Content.DisplayCoordinates; 65 Visualizer.Coordinates = Content.DisplayCoordinates; 52 66 GenerateImage(); 53 67 } … … 61 75 62 76 protected virtual void GenerateImage() { 63 if (coordinatesPictureBox.Width > 0 && coordinatesPictureBox.Height > 0) { 64 DoubleMatrix coordinates = Content?.DisplayCoordinates; 65 var bitmap = new Bitmap(coordinatesPictureBox.Width, coordinatesPictureBox.Height); 66 67 if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) { 68 double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue; 69 for (int i = 0; i < coordinates.Rows; i++) { 70 if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0]; 71 if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1]; 72 if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0]; 73 if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1]; 74 } 75 76 int border = 20; 77 double xStep = xMax != xMin ? (coordinatesPictureBox.Width - 2 * border) / (xMax - xMin) : 1; 78 double yStep = yMax != yMin ? (coordinatesPictureBox.Height - 2 * border) / (yMax - yMin) : 1; 79 80 Point[] points = new Point[coordinates.Rows]; 81 for (int i = 0; i < coordinates.Rows; i++) 82 points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)), 83 bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep)))); 84 85 using (Graphics graphics = Graphics.FromImage(bitmap)) { 86 for (int i = 0; i < points.Length; i++) 87 graphics.FillRectangle(Brushes.Red, points[i].X - 2, points[i].Y - 2, 6, 6); 88 } 89 } else { 90 using (Graphics graphics = Graphics.FromImage(bitmap)) { 91 graphics.Clear(Color.White); 92 Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular); 93 string text = "No coordinates defined or in wrong format."; 94 SizeF strSize = graphics.MeasureString(text, font); 95 graphics.DrawString(text, font, Brushes.Black, (float)(coordinatesPictureBox.Width - strSize.Width) / 2.0f, (float)(coordinatesPictureBox.Height - strSize.Height) / 2.0f); 96 } 97 } 98 coordinatesPictureBox.Image = bitmap; 99 } 77 coordinatesPictureBox.Image = Visualizer.Draw(coordinatesPictureBox.Width, coordinatesPictureBox.Height); 100 78 } 101 79 } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman.Views/3.3/TSPSolutionView.cs
r17260 r17335 22 22 using System; 23 23 using System.ComponentModel; 24 using System.Drawing;25 24 using System.Windows.Forms; 26 25 using HeuristicLab.Core.Views; 27 using HeuristicLab.Data;28 using HeuristicLab.Encodings.PermutationEncoding;29 26 using HeuristicLab.MainForm; 30 27 … … 35 32 [View("TSP Solution View")] 36 33 [Content(typeof(ITSPSolution), true)] 37 public partial class TSPSolutionView : ItemView { 34 public partial class TSPSolutionView : ItemView, ITSPVisualizerView { 35 public TSPVisualizer Visualizer { get; set; } 36 38 37 public new ITSPSolution Content { 39 38 get { return (ITSPSolution)base.Content; } … … 46 45 public TSPSolutionView() { 47 46 InitializeComponent(); 47 Visualizer = new TSPVisualizer(); 48 48 } 49 49 … … 63 63 pictureBox.Image = null; 64 64 tourViewHost.Content = null; 65 Visualizer.Coordinates = null; 66 Visualizer.Tour = null; 65 67 } else { 66 68 qualityViewHost.Content = Content.TourLength; 69 if (Content.TSPData is CoordinatesTSPData coordTsp) 70 Visualizer.Coordinates = coordTsp.Coordinates; 71 else if (Content.TSPData is MatrixTSPData matrixTsp) 72 Visualizer.Coordinates = matrixTsp.DisplayCoordinates; 73 Visualizer.Tour = Content.Tour; 67 74 GenerateImage(); 68 75 tourViewHost.Content = Content.Tour; … … 82 89 pictureBox.Image = null; 83 90 } else { 84 DoubleMatrix coordinates = Content.Coordinates; 85 Permutation permutation = Content.Tour; 86 Bitmap bitmap = new Bitmap(pictureBox.Width, pictureBox.Height); 87 88 if ((coordinates != null) && (coordinates.Rows > 0) && (coordinates.Columns == 2)) { 89 double xMin = double.MaxValue, yMin = double.MaxValue, xMax = double.MinValue, yMax = double.MinValue; 90 for (int i = 0; i < coordinates.Rows; i++) { 91 if (xMin > coordinates[i, 0]) xMin = coordinates[i, 0]; 92 if (yMin > coordinates[i, 1]) yMin = coordinates[i, 1]; 93 if (xMax < coordinates[i, 0]) xMax = coordinates[i, 0]; 94 if (yMax < coordinates[i, 1]) yMax = coordinates[i, 1]; 95 } 96 97 int border = 20; 98 double xStep = xMax != xMin ? (pictureBox.Width - 2 * border) / (xMax - xMin) : 1; 99 double yStep = yMax != yMin ? (pictureBox.Height - 2 * border) / (yMax - yMin) : 1; 100 101 Point[] points = new Point[coordinates.Rows]; 102 for (int i = 0; i < coordinates.Rows; i++) 103 points[i] = new Point(border + ((int)((coordinates[i, 0] - xMin) * xStep)), 104 bitmap.Height - (border + ((int)((coordinates[i, 1] - yMin) * yStep)))); 105 106 using (Graphics graphics = Graphics.FromImage(bitmap)) { 107 if (permutation != null && permutation.Length > 1) { 108 Point[] tour = new Point[permutation.Length]; 109 for (int i = 0; i < permutation.Length; i++) { 110 if (permutation[i] >= 0 && permutation[i] < points.Length) 111 tour[i] = points[permutation[i]]; 112 } 113 graphics.DrawPolygon(Pens.Black, tour); 114 } 115 for (int i = 0; i < points.Length; i++) 116 graphics.FillRectangle(Brushes.Red, points[i].X - 2, points[i].Y - 2, 6, 6); 117 } 118 } else { 119 using (Graphics graphics = Graphics.FromImage(bitmap)) { 120 graphics.Clear(Color.White); 121 Font font = new Font(FontFamily.GenericSansSerif, 12, FontStyle.Regular); 122 string text = "No coordinates defined or in wrong format."; 123 SizeF strSize = graphics.MeasureString(text, font); 124 graphics.DrawString(text, font, Brushes.Black, (float)(pictureBox.Width - strSize.Width) / 2.0f, (float)(pictureBox.Height - strSize.Height) / 2.0f); 125 } 126 } 127 pictureBox.Image = bitmap; 91 pictureBox.Image = Visualizer.Draw(pictureBox.Width, pictureBox.Height); 128 92 } 129 93 } … … 135 99 else { 136 100 switch (e.PropertyName) { 137 case nameof(Content.Coordinates): 101 case nameof(Content.TSPData): 102 if (Content.TSPData is CoordinatesTSPData coordTsp) 103 Visualizer.Coordinates = coordTsp.Coordinates; 104 else if (Content.TSPData is MatrixTSPData matrixTsp) 105 Visualizer.Coordinates = matrixTsp.DisplayCoordinates; 138 106 GenerateImage(); 139 107 break; 140 108 case nameof(Content.Tour): 109 Visualizer.Tour = Content.Tour; 141 110 GenerateImage(); 142 111 tourViewHost.Content = Content.Tour; -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSP.cs
r17320 r17335 143 143 Description = data.Description; 144 144 145 if (data.Dimension <= DistanceMatrixSizeLimit) { 146 TSPData = new MatrixTSPData(data.Name, data.GetDistanceMatrix(), data.Coordinates) { Description = data.Description }; 147 } else if (data.DistanceMeasure == DistanceMeasure.Direct && data.Distances != null) { 148 TSPData = new MatrixTSPData(data.Name, data.Distances, data.Coordinates) { Description = data.Description }; 149 } else { 150 switch (data.DistanceMeasure) { 151 case DistanceMeasure.Att: 152 TSPData = new AttTSPData(data.Name, data.Coordinates) { Description = data.Description }; 153 break; 154 case DistanceMeasure.Euclidean: 155 TSPData = new EuclideanTSPData(data.Name, data.Coordinates, EuclideanTSPData.DistanceRounding.None) { Description = data.Description }; 156 break; 157 case DistanceMeasure.RoundedEuclidean: 158 TSPData = new EuclideanTSPData(data.Name, data.Coordinates, EuclideanTSPData.DistanceRounding.Midpoint) { Description = data.Description }; 159 break; 160 case DistanceMeasure.UpperEuclidean: 161 TSPData = new EuclideanTSPData(data.Name, data.Coordinates, EuclideanTSPData.DistanceRounding.Ceiling) { Description = data.Description }; 162 break; 163 case DistanceMeasure.Geo: 164 TSPData = new GeoTSPData(data.Name, data.Coordinates) { Description = data.Description }; 165 break; 166 case DistanceMeasure.Manhattan: 167 TSPData = new ManhattanTSPData(data.Name, data.Coordinates) { Description = data.Description }; 168 break; 169 case DistanceMeasure.Maximum: 170 TSPData = new MaximumTSPData(data.Name, data.Coordinates) { Description = data.Description }; 171 break; 172 default: 173 throw new System.IO.InvalidDataException("An unknown distance measure is given in the instance!"); 174 } 175 } 145 TSPData = GetDataFromInstance(data); 176 146 BestKnownSolution = null; 177 147 BestKnownQuality = double.NaN; … … 181 151 var tour = new Permutation(PermutationTypes.RelativeUndirected, data.BestKnownTour); 182 152 var tourLength = Evaluate(tour); 183 BestKnownSolution = new TSPSolution( data.Coordinates != null ? new DoubleMatrix(data.Coordinates) : null, tour, new DoubleValue(tourLength));153 BestKnownSolution = new TSPSolution(TSPData, tour, new DoubleValue(tourLength)); 184 154 BestKnownQuality = tourLength; 185 155 } catch (InvalidOperationException) { … … 191 161 } 192 162 OnReset(); 163 } 164 165 public static ITSPData GetDataFromInstance(TSPData input) { 166 ITSPData tspData = null; 167 if (input.Dimension <= DistanceMatrixSizeLimit) { 168 tspData = new MatrixTSPData(input.Name, input.GetDistanceMatrix(), input.Coordinates) { Description = input.Description }; 169 } else if (input.DistanceMeasure == DistanceMeasure.Direct && input.Distances != null) { 170 tspData = new MatrixTSPData(input.Name, input.Distances, input.Coordinates) { Description = input.Description }; 171 } else { 172 switch (input.DistanceMeasure) { 173 case DistanceMeasure.Att: 174 tspData = new AttTSPData(input.Name, input.Coordinates) { Description = input.Description }; 175 break; 176 case DistanceMeasure.Euclidean: 177 tspData = new EuclideanTSPData(input.Name, input.Coordinates, EuclideanTSPData.DistanceRounding.None) { Description = input.Description }; 178 break; 179 case DistanceMeasure.RoundedEuclidean: 180 tspData = new EuclideanTSPData(input.Name, input.Coordinates, EuclideanTSPData.DistanceRounding.Midpoint) { Description = input.Description }; 181 break; 182 case DistanceMeasure.UpperEuclidean: 183 tspData = new EuclideanTSPData(input.Name, input.Coordinates, EuclideanTSPData.DistanceRounding.Ceiling) { Description = input.Description }; 184 break; 185 case DistanceMeasure.Geo: 186 tspData = new GeoTSPData(input.Name, input.Coordinates) { Description = input.Description }; 187 break; 188 case DistanceMeasure.Manhattan: 189 tspData = new ManhattanTSPData(input.Name, input.Coordinates) { Description = input.Description }; 190 break; 191 case DistanceMeasure.Maximum: 192 tspData = new MaximumTSPData(input.Name, input.Coordinates) { Description = input.Description }; 193 break; 194 default: 195 throw new System.IO.InvalidDataException("An unknown distance measure is given in the instance!"); 196 } 197 } 198 return tspData; 193 199 } 194 200 -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPData.cs
r17254 r17335 40 40 [Item("Matrix-based TSP Data", "TSP that is representd by a distance matrix.")] 41 41 [StorableType("4df58a35-679d-4414-b815-9450ae100823")] 42 public class MatrixTSPData : NamedItem, ITSPData {43 [Storable] public DoubleMatrix Matrix { get; pr otectedset; }44 [Storable] public DoubleMatrix DisplayCoordinates { get; pr otectedset; }42 public sealed class MatrixTSPData : NamedItem, ITSPData { 43 [Storable] public DoubleMatrix Matrix { get; private set; } 44 [Storable] public DoubleMatrix DisplayCoordinates { get; private set; } 45 45 46 46 public int Cities => Matrix.Rows; 47 47 48 48 [StorableConstructor] 49 pr otectedMatrixTSPData(StorableConstructorFlag _) : base(_) { }50 pr otectedMatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) {49 private MatrixTSPData(StorableConstructorFlag _) : base(_) { } 50 private MatrixTSPData(MatrixTSPData original, Cloner cloner) : base(original, cloner) { 51 51 Matrix = original.Matrix; 52 52 DisplayCoordinates = original.DisplayCoordinates; … … 76 76 } 77 77 78 public virtualITSPSolution GetSolution(Permutation tour, double tourLength) {79 return new TSPSolution( DisplayCoordinates, tour, new DoubleValue(tourLength));78 public ITSPSolution GetSolution(Permutation tour, double tourLength) { 79 return new TSPSolution(this, tour, new DoubleValue(tourLength)); 80 80 } 81 81 … … 135 135 136 136 public virtual ITSPSolution GetSolution(Permutation tour, double tourLength) { 137 return new TSPSolution( Coordinates, tour, new DoubleValue(tourLength));137 return new TSPSolution(this, tour, new DoubleValue(tourLength)); 138 138 } 139 139 … … 143 143 [Item("Euclidean TSP Data", "TSP that is represented by coordinates in an Euclidean plane.")] 144 144 [StorableType("4bf58348-cd98-46c5-a4c0-55f486ca88b4")] 145 public class EuclideanTSPData : CoordinatesTSPData {145 public sealed class EuclideanTSPData : CoordinatesTSPData { 146 146 public enum DistanceRounding { None, Midpoint, Ceiling } 147 147 148 148 [Storable] 149 public DistanceRounding Rounding { get; pr otectedset; }150 151 [StorableConstructor] 152 pr otectedEuclideanTSPData(StorableConstructorFlag _) : base(_) { }153 pr otectedEuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) {149 public DistanceRounding Rounding { get; private set; } 150 151 [StorableConstructor] 152 private EuclideanTSPData(StorableConstructorFlag _) : base(_) { } 153 private EuclideanTSPData(EuclideanTSPData original, Cloner cloner) : base(original, cloner) { 154 154 Rounding = original.Rounding; 155 155 } … … 199 199 [Item("Geo TSP Data", "TSP that is represented by geo coordinates.")] 200 200 [StorableType("dc859a89-e6c2-4af3-a3b6-9aa3041b14a9")] 201 public class GeoTSPData : CoordinatesTSPData {202 [StorableConstructor] 203 pr otectedGeoTSPData(StorableConstructorFlag _) : base(_) { }204 pr otectedGeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { }201 public sealed class GeoTSPData : CoordinatesTSPData { 202 [StorableConstructor] 203 private GeoTSPData(StorableConstructorFlag _) : base(_) { } 204 private GeoTSPData(GeoTSPData original, Cloner cloner) : base(original, cloner) { } 205 205 public GeoTSPData() : base() { } 206 206 public GeoTSPData(string name, double[,] coordinates) : base(name, coordinates) { } … … 228 228 [Item("ATT TSP Data", "TSP that is represented by ATT coordinates.")] 229 229 [StorableType("d7a0add3-6ec1-42e0-b1d7-b6454694d485")] 230 public class AttTSPData : CoordinatesTSPData {231 [StorableConstructor] 232 pr otectedAttTSPData(StorableConstructorFlag _) : base(_) { }233 pr otectedAttTSPData(AttTSPData original, Cloner cloner) : base(original, cloner) { }230 public sealed class AttTSPData : CoordinatesTSPData { 231 [StorableConstructor] 232 private AttTSPData(StorableConstructorFlag _) : base(_) { } 233 private AttTSPData(AttTSPData original, Cloner cloner) : base(original, cloner) { } 234 234 public AttTSPData() : base() { } 235 235 public AttTSPData(string name, double[,] coordinates) : base(name, coordinates) { } … … 257 257 [Item("Manhattan TSP Data", "TSP that is represented by Manhattan coordinates.")] 258 258 [StorableType("5f1ef9e2-cbd1-400e-8f87-6855f091fc9e")] 259 public class ManhattanTSPData : CoordinatesTSPData {260 [StorableConstructor] 261 pr otectedManhattanTSPData(StorableConstructorFlag _) : base(_) { }262 pr otectedManhattanTSPData(ManhattanTSPData original, Cloner cloner) : base(original, cloner) { }259 public sealed class ManhattanTSPData : CoordinatesTSPData { 260 [StorableConstructor] 261 private ManhattanTSPData(StorableConstructorFlag _) : base(_) { } 262 private ManhattanTSPData(ManhattanTSPData original, Cloner cloner) : base(original, cloner) { } 263 263 public ManhattanTSPData() : base() { } 264 264 public ManhattanTSPData(string name, double[,] coordinates) : base(name, coordinates) { } … … 286 286 [Item("Manhattan TSP Data", "TSP that is represented by the maximum absolute distance in either x or y coordinates.")] 287 287 [StorableType("c6294a6c-fe62-4906-9765-4bc306d3e4a8")] 288 public class MaximumTSPData : CoordinatesTSPData {289 [StorableConstructor] 290 pr otectedMaximumTSPData(StorableConstructorFlag _) : base(_) { }291 pr otectedMaximumTSPData(MaximumTSPData original, Cloner cloner) : base(original, cloner) { }288 public sealed class MaximumTSPData : CoordinatesTSPData { 289 [StorableConstructor] 290 private MaximumTSPData(StorableConstructorFlag _) : base(_) { } 291 private MaximumTSPData(MaximumTSPData original, Cloner cloner) : base(original, cloner) { } 292 292 public MaximumTSPData() : base() { } 293 293 public MaximumTSPData(string name, double[,] coordinates) : base(name, coordinates) { } -
branches/2521_ProblemRefactoring/HeuristicLab.Problems.TravelingSalesman/3.3/TSPSolution.cs
r17260 r17335 31 31 [StorableType("f08a63d9-0b83-4944-9251-42925baeb872")] 32 32 public interface ITSPSolution : IItem, INotifyPropertyChanged { 33 DoubleMatrix Coordinates{ get; }33 ITSPData TSPData { get; } 34 34 Permutation Tour { get; } 35 35 DoubleValue TourLength { get; } … … 41 41 [Item("TSP Solution", "Represents a tour of a Traveling Salesman Problem given in path representation which can be visualized in the GUI.")] 42 42 [StorableType("38d1aac3-3047-40d9-bcf9-4b3ca0b9f95c")] 43 public class TSPSolution : Item, ITSPSolution {43 public sealed class TSPSolution : Item, ITSPSolution { 44 44 public static new Image StaticItemImage { 45 45 get { return HeuristicLab.Common.Resources.VSImageLibrary.Image; } … … 47 47 48 48 [Storable] 49 private DoubleMatrix coordinates;50 public DoubleMatrix Coordinates{51 get { return coordinates; }49 private ITSPData tspData; 50 public ITSPData TSPData { 51 get { return tspData; } 52 52 set { 53 if ( coordinates== value) return;54 coordinates= value;55 OnPropertyChanged(nameof( Coordinates));53 if (tspData == value) return; 54 tspData = value; 55 OnPropertyChanged(nameof(TSPData)); 56 56 } 57 57 } … … 79 79 80 80 [StorableConstructor] 81 pr otectedTSPSolution(StorableConstructorFlag _) : base(_) { }82 pr otectedTSPSolution(TSPSolution original, Cloner cloner)81 private TSPSolution(StorableConstructorFlag _) : base(_) { } 82 private TSPSolution(TSPSolution original, Cloner cloner) 83 83 : base(original, cloner) { 84 this. coordinates = cloner.Clone(original.coordinates);84 this.tspData = cloner.Clone(original.tspData); 85 85 this.tour = cloner.Clone(original.tour); 86 86 this.tourLength = cloner.Clone(original.tourLength); 87 87 } 88 88 public TSPSolution() : base() { } 89 public TSPSolution( DoubleMatrix coordinates)89 public TSPSolution(ITSPData data) 90 90 : base() { 91 this. coordinates = coordinates;91 this.tspData = data; 92 92 } 93 public TSPSolution( DoubleMatrix coordinates, Permutation permutation)93 public TSPSolution(ITSPData data, Permutation permutation) 94 94 : base() { 95 this. coordinates = coordinates;95 this.tspData = data; 96 96 this.tour = permutation; 97 97 } 98 public TSPSolution( DoubleMatrix coordinates, Permutation permutation, DoubleValue quality)98 public TSPSolution(ITSPData data, Permutation permutation, DoubleValue quality) 99 99 : base() { 100 this. coordinates = coordinates;100 this.tspData = data; 101 101 this.tour = permutation; 102 102 this.tourLength = quality; … … 108 108 109 109 public event PropertyChangedEventHandler PropertyChanged; 110 pr otectedvoid OnPropertyChanged(string property) {110 private void OnPropertyChanged(string property) { 111 111 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 112 112 }
Note: See TracChangeset
for help on using the changeset viewer.