-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathFiniteBestStrip.cpp
More file actions
154 lines (135 loc) · 4.04 KB
/
FiniteBestStrip.cpp
File metadata and controls
154 lines (135 loc) · 4.04 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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using namespace std;
#include <cstdlib>
#include <utility>
#include <algorithm>
#include "utils.h"
#include "FiniteBestStrip.h"
// Finite Best Strip
Packing FBS(vector <Item> &items, int Hbin, int Wbin) {
// Sorting the items by nonincreasing height
// sort(items.begin(), items.end(), compareHeight);
// Number of bins used so far
int nbin = 0;
// leftover width used to fit figure
int wleft = Wbin;
int nItems = items.size();
vector<Strip> sset; // Strip set
int nstrip = 0; // Number of strips used
// Structure initialization
init_visited(items);
init_coord(items);
// At least one strip will have to be used
sset.push_back((Strip){vector<Item>(), false});
bool assig = false;
for(int i = 0; i < nItems; i++) {
if (!items[i].visited) {
if (items[i].width <= wleft) {
// We add the item to the strip
sset[nstrip].strip.push_back(items[i]);
wleft -= items[i].width;
}
else {
// We need to look for other elements
// that might fit
for(int k = i + 1; k < nItems; k++) {
if (!items[k].visited) {
if (items[k].width <= wleft) {
// We add the item to the strip
sset[nstrip].strip.push_back(items[k]);
wleft -= items[k].width;
items[k].visited = true;
assig = true;
break;
}
continue; // We keep on checking til the end
}
}
if (!assig) {
// None of the elements fit, so we need
// to open up a new strip
nstrip++;
sset.push_back((Strip) {vector <Item>(), false});
sset[nstrip].strip.push_back(items[i]);
wleft = Wbin;
assig = false;
}
}
}
}
Packing result = merge_strips(sset, Hbin, Wbin);
return result;
}
Packing merge_strips(vector<Strip> &sset,
int Hbin, int Wbin) {
int currBin = 0;
vector<Placement> total;
vector<Strip>::iterator it;
it = sset.begin();
total = total + genBin(currBin,(*it).strip);
int currH = (*it).strip[0].height;
it++;
bool assig = false;
for(it; it != sset.end(); it++) {
if (!(*it).visited) {
// See if the strip fits
if ((*it).strip[0].height + currH <= Hbin) {
// The strip fits
total = total + putAbove(*it, currH, currBin);
currH += (*it).strip[0].height;
}
else { // We have to check for the others strips
vector<Strip>::iterator k;
for(k = it; k != sset.end(); it++) {
if (!(*k).visited) {
if ((*k).strip[0].height + currH <= Hbin) {
total = total + putAbove(*k,currH, currBin);
currH += (*k).strip[0].height;
assig = true;
break;
}
else continue;
}
}
if (!assig) {
// No choice left, we have to open up a new bin
currBin++;
total = total + genBin(currBin,(*it).strip);
currH = (*it).strip[0].height;
assig = false;
}
}
}
}
Packing result = {total, currBin + 1};
return result;
}
vector<Placement> genBin(int newBin, vector <Item> bottom) {
vector<Placement> result;
// Accumulated width
int wacc = 0;
vector<Item>::iterator it;
for(it = bottom.begin(); it != bottom.end(); it++) {
result.push_back((Placement) {newBin, {wacc ,0}, *it});
wacc += (*it).width;
}
return result;
}
vector<Placement> putAbove(Strip &s, int currH,
int currBin) {
vector<Item>::iterator it;
vector<Placement> result;
int wacc = 0; // Accumulated width
for(it = s.strip.begin(); it != s.strip.end(); it++) {
result.push_back((Placement) {currBin, {wacc, currH}, *it});
wacc += (*it).width;
}
return result;
}
// Merges two Placement vectors.
vector<Placement> operator+(vector<Placement> a,
vector<Placement> b) {
vector<Placement>::iterator it;
for(it = b.begin(); it != b.end(); it++)
a.push_back(*it);
return a;
}