Changeset 14146 for branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking.2D/3.3/PackingSequenceProblem.cs
- Timestamp:
- 07/21/16 10:19:55 (8 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.BinPacking/HeuristicLab.Problems.BinPacking.2D/3.3/PackingSequenceProblem.cs
r14128 r14146 23 23 24 24 using System; 25 using System.Co deDom;25 using System.Collections.Generic; 26 26 using System.Linq; 27 using System.Text;28 27 using HeuristicLab.Common; 29 28 using HeuristicLab.Core; … … 31 30 using HeuristicLab.Encodings.PermutationEncoding; 32 31 using HeuristicLab.Optimization; 32 using HeuristicLab.Parameters; 33 33 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 34 34 using HeuristicLab.Problems.BinPacking; 35 35 using HeuristicLab.Problems.BinPacking2D; 36 using HeuristicLab.Problems.Instances; 37 using HeuristicLab.Random; 36 38 37 39 namespace HeuristicLab.Problems.BinPacking2d { 40 [Item("Bin Packing Problem (2D, permutation encoding) (BPP)", "Represents a two-dimensional bin-packing problem using only bins with identical measures and bins/items with rectangular shapes.")] 38 41 [StorableClass] 39 42 [Creatable(Category = CreatableAttribute.Categories.CombinatorialProblems, Priority = 300)] 40 public class PackingSequenceProblem : PackingSequenceProblem<Permutation, PermutationEncoding> { 43 public sealed class PackingSequenceProblem : SingleObjectiveBasicProblem<PermutationEncoding>, IProblemInstanceConsumer<BPPData>, IProblemInstanceExporter<BPPData> { 44 private readonly string SolutionEvaluatorParameterName = "SolutionEvaluator"; 45 #region Default Instance 46 private static readonly BPPData DefaultInstance = new BPPData() { 47 Name = "2D BPP Default Instance", 48 Description = "The default instance for 2D Bin Packing.", 49 BinShape = new PackingShape(20, 16), 50 Items = new PackingItem[] { 51 new PackingItem(3, 8, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 52 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 53 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 54 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 55 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 56 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 57 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 58 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 59 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 60 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 61 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 62 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 63 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 64 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 65 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 66 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 67 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 68 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 69 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 70 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 71 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 72 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 73 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 74 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 75 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 76 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 77 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 78 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 79 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 80 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 81 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 82 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 83 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 84 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 85 new PackingItem(5, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 86 new PackingItem(9, 3, new PackingShape(20, 16)) { Material = 1, Weight = 1.0}, 87 new PackingItem(2, 7, new PackingShape(20, 16)) { Material = 1, Weight = 1.0} 88 }, 89 }; 90 #endregion 91 92 #region parameter properties 93 public IValueParameter<IPermutationDecoder> DecoderParameter { 94 get { return (IValueParameter<IPermutationDecoder>)Parameters["Decoder"]; } 95 } 96 public IValueParameter<BinPacking2D.IEvaluator> SolutionEvaluatorParameter { 97 get { return (IValueParameter<BinPacking2D.IEvaluator>)Parameters[SolutionEvaluatorParameterName]; } 98 } 99 public IValueParameter<ReadOnlyItemList<PackingItem>> ItemsParameter { 100 get { return (IValueParameter<ReadOnlyItemList<PackingItem>>)Parameters["Items"]; } 101 } 102 public IValueParameter<PackingShape> BinShapeParameter { 103 get { return (IValueParameter<PackingShape>)Parameters["BinShape"]; } 104 } 105 public IValueParameter<Solution> BestKnownSolutionParameter { 106 get { return (IValueParameter<Solution>)Parameters["BestKnownSolution"]; } 107 } 108 public IFixedValueParameter<IntValue> LowerBoundParameter { 109 get { return (IFixedValueParameter<IntValue>)Parameters["LowerBound"]; } 110 } 111 #endregion 112 113 #region properties 114 public IPermutationDecoder Decoder { 115 get { return DecoderParameter.Value; } 116 set { DecoderParameter.Value = value; } 117 } 118 public new BinPacking2D.IEvaluator SolutionEvaluator { 119 get { return SolutionEvaluatorParameter.Value; } 120 set { SolutionEvaluatorParameter.Value = value; } 121 } 122 public ReadOnlyItemList<PackingItem> Items { 123 get { return ItemsParameter.Value; } 124 set { ItemsParameter.Value = value; } 125 } 126 public PackingShape BinShape { 127 get { return BinShapeParameter.Value; } 128 set { BinShapeParameter.Value = value; } 129 } 130 public Solution BestKnownSolution { 131 get { return BestKnownSolutionParameter.Value; } 132 set { BestKnownSolutionParameter.Value = value; } 133 } 134 public int LowerBound { 135 get { return LowerBoundParameter.Value.Value; } 136 } 137 public int NumberOfItems { 138 get { return Items == null ? 0 : Items.Count; } 139 } 140 #endregion 41 141 42 142 // persistence 43 143 [StorableConstructor] 44 protected PackingSequenceProblem(bool deserializing) : base(deserializing) { } 45 [StorableHook(HookType.AfterDeserialization)] 46 private void AfterDeserialization() { } 47 48 public override bool Maximization { 49 get { return true; } 50 } 51 144 private PackingSequenceProblem(bool deserializing) : base(deserializing) { } 52 145 53 146 // cloning 54 pr otectedPackingSequenceProblem(PackingSequenceProblem original, Cloner cloner)147 private PackingSequenceProblem(PackingSequenceProblem original, Cloner cloner) 55 148 : base(original, cloner) { 56 } 57 58 protected PackingSequenceProblem() : base() { } 59 60 149 RegisterEventHandlers(); 150 } 151 152 public PackingSequenceProblem() 153 : base() { 154 var defaultEvaluator = new PackingRatioEvaluator(); 155 var defaultDecoder = new ExtremePointPermutationDecoder(); 156 Parameters.Add(new ValueParameter<IPermutationDecoder>("Decoder", "The decoder translates a permutation to a packing solution candidiates", defaultDecoder)); 157 Parameters.Add(new ValueParameter<BinPacking2D.IEvaluator>(SolutionEvaluatorParameterName, "The evaluator calculates qualities of solution candidates", defaultEvaluator)); 158 Parameters.Add(new ValueParameter<ReadOnlyItemList<PackingItem>>("Items", "The items which must be packed into bins")); 159 Parameters.Add(new ValueParameter<PackingShape>("BinShape", "The size of bins into which items must be packed")); 160 Parameters.Add(new OptionalValueParameter<Solution>("BestKnownSolution", "The best solution found so far")); 161 Parameters.Add(new FixedValueParameter<IntValue>("LowerBound", "A lower bound for the number of bins that is necessary to pack all items")); 162 163 Load(DefaultInstance); 164 165 Encoding = new PermutationEncoding("PackingSequence", Items.Count, PermutationTypes.Absolute); 166 AddOperators(); 167 RegisterEventHandlers(); 168 } 61 169 public override IDeepCloneable Clone(Cloner cloner) { 62 170 return new PackingSequenceProblem(this, cloner); 63 171 } 64 172 173 [StorableHook(HookType.AfterDeserialization)] 174 private void AfterDeserialization() { 175 RegisterEventHandlers(); 176 } 177 178 179 private void AddOperators() { 180 Operators.Add(new StochasticInsertionMultiMoveGenerator()); 181 Operators.Add(new ExhaustiveInsertionMoveGenerator()); 182 Operators.Add(new TranslocationMoveMaker()); 183 Operators.Add(new TranslocationMoveEvaluator()); 184 Operators.Add(new TranslocationMoveTabuMaker()); 185 186 Operators.RemoveAll(x => x is SingleObjectiveMoveGenerator); 187 Operators.RemoveAll(x => x is SingleObjectiveMoveMaker); 188 Operators.RemoveAll(x => x is SingleObjectiveMoveEvaluator); 189 190 Encoding.ConfigureOperators(Operators.OfType<IOperator>()); 191 } 192 193 private void RegisterEventHandlers() { 194 // update encoding length when number of items is changed 195 ItemsParameter.ValueChanged += (sender, args) => Encoding.Length = Items.Count; 196 } 197 198 public override bool Maximization { get { return true; } } 199 65 200 66 201 public override double Evaluate(Individual individual, IRandom random) { 67 var permutation = individual.Permutation(); 68 var decoder = new ExtremePointPackingSequenceDecoder2D(); 69 var packingPlan = decoder.CreatePackingPlanFromEncoding(permutation, Bin, Items); 70 var ratio = PackingRatioEvaluator.CalculatePackingRatio(packingPlan); 71 return ratio.Value; 202 var permutation = individual.Permutation("PackingSequence"); 203 var decoder = Decoder; 204 var solution = decoder.Decode(permutation, BinShape, Items); 205 return SolutionEvaluator.Evaluate(solution); 72 206 } 73 207 74 208 public override void Analyze(Individual[] individuals, double[] qualities, ResultCollection results, IRandom random) { 75 209 base.Analyze(individuals, qualities, results, random); 76 Analyze(individuals.Select(i => i.Permutation()).ToArray(), qualities, results, random); 77 } 210 Analyze(individuals.Select(i => i.Permutation("PackingSequence")).ToArray(), qualities, results, random); 211 } 212 213 public void Analyze(Permutation[] individuals, double[] qualities, ResultCollection results, IRandom random) { 214 var bestSolutionResultName = "Best Packing Solution"; 215 var numContainersResultName = "Nr of Containers"; 216 var binUtilResultName = "Overall Bin Utilization"; 217 218 if (!results.ContainsKey(bestSolutionResultName)) results.Add(new Result(bestSolutionResultName, typeof(Solution))); 219 if (!results.ContainsKey(numContainersResultName)) results.Add(new Result(numContainersResultName, typeof(IntValue))); 220 if (!results.ContainsKey(binUtilResultName)) results.Add(new Result(binUtilResultName, typeof(DoubleValue))); 221 222 223 // find index of item with max quality 224 int bestIdx = 0; 225 for (int j = 1; j < qualities.Length; j++) 226 if (qualities[j] > qualities[bestIdx]) bestIdx = j; 227 228 229 // update best solution so far 230 var bestSolution = results[bestSolutionResultName].Value as Solution; 231 if (bestSolution == null || 232 bestSolution.Quality.Value < qualities[bestIdx]) { 233 234 var newBestSolution = Decoder.Decode(individuals[bestIdx], BinShape, Items); 235 newBestSolution.Quality = new DoubleValue(qualities[bestIdx]); 236 results[bestSolutionResultName].Value = newBestSolution; 237 results[numContainersResultName].Value = new IntValue(newBestSolution.NrOfBins); 238 results[binUtilResultName].Value = new DoubleValue(BinUtilizationEvaluator.CalculateBinUtilization(newBestSolution)); 239 240 // update best known solution 241 var bestKnownQuality = BestKnownQualityParameter.Value; 242 if (bestKnownQuality == null || 243 bestKnownQuality.Value < qualities[bestIdx]) { 244 BestKnownQualityParameter.ActualValue = new DoubleValue(qualities[bestIdx]); 245 BestKnownSolutionParameter.ActualValue = newBestSolution; 246 } 247 } 248 } 249 250 251 #region Problem instance handling 252 public void Load(BPPData data) { 253 BestKnownSolutionParameter.Value = null; 254 BestKnownQualityParameter.Value = null; 255 256 if (data.BestKnownQuality.HasValue) 257 BestKnownQuality = data.BestKnownQuality.Value; 258 259 BinShape = data.BinShape; 260 var items = new ItemList<PackingItem>(data.Items); 261 items.Sort((x, y) => y.CompareTo(x)); 262 Items = items.AsReadOnly(); 263 264 ApplyHorizontalOrientation(); 265 LowerBoundParameter.Value.Value = CalculateLowerBound(); 266 } 267 268 269 public BPPData Export() { 270 return new BPPData { 271 Name = Name, 272 Description = Description, 273 BinShape = BinShape, 274 Items = Items.ToArray() 275 }; 276 } 277 #endregion 278 279 280 #region helpers 281 private void ApplyHorizontalOrientation() { 282 BinShape.ApplyHorizontalOrientation(); 283 foreach (var shape in Items) { 284 shape.ApplyHorizontalOrientation(); 285 } 286 } 287 288 private int CalculateLowerBound() { 289 //This is the obvious continuous lower bound calculation; Martello and Vigo proposed a better way but it has not been implemented yet; 290 int itemsVol = Items.Select(x => x.Volume).Sum(); 291 int binVol = BinShape.Volume; 292 return (itemsVol + binVol - 1) / (binVol); 293 } 294 295 #endregion 78 296 } 79 297 }
Note: See TracChangeset
for help on using the changeset viewer.