Completed
Push — master ( 9610e0...320eee )
by Doug
08:43
created

PackedBoxList.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem)
4
 * @package BoxPacker
5
 * @author Doug Wright
6
 */
7
namespace DVDoug\BoxPacker;
8
9
/**
10
 * List of possible packed box choices, ordered by utilisation (item count, volume)
11
 * @author Doug Wright
12
 * @package BoxPacker
13
 */
14
class PackedBoxList extends \SplMinHeap
15
{
16
17
    /**
18
     * Average (mean) weight of boxes
19
     * @var float
20
     */
21
    protected $meanWeight;
22
23
    /**
24
     * Compare elements in order to place them correctly in the heap while sifting up.
25
     * @see \SplMinHeap::compare()
26
     */
27 8 View Code Duplication
    public function compare($boxA, $boxB)
28
    {
29 8
        $choice = $boxA->getItems()->count() - $boxB->getItems()->count();
30 8
        if ($choice === 0) {
31 4
            $choice = $boxB->getBox()->getInnerVolume() - $boxA->getBox()->getInnerVolume();
32
        }
33 8
        if ($choice === 0) {
34 4
            $choice = $boxA->getWeight() - $boxB->getWeight();
35
        }
36 8
        return $choice;
37
    }
38
39
    /**
40
     * Reversed version of compare
41
     * @return int
0 ignored issues
show
Should the return type not be integer|double?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
42
     */
43 2 View Code Duplication
    public function reverseCompare($boxA, $boxB)
44
    {
45 2
        $choice = $boxB->getItems()->count() - $boxA->getItems()->count();
46 2
        if ($choice === 0) {
47 1
            $choice = $boxA->getBox()->getInnerVolume() - $boxB->getBox()->getInnerVolume();
48
        }
49 2
        if ($choice === 0) {
50 1
            $choice = $boxB->getWeight() - $boxA->getWeight();
51
        }
52 2
        return $choice;
53
    }
54
55
    /**
56
     * Calculate the average (mean) weight of the boxes
57
     * @return float
58
     */
59 7
    public function getMeanWeight()
60
    {
61
62 7
        if (!is_null($this->meanWeight)) {
63 6
            return $this->meanWeight;
64
        }
65
66 7
        foreach (clone $this as $box) {
67 7
            $this->meanWeight += $box->getWeight();
68
        }
69
70 7
        return $this->meanWeight /= $this->count();
71
72
    }
73
74
    /**
75
     * Calculate the variance in weight between these boxes
76
     * @return float
77
     */
78 7
    public function getWeightVariance()
79
    {
80 7
        $mean = $this->getMeanWeight();
81
82 7
        $weightVariance = 0;
83 7
        foreach (clone $this as $box) {
84 7
            $weightVariance += pow($box->getWeight() - $mean, 2);
85
        }
86
87 7
        return $weightVariance / $this->count();
88
89
    }
90
91
    /**
92
     * Get volume utilisation of the set of packed boxes
93
     * @return float
94
     */
95 1
    public function getVolumeUtilisation()
96
    {
97 1
        $itemVolume = 0;
98 1
        $boxVolume = 0;
99
100
        /** @var PackedBox $box */
101 1
        foreach (clone $this as $box) {
102 1
            $boxVolume += $box->getBox()->getInnerVolume();
103
104
            /** @var Item $item */
105 1
            foreach (clone $box->getItems() as $item) {
106 1
                $itemVolume += $item->getVolume();
107
            }
108
        }
109
110 1
        return round($itemVolume / $boxVolume * 100, 1);
111
    }
112
113
    /**
114
     * Do a bulk insert
115
     * @param array $boxes
116
     */
117 6
    public function insertFromArray(array $boxes)
118
    {
119 6
        foreach ($boxes as $box) {
120 4
            $this->insert($box);
121
        }
122
    }
123
}
124