예제 #1
0
 /**
  * Pack items into boxes using the principle of largest volume item first
  *
  * @throws \RuntimeException
  * @return PackedBoxList
  */
 public function doVolumePacking()
 {
     $packedBoxes = new PackedBoxList();
     //Keep going until everything packed
     while ($this->items->count()) {
         $boxesToEvaluate = clone $this->boxes;
         $packedBoxesIteration = new PackedBoxList();
         //Loop through boxes starting with smallest, see what happens
         while (!$boxesToEvaluate->isEmpty()) {
             $box = $boxesToEvaluate->extract();
             $packedBox = $this->packIntoBox($box, clone $this->items);
             if ($packedBox->getItems()->count()) {
                 $packedBoxesIteration->insert($packedBox);
                 //Have we found a single box that contains everything?
                 if ($packedBox->getItems()->count() === $this->items->count()) {
                     break;
                 }
             }
         }
         //Check iteration was productive
         if ($packedBoxesIteration->isEmpty()) {
             throw new \RuntimeException('Item ' . $this->items->top()->getDescription() . ' is too large to fit into any box');
         }
         //Find best box of iteration, and remove packed items from unpacked list
         $bestBox = $packedBoxesIteration->top();
         for ($i = 0; $i < $bestBox->getItems()->count(); $i++) {
             $this->items->extract();
         }
         $packedBoxes->insert($bestBox);
     }
     return $packedBoxes;
 }
예제 #2
0
파일: Packer.php 프로젝트: dvdoug/boxpacker
 /**
  * Pack items into boxes using the principle of largest volume item first
  *
  * @throws \RuntimeException
  * @return PackedBoxList
  */
 public function doVolumePacking()
 {
     $packedBoxes = new PackedBoxList();
     //Keep going until everything packed
     while ($this->items->count()) {
         $boxesToEvaluate = clone $this->boxes;
         $packedBoxesIteration = new PackedBoxList();
         //Loop through boxes starting with smallest, see what happens
         while (!$boxesToEvaluate->isEmpty()) {
             $box = $boxesToEvaluate->extract();
             $volumePacker = new VolumePacker($box, clone $this->items);
             $volumePacker->setLogger($this->logger);
             $packedBox = $volumePacker->pack();
             if ($packedBox->getItems()->count()) {
                 $packedBoxesIteration->insert($packedBox);
                 //Have we found a single box that contains everything?
                 if ($packedBox->getItems()->count() === $this->items->count()) {
                     break;
                 }
             }
         }
         //Check iteration was productive
         if ($packedBoxesIteration->isEmpty()) {
             throw new \RuntimeException('Item ' . $this->items->top()->getDescription() . ' is too large to fit into any box');
         }
         //Find best box of iteration, and remove packed items from unpacked list
         $bestBox = $packedBoxesIteration->top();
         $unPackedItems = $this->items->asArray();
         foreach (clone $bestBox->getItems() as $packedItem) {
             foreach ($unPackedItems as $unpackedKey => $unpackedItem) {
                 if ($packedItem === $unpackedItem) {
                     unset($unPackedItems[$unpackedKey]);
                     break;
                 }
             }
         }
         $unpackedItemList = new ItemList();
         foreach ($unPackedItems as $unpackedItem) {
             $unpackedItemList->insert($unpackedItem);
         }
         $this->items = $unpackedItemList;
         $packedBoxes->insert($bestBox);
     }
     return $packedBoxes;
 }