Skip to content

Commit e27c4fd

Browse files
committed
Fix column generation algorithm with multiple bin sizes (#5)
1 parent 3407a1c commit e27c4fd

File tree

5 files changed

+45
-32
lines changed

5 files changed

+45
-32
lines changed

packingsolver/algorithms/column_generation.hpp

+19-19
Original file line numberDiff line numberDiff line change
@@ -162,14 +162,6 @@ std::vector<ColIdx> VariableSizeBinPackingPricingSolver<Instance, InstanceBuilde
162162
return {};
163163
}
164164

165-
template <typename Solution>
166-
struct VariableSizeBinPackingColumnExtra
167-
{
168-
Solution solution;
169-
BinTypeId bin_type_id;
170-
std::vector<ItemTypeId> kp2vbpp;
171-
};
172-
173165
template <typename Solution>
174166
std::vector<Column> solution2column(
175167
const Solution& solution)
@@ -178,23 +170,22 @@ std::vector<Column> solution2column(
178170
BinPos m = solution.instance().number_of_bin_types();
179171
for (BinPos bin_pos = 0; bin_pos < solution.number_of_different_bins(); ++bin_pos) {
180172
BinTypeId bin_type_id = solution.bin(bin_pos).bin_type_id;
181-
Solution solution_i(solution.instance());
182-
solution_i.append(solution, bin_pos, 1);
183-
VariableSizeBinPackingColumnExtra<Solution> extra {solution_i, bin_type_id, {}};
173+
Solution extra_solution(solution.instance());
174+
extra_solution.append(solution, bin_pos, 1);
184175
Column column;
185176
column.objective_coefficient = solution.instance().bin_type(bin_type_id).cost;
186177
column.row_indices.push_back(bin_type_id);
187178
column.row_coefficients.push_back(1);
188179
for (ItemTypeId item_type_id = 0;
189180
item_type_id < solution.instance().number_of_item_types();
190181
++item_type_id) {
191-
if (extra.solution.item_copies(item_type_id) > 0) {
182+
if (extra_solution.item_copies(item_type_id) > 0) {
192183
column.row_indices.push_back(m + item_type_id);
193184
column.row_coefficients.push_back(
194-
extra.solution.item_copies(item_type_id));
185+
extra_solution.item_copies(item_type_id));
195186
}
196187
}
197-
column.extra = std::shared_ptr<void>(new VariableSizeBinPackingColumnExtra<Solution>(extra));
188+
column.extra = std::shared_ptr<void>(new Solution(extra_solution));
198189
columns.push_back(column);
199190
}
200191
return columns;
@@ -243,7 +234,9 @@ std::vector<Column> VariableSizeBinPackingPricingSolver<Instance, InstanceBuilde
243234

244235
// Retrieve column.
245236
for (const Solution& kp_solution: kp_solution_pool.solutions()) {
246-
VariableSizeBinPackingColumnExtra<Solution> extra {kp_solution, bin_type_id, kp2vbpp};
237+
if (kp_solution.number_of_bins() == 0)
238+
continue;
239+
247240
Column column;
248241
column.objective_coefficient = instance_.bin_type(bin_type_id).cost;
249242
column.row_indices.push_back(bin_type_id);
@@ -253,13 +246,20 @@ std::vector<Column> VariableSizeBinPackingPricingSolver<Instance, InstanceBuilde
253246
for (ItemTypeId kp_item_type_id = 0;
254247
kp_item_type_id < kp_instance.number_of_item_types();
255248
++kp_item_type_id) {
256-
if (extra.solution.item_copies(kp_item_type_id) > 0) {
257-
column.row_indices.push_back(m + extra.kp2vbpp[kp_item_type_id]);
258-
column.row_coefficients.push_back(extra.solution.item_copies(kp_item_type_id));
249+
if (kp_solution.item_copies(kp_item_type_id) > 0) {
250+
column.row_indices.push_back(m + kp2vbpp[kp_item_type_id]);
251+
column.row_coefficients.push_back(kp_solution.item_copies(kp_item_type_id));
259252
//std::cout << duals[m + extra->kp2vbpp[kp_j]] << std::endl;
260253
}
261254
}
262-
column.extra = std::shared_ptr<void>(new VariableSizeBinPackingColumnExtra<Solution>(extra));
255+
Solution extra_solution(instance_);
256+
extra_solution.append(
257+
kp_solution,
258+
0,
259+
1,
260+
{bin_type_id},
261+
kp2vbpp);
262+
column.extra = std::shared_ptr<void>(new Solution(extra_solution));
263263
//std::cout << column << std::endl;
264264
columns.push_back(column);
265265
}

packingsolver/onedimensional/optimize.cpp

+8-7
Original file line numberDiff line numberDiff line change
@@ -161,22 +161,23 @@ Output packingsolver::onedimensional::optimize(
161161
if (parameters.column_generation_maximum_discrepancy >= 0)
162162
lds_parameters.discrepancy_limit = parameters.column_generation_maximum_discrepancy;
163163
lds_parameters.new_bound_callback = [&instance, &parameters, &output](
164-
const columngenerationsolver::LimitedDiscrepancySearchOutput& o)
164+
const columngenerationsolver::LimitedDiscrepancySearchOutput& lds_output)
165165
{
166-
if (o.solution.size() > 0) {
166+
if (lds_output.solution.size() > 0) {
167167
Solution solution(instance);
168-
for (const auto& pair: o.solution) {
168+
for (const auto& pair: lds_output.solution) {
169169
const Column& column = pair.first;
170170
BinPos value = std::round(pair.second);
171171
if (value < 0.5)
172172
continue;
173173
//std::cout << "append val " << value << " col " << column << std::endl;
174-
std::shared_ptr<VariableSizeBinPackingColumnExtra<Solution>> extra
175-
= std::static_pointer_cast<VariableSizeBinPackingColumnExtra<Solution>>(column.extra);
176-
solution.append(extra->solution, 0, value, {extra->bin_type_id}, extra->kp2vbpp);
174+
solution.append(
175+
*std::static_pointer_cast<Solution>(column.extra),
176+
0,
177+
value);
177178
}
178179
std::stringstream ss;
179-
ss << "discrepancy " << o.solution_discrepancy;
180+
ss << "discrepancy " << lds_output.solution_discrepancy;
180181
output.solution_pool.add(solution, ss, parameters.info);
181182
}
182183
};

packingsolver/onedimensional/solution.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,16 @@ void Solution::append(
6262
const std::vector<ItemTypeId>& item_type_ids)
6363
{
6464
const SolutionBin& bin = solution.bins_[bin_pos];
65+
66+
if (!bin_type_ids.empty()) {
67+
if (bin.bin_type_id >= (BinPos)bin_type_ids.size()) {
68+
throw std::runtime_error(
69+
"onedimensional::Solution::append"
70+
"; bin.bin_type_id: " + std::to_string(bin.bin_type_id)
71+
+ "; bin_type_ids.size(): " + std::to_string(bin_type_ids.size()));
72+
}
73+
}
74+
6575
BinTypeId bin_type_id = (bin_type_ids.empty())?
6676
solution.bins_[bin_pos].bin_type_id:
6777
bin_type_ids[bin.bin_type_id];

packingsolver/rectangle/optimize.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,10 @@ Output packingsolver::rectangle::optimize(
188188
BinPos value = std::round(pair.second);
189189
if (value < 0.5)
190190
continue;
191-
std::shared_ptr<VariableSizeBinPackingColumnExtra<Solution>> extra
192-
= std::static_pointer_cast<VariableSizeBinPackingColumnExtra<Solution>>(column.extra);
193-
solution.append(extra->solution, 0, value, {extra->bin_type_id}, extra->kp2vbpp);
191+
solution.append(
192+
*std::static_pointer_cast<Solution>(column.extra),
193+
0,
194+
value);
194195
}
195196
std::stringstream ss;
196197
ss << "discrepancy " << o.solution_discrepancy;

packingsolver/rectangleguillotine/optimize.cpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,10 @@ Output packingsolver::rectangleguillotine::optimize(
166166
if (value < 0.5)
167167
continue;
168168
//std::cout << "append val " << value << " col " << column << std::endl;
169-
std::shared_ptr<VariableSizeBinPackingColumnExtra<Solution>> extra
170-
= std::static_pointer_cast<VariableSizeBinPackingColumnExtra<Solution>>(column.extra);
171-
solution.append(extra->solution, 0, value, {extra->bin_type_id}, extra->kp2vbpp);
169+
solution.append(
170+
*std::static_pointer_cast<Solution>(column.extra),
171+
0,
172+
value);
172173
}
173174
std::stringstream ss;
174175
ss << "discrepancy " << o.solution_discrepancy;

0 commit comments

Comments
 (0)