Completed
Branch master (c1e62b)
by Doug
02:44
created

PackedBoxList   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 12
Bugs 0 Features 2
Metric Value
wmc 16
c 12
b 0
f 2
lcom 1
cbo 0
dl 0
loc 110
ccs 38
cts 38
cp 1
rs 10

6 Methods

Rating   Name   Duplication   Size   Complexity  
A reverseCompare() 0 11 3
A getWeightVariance() 0 12 2
A compare() 0 11 3
A getMeanWeight() 0 14 3
A getVolumeUtilisation() 0 17 3
A insertFromArray() 0 6 2
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 6
    public function compare($boxA, $boxB)
28
    {
29 6
        $choice = $boxA->getItems()->count() - $boxB->getItems()->count();
30 6
        if ($choice === 0) {
31 3
            $choice = $boxB->getBox()->getInnerVolume() - $boxA->getBox()->getInnerVolume();
32
        }
33 6
        if ($choice === 0) {
34 3
            $choice = $boxA->getWeight() - $boxB->getWeight();
35
        }
36 6
        return $choice;
37
    }
38
39
    /**
40
     * Reversed version of compare
41
     * @return int
0 ignored issues
show
Documentation introduced by
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
    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
0 ignored issues
show
Documentation introduced by
Should the return type not be double|integer?

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...
58
     */
59 5
    public function getMeanWeight()
60
    {
61
62 5
        if (!is_null($this->meanWeight)) {
63 4
            return $this->meanWeight;
64
        }
65
66 5
        foreach (clone $this as $box) {
67 5
            $this->meanWeight += $box->getWeight();
68
        }
69
70 5
        return $this->meanWeight /= $this->count();
71
72
    }
73
74
    /**
75
     * Calculate the variance in weight between these boxes
76
     * @return float
0 ignored issues
show
Documentation introduced by
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...
77
     */
78 5
    public function getWeightVariance()
79
    {
80 5
        $mean = $this->getMeanWeight();
81
82 5
        $weightVariance = 0;
83 5
        foreach (clone $this as $box) {
84 5
            $weightVariance += pow($box->getWeight() - $mean, 2);
85
        }
86
87 5
        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 4
    public function insertFromArray(array $boxes)
118
    {
119 4
        foreach ($boxes as $box) {
120 3
            $this->insert($box);
121
        }
122 4
    }
123
}
124