- Timestamp:
- 04/02/11 16:45:04 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/QAP/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs
r5871 r5931 29 29 /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method 30 30 /// to fit the coordinates such that the difference between the fit distances 31 /// and the actual distances becomes minimal.31 /// and the dissimilarities becomes minimal. 32 32 /// </summary> 33 33 /// <remarks> 34 34 /// It will initialize the coordinates in a deterministic fashion such that all initial points are equally spaced on a circle. 35 35 /// </remarks> 36 /// <param name="dissimilarities">A symmetric NxN matrix that specifies the dis tances between each element i and j. Diagonal elements are ignored.</param>36 /// <param name="dissimilarities">A symmetric NxN matrix that specifies the dissimilarities between each element i and j. Diagonal elements are ignored.</param> 37 37 /// 38 38 /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns> … … 43 43 int dimension = dissimilarities.Rows; 44 44 if (dimension == 1) return new DoubleMatrix(new double[,] { { 0, 0 } }); 45 else if (dimension == 2) return new DoubleMatrix(new double[,] { { 0, dissimilarities[0, 1] } });45 else if (dimension == 2) return new DoubleMatrix(new double[,] { { 0, 0 }, { 0, dissimilarities[0, 1] } }); 46 46 47 47 DoubleMatrix coordinates = new DoubleMatrix(dimension, 2); … … 58 58 /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method 59 59 /// to fit the coordinates such that the difference between the fit distances 60 /// and the actual distances is minimal.60 /// and the dissimilarities is minimal. 61 61 /// </summary> 62 62 /// <remarks> 63 63 /// It will use a pre-initialized x,y-coordinates matrix as a starting point of the gradient descent. 64 64 /// </remarks> 65 /// <param name="dissimilarities">A symmetric NxN matrix that specifies the distances between each element i and j. Diagonal elements are ignored.</param> 66 /// 65 /// <param name="dissimilarities">A symmetric NxN matrix that specifies the dissimilarities between each element i and j. Diagonal elements are ignored.</param> 67 66 /// <param name="coordinates">The Nx2 matrix of initial coordinates.</param> 67 /// <param name="maximumIterations">The number of iterations for which the algorithm should run. 68 /// In every iteration it tries to find the best location for every item.</param> 68 69 /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns> 69 public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities, DoubleMatrix coordinates ) {70 public static DoubleMatrix KruskalShepard(DoubleMatrix dissimilarities, DoubleMatrix coordinates, int maximumIterations = 100) { 70 71 int dimension = dissimilarities.Rows; 71 72 if (dimension != dissimilarities.Columns || coordinates.Rows != dimension) throw new ArgumentException("The number of coordinates and the number of rows and columns in the dissimilarities matrix do not match."); … … 78 79 alglib.mincgreport rep; 79 80 80 for (int iterations = 0; iterations < 10; iterations++) { 81 for (int iterations = 0; iterations < maximumIterations; iterations++) { 82 bool changed = false; 81 83 for (int i = 0; i < dimension; i++) { 82 84 double[] c = new double[] { coordinates[i, 0], coordinates[i, 1] }; … … 93 95 } catch (alglib.alglibexception) { } 94 96 if (!double.IsNaN(c[0]) && !double.IsNaN(c[1])) { 97 changed = changed || (coordinates[i, 0] != c[0]) || (coordinates[i, 1] != c[1]); 95 98 coordinates[i, 0] = c[0]; 96 99 coordinates[i, 1] = c[1]; 97 100 } 98 101 } 102 if (!changed) break; 99 103 } 100 104 return coordinates; … … 106 110 Info info = (obj as Info); 107 111 for (int i = 0; i < info.Coordinates.Rows; i++) { 108 double c = info.Dis tances[info.Row, i];112 double c = info.Dissimilarities[info.Row, i]; 109 113 if (i != info.Row) { 110 114 double a = info.Coordinates[i, 0]; … … 143 147 for (int i = 0; i < dimension - 1; i++) { 144 148 for (int j = i + 1; j < dimension; j++) { 145 if (dissimilarities[i, j] != dissimilarities[j, i]) throw new ArgumentException("Dis tances is not a symmetric matrix.", "distances");149 if (dissimilarities[i, j] != dissimilarities[j, i]) throw new ArgumentException("Dissimilarities is not a symmetric matrix.", "dissimilarities"); 146 150 if (dissimilarities[i, j] != 0) { 147 151 stress += Stress(coordinates[i, 0], coordinates[i, 1], dissimilarities[i, j], coordinates[j, 0], coordinates[j, 1]); … … 155 159 private class Info { 156 160 public DoubleMatrix Coordinates { get; set; } 157 public DoubleMatrix Dis tances { get; set; }161 public DoubleMatrix Dissimilarities { get; set; } 158 162 public int Row { get; set; } 159 163 160 164 public Info(DoubleMatrix c, DoubleMatrix d, int r) { 161 165 Coordinates = c; 162 Dis tances = d;166 Dissimilarities = d; 163 167 Row = r; 164 168 }
Note: See TracChangeset
for help on using the changeset viewer.