Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2817-BinPackingSpeedup/HeuristicLab.Tests/HeuristicLab.Problems.Bin-Packing-3.3/AlgorithmTest.cs @ 15428

Last change on this file since 15428 was 15424, checked in by rhanghof, 7 years ago

#2817:

  • Added some comments and regions to the source code
  • Addes reference instance files created by the test algoritm of S. Martello, D. Pisinger, D. Vigo
File size: 13.5 KB
Line 
1using System;
2using System.IO;
3using Microsoft.VisualStudio.TestTools.UnitTesting;
4using HeuristicLab.Problems.BinPacking3D;
5using System.Collections.Generic;
6using System.Linq;
7using HeuristicLab.Core;
8
9namespace HeuristicLab.Problems.BinPacking.Tests {
10  [TestClass]
11  public class AlgorithmTest {
12
13    private struct Dimension {
14      public int Id { get; set; }
15      public int Width { get; set; }
16      public int Height { get; set; }
17      public int Depth { get; set; }
18    }
19
20    #region TestRandomInstanceProvider
21
22
23    /// <summary>
24    /// Tests if the generated random instance equals to the references generated by david pisinger
25    /// http://www.diku.dk/~pisinger/new3dbpp/test3dbpp.c
26    /// </summary>
27    [TestMethod]
28    [TestCategory("Problems.BinPacking")]
29    public void TestRandomInstanceProvider() {
30
31      var referenceItemLists = ReadReferenceItemLists();
32      TestRandomInstanceProviderByClass(new RandomInstanceClass1ProviderWithSRand(), referenceItemLists);
33      TestRandomInstanceProviderByClass(new RandomInstanceClass2ProviderWithSRand(), referenceItemLists);
34      TestRandomInstanceProviderByClass(new RandomInstanceClass3ProviderWithSRand(), referenceItemLists);
35      TestRandomInstanceProviderByClass(new RandomInstanceClass4ProviderWithSRand(), referenceItemLists);
36      TestRandomInstanceProviderByClass(new RandomInstanceClass5ProviderWithSRand(), referenceItemLists);
37      TestRandomInstanceProviderByClass(new RandomInstanceClass6ProviderWithSRand(), referenceItemLists);
38      TestRandomInstanceProviderByClass(new RandomInstanceClass7ProviderWithSRand(), referenceItemLists);
39      TestRandomInstanceProviderByClass(new RandomInstanceClass8ProviderWithSRand(), referenceItemLists);
40
41    }
42
43    private IDictionary<string, List<Dimension>> ReadReferenceItemLists() {
44      var itemList = new Dictionary<string, List<Dimension>>();
45      string path = @".\..\HeuristicLab.Tests\HeuristicLab.Problems.Bin-Packing-3.3\ReferenceInstances";
46
47      string[] files = Directory.GetFiles(path);
48      foreach (string filePath in files) {
49        string key = Path.GetFileNameWithoutExtension(filePath);
50
51        using (StreamReader reader = new StreamReader(filePath)) {
52          int lineNumber = 1;
53          List<Dimension> dimensionList = new List<Dimension>();
54          while (!reader.EndOfStream) {
55            string line = reader.ReadLine();
56            if (lineNumber > 2) {
57              string[] lineValues = line.Split('\t');
58              int id;
59              int depth;
60              int width;
61              int height;
62              Int32.TryParse(lineValues[0], out id);
63              Int32.TryParse(lineValues[1], out depth);
64              Int32.TryParse(lineValues[2], out width);
65              Int32.TryParse(lineValues[3], out height);
66              dimensionList.Add(new Dimension() {
67                Id = id,
68                Depth = depth,
69                Width = width,
70                Height = height
71              });
72            }
73            lineNumber++;
74          }
75          itemList.Add(key, dimensionList);
76        }
77      }
78      return itemList;
79    }
80
81    private void TestRandomInstanceProviderByClass(RandomInstanceProviderWithSRand randomInstanceProvider, IDictionary<string, List<Dimension>> referenceItems) {
82
83      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
84      foreach (var dataDescriptor in dataDescriptors) {
85        List<Dimension> testItemDimensions = null;
86        if (referenceItems.TryGetValue(dataDescriptor.Name, out testItemDimensions)) {
87          var packingItems = randomInstanceProvider.LoadData(dataDescriptor).Items;
88          Assert.IsNotNull(packingItems);
89          Assert.AreEqual(testItemDimensions.Count, packingItems.Length);
90          for (int i = 0; i < packingItems.Length; i++) {
91            Assert.AreEqual(testItemDimensions[i].Width, packingItems[i].Width);
92            Assert.AreEqual(testItemDimensions[i].Height, packingItems[i].Height);
93            Assert.AreEqual(testItemDimensions[i].Depth, packingItems[i].Depth);
94          }
95        }
96      }
97    }
98    #endregion
99
100    #region TestExtremePointAlgorithm
101
102    /// <summary>
103    /// Constants for testing the algorithm
104    /// The test parameters are defined in the paper
105    /// </summary>
106    private const int NUMBER_OF_TEST_INSTANCES = 10;
107    private static readonly int[] TEST_CLASSES = { 1, 2 };
108    private static readonly int[] NUMBER_OF_TEST_ITEMS = { 50, 100, 150, 200 };
109
110    [TestMethod]
111    [TestCategory("Problems.BinPacking")]
112    public void TestExtremePointAlgorithmClass1() {
113      TestExtremePointAlgorithm(new RandomInstanceClass1ProviderWithSRand(), 1);
114    }
115
116    [TestMethod]
117    [TestCategory("Problems.BinPacking")]
118    public void TestExtremePointAlgorithmClass2() {
119      TestExtremePointAlgorithm(new RandomInstanceClass2ProviderWithSRand(), 2);
120    }
121
122    [TestMethod]
123    [TestCategory("Problems.BinPacking")]
124    public void TestExtremePointAlgorithmClass3() {
125      TestExtremePointAlgorithm(new RandomInstanceClass3ProviderWithSRand(), 3);
126    }
127
128    [TestMethod]
129    [TestCategory("Problems.BinPacking")]
130    public void TestExtremePointAlgorithmClass4() {
131      TestExtremePointAlgorithm(new RandomInstanceClass4ProviderWithSRand(), 4);
132    }
133
134    [TestMethod]
135    [TestCategory("Problems.BinPacking")]
136    public void TestExtremePointAlgorithmClass5() {
137      TestExtremePointAlgorithm(new RandomInstanceClass5ProviderWithSRand(), 5);
138    }
139
140    [TestMethod]
141    [TestCategory("Problems.BinPacking")]
142    public void TestExtremePointAlgorithmClass6() {
143      TestExtremePointAlgorithm(new RandomInstanceClass6ProviderWithSRand(), 6);
144    }
145
146    [TestMethod]
147    [TestCategory("Problems.BinPacking")]
148    public void TestExtremePointAlgorithmClass7() {
149      TestExtremePointAlgorithm(new RandomInstanceClass7ProviderWithSRand(), 7);
150    }
151
152    [TestMethod]
153    [TestCategory("Problems.BinPacking")]
154    public void TestExtremePointAlgorithmClass8() {
155      TestExtremePointAlgorithm(new RandomInstanceClass8ProviderWithSRand(), 8);
156    }
157
158    private void TestExtremePointAlgorithm(RandomInstanceProviderWithSRand randomInstanceProvider, int @class) {
159      foreach (SortingMethod sortingMethod in Enum.GetValues(typeof(SortingMethod))) {
160        //foreach (FittingMethod fittingMethod in Enum.GetValues(typeof(FittingMethod))) {
161        FittingMethod fittingMethod = FittingMethod.FirstFit;
162        TestExtremePointAlgorithmByParameters(randomInstanceProvider, @class, sortingMethod, fittingMethod);
163        //}
164      }
165    }
166
167
168
169
170    private void TestExtremePointAlgorithmByParameters(RandomInstanceProviderWithSRand randomInstanceProvider, int @class, SortingMethod sortingMethod, FittingMethod fittingMethod) {
171      var dataDescriptors = randomInstanceProvider.GetDataDescriptors();
172      var referenceValues = GetReferenceAlgorithmValues();
173      foreach (var numItems in NUMBER_OF_TEST_ITEMS) {
174        int sumNumberOfBins = 0;
175        for (int instance = 1; instance <= NUMBER_OF_TEST_INSTANCES; instance++) {
176          string name = string.Format("n={0}-id={1:00} (class={2})", numItems, instance, @class);
177          var selectedDataDescriptor = dataDescriptors.Where(dataDescriptor => dataDescriptor.Name == name);
178          Assert.IsNotNull(selectedDataDescriptor?.First());
179          var packingData = randomInstanceProvider.LoadData(selectedDataDescriptor.First());
180
181          ExtremePointAlgorithm algorithm = new ExtremePointAlgorithm();
182          algorithm.SortingMethodParameter.Value.Value = sortingMethod;
183          algorithm.FittingMethodParameter.Value.Value = fittingMethod;
184          algorithm.Problem.Load(packingData);
185
186          algorithm.Start();
187
188          PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem> bestPackingPlan = null;
189          foreach (Optimization.IResult result in algorithm.Results) {
190            if (result.Name == "Best Solution") {
191              bestPackingPlan = (PackingPlan<BinPacking3D.PackingPosition, PackingShape, PackingItem>)result.Value;
192              break;
193            }
194          }
195
196          sumNumberOfBins += bestPackingPlan.NrOfBins;
197        }
198
199        double referenceValue = 0.0;
200
201        if (referenceValues.TryGetValue(new Tuple<int, int, SortingMethod>(@class, numItems, sortingMethod), out referenceValue)) {
202          Console.WriteLine($"{numItems}-{@class}-{sortingMethod}: \t{referenceValue} \t {(double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES} \t{(referenceValue - ((double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES)):F2}");
203          Assert.AreEqual(referenceValue, (double)sumNumberOfBins / (double)NUMBER_OF_TEST_INSTANCES, 10.0);
204        }
205      }
206    }
207
208
209    /// <summary>
210    /// Returns a dictionary which contains the reference values from table 2 given by the paper https://www.cirrelt.ca/DocumentsTravail/CIRRELT-2007-41.pdf
211    /// Dictionary<Tuple<int, int, SortingMethod>, double> -> Dictionary<Tuple<@class, number of items, SortingMethod>, value>
212    /// </summary>
213    /// <returns></returns>
214    private Dictionary<Tuple<int, int, SortingMethod>, double> GetReferenceAlgorithmValues() {
215      Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues = new Dictionary<Tuple<int, int, SortingMethod>, double>();
216
217      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.Given, new double[] { 14.6, 29.2, 40.1, 55.9});
218      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightVolume, new double[] { 15, 29.2, 39.9, 55.6 });
219      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.VolumeHeight, new double[] { 14.4, 29.5, 40.3, 55.7 });
220      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.AreaHeight, new double[] { 14.4, 28.3, 39.2, 53.2 });
221      AddToReferenceAlgorithmValuesDict(referenceValues, 1, SortingMethod.HeightArea, new double[] { 15, 29, 39.8, 55.1});
222
223      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.Given, new double[] { 29.7, 60.2, 88.5, 119.9 });
224      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightVolume, new double[] { 30.1, 59.6, 88.3, 120.1 });
225      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.VolumeHeight, new double[] { 29.9, 60.4, 88.6, 119.6 });
226      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.AreaHeight, new double[] { 30, 59.7, 88.4, 120.3 });
227      AddToReferenceAlgorithmValuesDict(referenceValues, 4, SortingMethod.HeightArea, new double[] { 30, 59.6, 88.3, 120 });
228
229      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.Given, new double[] { 10.1, 18.1, 24.4, 32.5 });
230      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightVolume, new double[] { 9, 16.7, 22.9, 30.7});
231      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.VolumeHeight, new double[] { 10, 17.8, 24.5, 32.6 });
232      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.AreaHeight, new double[] { 9.2, 16.1, 21.9, 29.5 });
233      AddToReferenceAlgorithmValuesDict(referenceValues, 5, SortingMethod.HeightArea, new double[] { 9, 16.6, 22.6, 30.5 });
234
235      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.Given, new double[] { 11.7, 21.7, 33, 44.4});
236      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightVolume, new double[] { 10.9, 21.2, 31.8, 41.5 });
237      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.VolumeHeight, new double[] { 11.7, 22, 34.2, 44 });
238      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.AreaHeight, new double[] { 10.6, 20.2, 30.8, 39.5});
239      AddToReferenceAlgorithmValuesDict(referenceValues, 6, SortingMethod.HeightArea, new double[] { 10.9, 20.5, 31, 39.8 });
240
241      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.Given, new double[] { 9.4, 15.9, 19.3, 30 });
242      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightVolume, new double[] { 8.2, 14.6, 19.2, 28.1 });
243      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.VolumeHeight, new double[] { 9.3, 15.6, 19.7, 30.2 });
244      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.AreaHeight, new double[] { 8.1, 14.1, 18.2, 26.2 });
245      AddToReferenceAlgorithmValuesDict(referenceValues, 7, SortingMethod.HeightArea, new double[] { 8.1, 14.1, 18.9, 27,2 });
246
247      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.Given, new double[] { 11.6, 22, 28.5, 35.4 });
248      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightVolume, new double[] { 10.5, 20.9, 27.4, 33.9 });
249      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.VolumeHeight, new double[] { 11.6, 22.1, 28.4, 35.4});
250      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.AreaHeight, new double[] { 10.1, 20.3, 26.4, 32.2 });
251      AddToReferenceAlgorithmValuesDict(referenceValues, 8, SortingMethod.HeightArea, new double[] { 10.5, 20.8, 37.7, 33.9 });
252      return referenceValues;
253    }
254
255    private void AddToReferenceAlgorithmValuesDict(Dictionary<Tuple<int, int, SortingMethod>, double> referenceValues, int @class, SortingMethod sortingMethod, double[] values) {
256      for (int i = 0; i < values.Length; i++) {
257        referenceValues.Add(new Tuple<int, int, SortingMethod>(@class, 50 + (50 * i), sortingMethod), values[i]);
258      }
259     
260    }
261
262
263    #endregion
264  }
265
266}
Note: See TracBrowser for help on using the repository browser.