Test Failed
Push — 2.x-dev ( 5e90af...eccc16 )
by Doug
03:16
created

PackedBoxList::compare()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5.0342

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 8
c 1
b 0
f 0
nc 12
nop 2
dl 0
loc 15
ccs 8
cts 9
cp 0.8889
crap 5.0342
rs 9.6111
1
<?php
2
/**
3
 * Box packing (3D bin packing, knapsack problem).
4
 *
5
 * @author Doug Wright
6
 */
7
namespace DVDoug\BoxPacker;
8
9
/**
10
 * List of packed boxes.
11
 *
12
 * @author Doug Wright
13
 */
14
class PackedBoxList extends \SplMinHeap
15
{
16
    /**
17
     * Average (mean) weight of boxes.
18
     *
19
     * @var float
20
     */
21
    protected $meanWeight;
22
23
    /**
24
     * Average (mean) item weight of boxes.
25
     *
26
     * @var float
27
     */
28
    protected $meanItemWeight;
29
30
    /**
31
     * Compare elements in order to place them correctly in the heap while sifting up.
32
     *
33
     * @see \SplMinHeap::compare()
34
     *
35
     * @param PackedBox $boxA
36
     * @param PackedBox $boxB
37
     *
38
     * @return int
39
     */
40 5
    public function compare($boxA, $boxB)
41
    {
42 5
        $choice = $boxA->getItems()->count() - $boxB->getItems()->count();
43 5
        if ($choice == 0) {
44 5
            $choice = $boxA->getInnerVolume() - $boxB->getInnerVolume();
45
        }
46 5
        if ($choice == 0) {
47 5
            $choice = $boxB->getWeight() - $boxA->getWeight();
48
        }
49
50 5
        if ($choice == 0) {
51
            $choice = PHP_MAJOR_VERSION > 5 ? -1 : 1;
52
        }
53
54 5
        return $choice;
55
56
    }
57
58
    /**
59
     * Reversed version of compare.
60
     *
61
     * @deprecated
62
     *
63
     * @param PackedBox $boxA
64
     * @param PackedBox $boxB
65
     *
66
     * @return int
67
     */
68
    public function reverseCompare($boxA, $boxB)
69
    {
70
        $choice = $boxB->getItems()->count() - $boxA->getItems()->count();
71
        if ($choice === 0) {
72
            $choice = $boxA->getBox()->getInnerVolume() - $boxB->getBox()->getInnerVolume();
73
        }
74
        if ($choice === 0) {
75
            $choice = $boxB->getWeight() - $boxA->getWeight();
76
        }
77
78
        return $choice;
79
    }
80
81
    /**
82
     * Calculate the average (mean) weight of the boxes.
83
     *
84
     * @return float
85
     */
86 2
    public function getMeanWeight()
87
    {
88 2
        if (!is_null($this->meanWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->meanWeight) is always false.
Loading history...
89
            return $this->meanWeight;
90
        }
91
92 2
        foreach (clone $this as $box) {
93 2
            $this->meanWeight += $box->getWeight();
94
        }
95
96 2
        return $this->meanWeight /= $this->count();
97
    }
98
99
100
    /**
101
     * Calculate the average (mean) weight of the boxes.
102
     *
103
     * @return float
104
     */
105
    public function getMeanItemWeight()
106
    {
107
        if (!is_null($this->meanItemWeight)) {
0 ignored issues
show
introduced by
The condition is_null($this->meanItemWeight) is always false.
Loading history...
108
            return $this->meanItemWeight;
109
        }
110
111
        foreach (clone $this as $box) {
112
            $this->meanItemWeight += $box->getItemWeight();
113
        }
114
115
        return $this->meanItemWeight /= $this->count();
116
    }
117
118
    /**
119
     * Calculate the variance in weight between these boxes.
120
     *
121
     * @return float
122
     */
123 1
    public function getWeightVariance()
124
    {
125 1
        $mean = $this->getMeanWeight();
126
127 1
        $weightVariance = 0;
128 1
        foreach (clone $this as $box) {
129 1
            $weightVariance += pow($box->getWeight() - $mean, 2);
130
        }
131
132 1
        return round($weightVariance / $this->count(), 1);
133
    }
134
135
    /**
136
     * Get volume utilisation of the set of packed boxes.
137
     *
138
     * @return float
139
     */
140 1
    public function getVolumeUtilisation()
141
    {
142 1
        $itemVolume = 0;
143 1
        $boxVolume = 0;
144
145
        /** @var PackedBox $box */
146 1
        foreach (clone $this as $box) {
147 1
            $boxVolume += $box->getBox()->getInnerVolume();
148
149
            /** @var Item $item */
150 1
            foreach (clone $box->getItems() as $item) {
151 1
                $itemVolume += $item->getVolume();
152
            }
153
        }
154
155 1
        return round($itemVolume / $boxVolume * 100, 1);
156
    }
157
158
    /**
159
     * Do a bulk insert.
160
     *
161
     * @param array $boxes
162
     */
163 1
    public function insertFromArray(array $boxes)
164
    {
165 1
        foreach ($boxes as $box) {
166 1
            $this->insert($box);
167
        }
168 1
    }
169
}
170