Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
04/02/11 16:45:04 (14 years ago)
Author:
abeham
Message:

#1330

  • changes according to the review
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/QAP/HeuristicLab.Analysis/3.3/MultidimensionalScaling/MultidimensionalScaling.cs

    r5871 r5931  
    2929    /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method
    3030    /// 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.
    3232    /// </summary>
    3333    /// <remarks>
    3434    /// It will initialize the coordinates in a deterministic fashion such that all initial points are equally spaced on a circle.
    3535    /// </remarks>
    36     /// <param name="dissimilarities">A symmetric NxN matrix that specifies the distances 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>
    3737    ///
    3838    /// <returns>A Nx2 matrix where the first column represents the x- and the second column the y coordinates.</returns>
     
    4343      int dimension = dissimilarities.Rows;
    4444      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] } });
    4646
    4747      DoubleMatrix coordinates = new DoubleMatrix(dimension, 2);
     
    5858    /// Performs the Kruskal-Shepard algorithm and applies a gradient descent method
    5959    /// 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.
    6161    /// </summary>
    6262    /// <remarks>
    6363    /// It will use a pre-initialized x,y-coordinates matrix as a starting point of the gradient descent.
    6464    /// </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>
    6766    /// <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>
    6869    /// <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) {
    7071      int dimension = dissimilarities.Rows;
    7172      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.");
     
    7879      alglib.mincgreport rep;
    7980
    80       for (int iterations = 0; iterations < 10; iterations++) {
     81      for (int iterations = 0; iterations < maximumIterations; iterations++) {
     82        bool changed = false;
    8183        for (int i = 0; i < dimension; i++) {
    8284          double[] c = new double[] { coordinates[i, 0], coordinates[i, 1] };
     
    9395          } catch (alglib.alglibexception) { }
    9496          if (!double.IsNaN(c[0]) && !double.IsNaN(c[1])) {
     97            changed = changed || (coordinates[i, 0] != c[0]) || (coordinates[i, 1] != c[1]);
    9598            coordinates[i, 0] = c[0];
    9699            coordinates[i, 1] = c[1];
    97100          }
    98101        }
     102        if (!changed) break;
    99103      }
    100104      return coordinates;
     
    106110      Info info = (obj as Info);
    107111      for (int i = 0; i < info.Coordinates.Rows; i++) {
    108         double c = info.Distances[info.Row, i];
     112        double c = info.Dissimilarities[info.Row, i];
    109113        if (i != info.Row) {
    110114          double a = info.Coordinates[i, 0];
     
    143147      for (int i = 0; i < dimension - 1; i++) {
    144148        for (int j = i + 1; j < dimension; j++) {
    145           if (dissimilarities[i, j] != dissimilarities[j, i]) throw new ArgumentException("Distances is not a symmetric matrix.", "distances");
     149          if (dissimilarities[i, j] != dissimilarities[j, i]) throw new ArgumentException("Dissimilarities is not a symmetric matrix.", "dissimilarities");
    146150          if (dissimilarities[i, j] != 0) {
    147151            stress += Stress(coordinates[i, 0], coordinates[i, 1], dissimilarities[i, j], coordinates[j, 0], coordinates[j, 1]);
     
    155159    private class Info {
    156160      public DoubleMatrix Coordinates { get; set; }
    157       public DoubleMatrix Distances { get; set; }
     161      public DoubleMatrix Dissimilarities { get; set; }
    158162      public int Row { get; set; }
    159163
    160164      public Info(DoubleMatrix c, DoubleMatrix d, int r) {
    161165        Coordinates = c;
    162         Distances = d;
     166        Dissimilarities = d;
    163167        Row = r;
    164168      }
Note: See TracChangeset for help on using the changeset viewer.