-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathgoals_test.go
More file actions
103 lines (82 loc) · 2.94 KB
/
Copy pathgoals_test.go
File metadata and controls
103 lines (82 loc) · 2.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package boxpacker3_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/bavix/boxpacker3"
)
func TestGoals_ConflictScenarios(t *testing.T) {
t.Parallel()
// A: 1 Huge Box (100L capacity).
// - Items inside take 10L.
// - Fill rate: 10%.
// - Total Volume: 100L.
// - Box Count: 1.
//
// B: 2 Small Boxes (10L capacity each).
// - Items inside take 10L (5L per box).
// - Fill rate: 50% per box.
// - Total Volume: 20L.
// - Box Count: 2.
resA := &boxpacker3.Result{
Boxes: []*boxpacker3.Box{
makeBoxWithProps(100, 10, 10),
},
UnfitItems: []*boxpacker3.Item{},
}
resB := &boxpacker3.Result{
Boxes: []*boxpacker3.Box{
makeBoxWithProps(10, 5, 5),
makeBoxWithProps(10, 5, 5),
},
UnfitItems: []*boxpacker3.Item{},
}
// MinimizeBoxes should prefer A (1 box < 2 boxes).
require.True(t, boxpacker3.MinimizeBoxesGoal(resA, resB),
"MinimizeBoxes should prefer 1 huge box over 2 small ones")
// TightestPacking should prefer B (20L total volume < 100L total volume).
require.True(t, boxpacker3.TightestPackingGoal(resB, resA),
"TightestPacking should prefer 2 small boxes (20L) over 1 huge box (100L)")
// MaxAverageFillRate should prefer B (50% fill vs 10% fill).
require.True(t, boxpacker3.MaxAverageFillRateGoal(resB, resA),
"MaxAverageFillRate should prefer higher density")
}
func TestGoals_BalancedPacking(t *testing.T) {
t.Parallel()
// Candidate A: Balanced (10kg, 10kg). StdDev = 0.
resA := &boxpacker3.Result{
Boxes: []*boxpacker3.Box{
makeBoxWithProps(20, 10, 10), // 10 kg
makeBoxWithProps(20, 10, 10), // 10 kg
},
}
// Candidate B: Unbalanced (1kg, 19kg). High StdDev.
resB := &boxpacker3.Result{
Boxes: []*boxpacker3.Box{
makeBoxWithProps(20, 10, 1), // 1 kg
makeBoxWithProps(20, 10, 19), // 19 kg
},
}
require.True(t, boxpacker3.BalancedPackingGoal(resA, resB),
"BalancedPacking should prefer equal weights")
}
func TestGoals_TieBreaker(t *testing.T) {
t.Parallel()
// Both use 1 box.
// A is smaller (10L). B is larger (20L).
resA := &boxpacker3.Result{Boxes: []*boxpacker3.Box{makeBoxWithProps(10, 5, 5)}}
resB := &boxpacker3.Result{Boxes: []*boxpacker3.Box{makeBoxWithProps(20, 5, 5)}}
// MinimizeBoxes should fall back to volume check if counts are equal
require.True(t, boxpacker3.MinimizeBoxesGoal(resA, resB),
"MinimizeBoxes should prefer smaller volume if box counts are equal")
}
// makeBoxWithProps creates a real Box struct and populates it with an item
// to simulate volume and weight usage for testing goals.
func makeBoxWithProps(volume, itemsVolume, itemsWeight float64) *boxpacker3.Box {
// Create a box with W=volume, H=1, D=1 => Volume = volume
b := boxpacker3.NewBox("mock", volume, 1, 1, 1000)
// Create an item with matching props to populate the box stats
item := boxpacker3.NewItem("mock-item", itemsVolume, 1, 1, itemsWeight)
// PutItem updates internal itemsVolume and itemsWeight
b.PutItem(item, boxpacker3.Pivot{})
return b
}