source: branches/1614_GeneralizedQAP/UnitTests/GQAPNMoveEvaluatorTest.cs @ 15713

Last change on this file since 15713 was 15504, checked in by abeham, 4 years ago

#1614: refactored code

  • change problem to derive from basic problem
  • using a combined instance class instead of individual parameters
File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2017 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
22using System;
23using HeuristicLab.Data;
24using HeuristicLab.Encodings.IntegerVectorEncoding;
25using HeuristicLab.Problems.GeneralizedQuadraticAssignment;
26using HeuristicLab.Random;
27using Microsoft.VisualStudio.TestTools.UnitTesting;
28
29namespace UnitTests {
30  /// <summary>
31  ///This is a test class for GQAPNMoveEvaluatorTest and is intended
32  ///to contain all GQAPNMoveEvaluatorTest Unit Tests
33  ///</summary>
34  [TestClass()]
35  public class GQAPNMoveEvaluatorTest {
36    private const int Equipments = 10, Locations = 5;
37    private static GQAPInstance symmetricInstance, asymmetricInstance, nonZeroDiagonalInstance;
38    private static IntegerVector assignment;
39    private static MersenneTwister random;
40
41    private TestContext testContextInstance;
42
43    /// <summary>
44    ///Gets or sets the test context which provides
45    ///information about and functionality for the current test run.
46    ///</summary>
47    public TestContext TestContext {
48      get { return testContextInstance; }
49      set { testContextInstance = value; }
50    }
51
52    #region Additional test attributes
53    [ClassInitialize()]
54    public static void MyClassInitialize(TestContext testContext) {
55      random = new MersenneTwister();
56      var symmetricDistances = new DoubleMatrix(Locations, Locations);
57      var symmetricWeights = new DoubleMatrix(Equipments, Equipments);
58      var asymmetricDistances = new DoubleMatrix(Locations, Locations);
59      var asymmetricWeights = new DoubleMatrix(Equipments, Equipments);
60      var nonZeroDiagonalDistances = new DoubleMatrix(Locations, Locations);
61      var nonZeroDiagonalWeights = new DoubleMatrix(Equipments, Equipments);
62      for (int i = 0; i < Equipments - 1; i++) {
63        for (int j = i + 1; j < Equipments; j++) {
64          symmetricWeights[i, j] = random.Next(Equipments * 100);
65          symmetricWeights[j, i] = symmetricWeights[i, j];
66          asymmetricWeights[i, j] = random.Next(Equipments * 100);
67          asymmetricWeights[j, i] = random.Next(Equipments * 100);
68          nonZeroDiagonalWeights[i, j] = random.Next(Equipments * 100);
69          nonZeroDiagonalWeights[j, i] = random.Next(Equipments * 100);
70        }
71        nonZeroDiagonalWeights[i, i] = random.Next(Equipments * 100);
72      }
73      for (int i = 0; i < Locations - 1; i++) {
74        for (int j = i + 1; j < Locations; j++) {
75          symmetricDistances[i, j] = random.Next(Locations * 100);
76          symmetricDistances[j, i] = symmetricDistances[i, j];
77          asymmetricDistances[i, j] = random.Next(Locations * 100);
78          asymmetricDistances[j, i] = random.Next(Locations * 100);
79          nonZeroDiagonalDistances[i, j] = random.Next(Locations * 100);
80          nonZeroDiagonalDistances[j, i] = random.Next(Locations * 100);
81        }
82        nonZeroDiagonalDistances[i, i] = random.Next(Locations * 100);
83      }
84      var installationCosts = new DoubleMatrix(Equipments, Locations);
85      for (int i = 0; i < Equipments; i++) {
86        for (int j = 0; j < Locations; j++) {
87          installationCosts[i, j] = random.Next(0, 10);
88        }
89      }
90      var demands = new DoubleArray(Equipments);
91      for (int i = 0; i < Equipments; i++) {
92        demands[i] = random.Next(1, 10);
93      }
94      var capacities = new DoubleArray(Locations);
95      for (int j = 0; j < Locations; j++) {
96        capacities[j] = random.Next(1, 10) * ((double)Equipments / (double)Locations) * 1.5;
97      }
98      int index = random.Next(Locations);
99      if (nonZeroDiagonalDistances[index, index] == 0)
100        nonZeroDiagonalDistances[index, index] = random.Next(1, Equipments * 100);
101      index = random.Next(Equipments);
102      if (nonZeroDiagonalWeights[index, index] == 0)
103        nonZeroDiagonalWeights[index, index] = random.Next(1, Equipments * 100);
104
105      var transportationCosts = random.NextDouble() * 10;
106      var overbookedCapacityPenalty = 1000 * random.NextDouble() + 100;
107      assignment = new IntegerVector(Equipments, random, 0, Locations);
108
109      symmetricInstance = new GQAPInstance() {
110        Capacities = capacities,
111        Demands = demands,
112        InstallationCosts = installationCosts,
113        PenaltyLevel = overbookedCapacityPenalty,
114        TransportationCosts = transportationCosts,
115        Weights = symmetricWeights,
116        Distances = symmetricDistances
117      };
118      asymmetricInstance = new GQAPInstance() {
119        Capacities = capacities,
120        Demands = demands,
121        InstallationCosts = installationCosts,
122        PenaltyLevel = overbookedCapacityPenalty,
123        TransportationCosts = transportationCosts,
124        Weights = asymmetricWeights,
125        Distances = asymmetricDistances
126      };
127      nonZeroDiagonalInstance = new GQAPInstance() {
128        Capacities = capacities,
129        Demands = demands,
130        InstallationCosts = installationCosts,
131        PenaltyLevel = overbookedCapacityPenalty,
132        TransportationCosts = transportationCosts,
133        Weights = nonZeroDiagonalWeights,
134        Distances = nonZeroDiagonalDistances
135      };
136    }
137    #endregion
138
139
140    /// <summary>
141    ///A test for Evaluate
142    ///</summary>
143    [TestMethod()]
144    public void EvaluateTest() {
145      for (int i = 0; i < 500; i++) {
146        NMove currentMove = StochasticNMoveSingleMoveGenerator.GenerateUpToN(random, assignment, 3, symmetricInstance.Capacities);
147        IntegerVector prevAssignment = (IntegerVector)assignment.Clone();
148        NMoveMaker.Apply(assignment, currentMove);
149        var beforeEval = symmetricInstance.Evaluate(prevAssignment);
150        double before = symmetricInstance.ToSingleObjective(beforeEval);
151        double after = Evaluate(symmetricInstance, assignment);
152        double moveDiff = symmetricInstance.ToSingleObjective(
153          GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, beforeEval, symmetricInstance)
154          ) - symmetricInstance.ToSingleObjective(beforeEval);
155        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on symmetric matrices: " + Environment.NewLine
156          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
157
158        beforeEval = asymmetricInstance.Evaluate(prevAssignment);
159        before = asymmetricInstance.ToSingleObjective(beforeEval);
160        after = Evaluate(asymmetricInstance, assignment);
161        moveDiff = asymmetricInstance.ToSingleObjective(
162          GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, beforeEval, asymmetricInstance)
163          ) - asymmetricInstance.ToSingleObjective(beforeEval);
164        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on asymmetric matrices: " + Environment.NewLine
165          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
166
167        beforeEval = nonZeroDiagonalInstance.Evaluate(prevAssignment);
168        before = nonZeroDiagonalInstance.ToSingleObjective(beforeEval);
169        after = Evaluate(nonZeroDiagonalInstance, assignment);
170        moveDiff = nonZeroDiagonalInstance.ToSingleObjective(
171          GQAPNMoveEvaluator.Evaluate(currentMove, prevAssignment, beforeEval, nonZeroDiagonalInstance)
172          ) - nonZeroDiagonalInstance.ToSingleObjective(beforeEval);
173        Assert.IsTrue(Math.Abs(moveDiff - (after - before)) < 1e-07, "Failed on non-zero diagonal matrices: " + Environment.NewLine
174          + "Quality changed from " + before + " to " + after + " (" + (after - before).ToString() + "), but move quality change was " + moveDiff + ".");
175      }
176    }
177
178    private double Evaluate(GQAPInstance instance, IntegerVector assignment) {
179      return instance.ToSingleObjective(instance.Evaluate(assignment));
180    }
181  }
182}
Note: See TracBrowser for help on using the repository browser.