aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Brandenburg <bbb@mpi-sws.org>2012-02-13 03:04:20 -0500
committerBjoern Brandenburg <bbb@mpi-sws.org>2012-02-13 03:04:20 -0500
commit6f1f3ab6fdcb881401ad4d086bbdf1c104c8fb02 (patch)
treeb13f692f7a2aae5126ff5cb7c7c36d66d245f895
parent532478450c1e0a25ab92b2585a8c3ee61089d02b (diff)
Add any_fit and almost_worst_fit binpacking heuristics.
almost_worst_fit: like worst_fit, but uses second-to-worst bin. any_fit: try each of the implemented heuristics and see if one works.
-rw-r--r--schedcat/mapping/binpack.py40
1 files changed, 38 insertions, 2 deletions
diff --git a/schedcat/mapping/binpack.py b/schedcat/mapping/binpack.py
index 00a2bd9..bbd1224 100644
--- a/schedcat/mapping/binpack.py
+++ b/schedcat/mapping/binpack.py
@@ -103,8 +103,29 @@ def worst_fit(items, bins, capacity=1.0, weight=id, misfit=ignore,
103 c = weight(x) 103 c = weight(x)
104 # pick the bin where the item will leave the most space 104 # pick the bin where the item will leave the most space
105 # after placing it, aka the bin with the least sum 105 # after placing it, aka the bin with the least sum
106 i = sums.index(min(sums)) 106 candidates = [s for s in sums if s + c <= capacity]
107 if sums[i] + c <= capacity: 107 if candidates:
108 # fits somewhere
109 i = sums.index(min(candidates))
110 sets[i] += [x]
111 sums[i] += c
112 else:
113 misfit(x)
114 return sets
115
116def almost_worst_fit(items, bins, capacity=1.0, weight=id, misfit=ignore,
117 empty_bin=list):
118 sets = [empty_bin() for _ in xrange(0, bins)]
119 sums = [0.0 for _ in xrange(0, bins)]
120 for x in items:
121 c = weight(x)
122 # pick the bin where the item will leave almost the most space
123 # after placing it, aka the bin with the second to least sum
124 candidates = [s for s in sums if s + c <= capacity]
125 if candidates:
126 # fits somewhere
127 candidates.sort()
128 i = sums.index(candidates[1] if len(candidates) > 1 else candidates[0])
108 sets[i] += [x] 129 sets[i] += [x]
109 sums[i] += c 130 sums[i] += c
110 else: 131 else:
@@ -129,6 +150,19 @@ def best_fit(items, bins, capacity=1.0, weight=id, misfit=ignore,
129 misfit(x) 150 misfit(x)
130 return sets 151 return sets
131 152
153def any_fit(items, bins, capacity=1.0, weight=id, misfit=ignore,
154 empty_bin=list):
155 for h in [next_fit, first_fit, worst_fit, almost_worst_fit, best_fit]:
156 try:
157 sets = h(items, bins, capacity, weight, report_failure, empty_bin)
158 return sets
159 except DidNotFit as dnf:
160 pass
161 # if we get here, none of the heuristics worked
162 misfit(dnf.item)
163 # if we get here, misfit did not raise an exception => return something
164 return next_fit(items, bins, capacity, weight, misfit, empty_bin)
165
132def decreasing(algorithm): 166def decreasing(algorithm):
133 def alg_decreasing(items, bins, capacity=1.0, weight=id, *args, **kargs): 167 def alg_decreasing(items, bins, capacity=1.0, weight=id, *args, **kargs):
134 # don't clobber original items 168 # don't clobber original items
@@ -141,4 +175,6 @@ next_fit_decreasing = decreasing(next_fit)
141first_fit_decreasing = decreasing(first_fit) 175first_fit_decreasing = decreasing(first_fit)
142worst_fit_decreasing = decreasing(worst_fit) 176worst_fit_decreasing = decreasing(worst_fit)
143best_fit_decreasing = decreasing(best_fit) 177best_fit_decreasing = decreasing(best_fit)
178almost_worst_fit_decreasing = decreasing(almost_worst_fit)
179any_fit_decreasing = decreasing(any_fit)
144 180