-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathBinPacker.py
More file actions
77 lines (52 loc) · 2.05 KB
/
BinPacker.py
File metadata and controls
77 lines (52 loc) · 2.05 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
from copy import deepcopy
from Rect import Rect
from Configuration import Configuration
from util import argmax
class BinPacker:
def __init__(self, configuration: Configuration) -> None:
self.C = configuration
def _degree(self, i:Rect, C: Configuration) -> float:
d_mins = [i.min_distance(m) for m in C.packed_rects]
# Add the distances to the borders
d_mins += [i.bottom, i.left, C.size[1] - i.top, C.size[0] - i.right]
# Remove two smallest elements, which will be 0 - the two imediate neighbours
assert(min(d_mins) == 0)
d_mins.remove(min(d_mins))
assert(min(d_mins) == 0)
d_mins.remove(min(d_mins))
return 1 - (min(d_mins) /((i.width + i.height)/2))
def _A0(self, C: Configuration):
while C.L:
degrees = [self._degree(ccoa, C) for ccoa in C.L]
best = argmax(degrees)
C.place_rect(C.L[best])
return C
def _BenefitA1(self, ccoa: Rect, Cx: Configuration):
Cx.place_rect(ccoa)
Cx = self._A0(Cx)
if Cx.is_successful():
return Cx
else:
return Cx.density()
def PackConfiguration(self, C: Configuration):
""" The method called A1 in the paper """
while C.L:
max_benefit = 0
max_benefit_ccoa = None
for ccoa in C.L:
d = self._BenefitA1(ccoa, deepcopy(C))
if type(d) is Configuration:
print("Found successful configuration")
return d
else:
if max_benefit < d:
max_benefit = d
max_benefit_ccoa = ccoa
print(f"Placed {max_benefit_ccoa}, {len(C.unpacked_rects)} rects remaining")
C.place_rect(max_benefit_ccoa)
if C.is_successful():
print("Found successful configuration")
else:
print("Stopped with failure")
print(f"Rects remaining: {C.unpacked_rects}")
return C