1  #region License Information


2  /* HeuristicLab


3  * Copyright (C) 20022017 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;


23  using HeuristicLab.Data;


24  using HeuristicLab.Encodings.IntegerVectorEncoding;


25  using HeuristicLab.Problems.GeneralizedQuadraticAssignment;


26  using HeuristicLab.Random;


27  using Microsoft.VisualStudio.TestTools.UnitTesting;


28 


29  namespace 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)) < 1e07, "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)) < 1e07, "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)) < 1e07, "Failed on nonzero 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  }

