|
1 | 1 | #include "rectangle/dual_feasible_functions.hpp"
|
2 | 2 |
|
3 | 3 | #include "packingsolver/rectangle/algorithm_formatter.hpp"
|
| 4 | +#include "packingsolver/rectangle/instance_builder.hpp" |
4 | 5 |
|
5 | 6 | using namespace packingsolver;
|
6 | 7 | using namespace packingsolver::rectangle;
|
@@ -92,8 +93,96 @@ DualFeasibleFunctionsOutput packingsolver::rectangle::dual_feasible_functions(
|
92 | 93 | break;
|
93 | 94 | }
|
94 | 95 | }
|
95 |
| - if (!all_items_oriented) |
| 96 | + if (!all_items_oriented) { |
| 97 | + // If there are some non-oriented items, we use the strategy from |
| 98 | + // clautiaux2007: |
| 99 | + // - Build a modified instance containing for each item of the original |
| 100 | + // instance, one item for each orientation. |
| 101 | + // - Compute the bound on the modified instance. |
| 102 | + // - Divide it by 2 to get the bound of the original instance. |
| 103 | + |
| 104 | + BinPos bound = 0; |
| 105 | + for (;;) { |
| 106 | + // Build modified instance. |
| 107 | + InstanceBuilder modified_instance_builder; |
| 108 | + modified_instance_builder.set_objective(instance.objective()); |
| 109 | + modified_instance_builder.set_parameters(instance.parameters()); |
| 110 | + // Add bins and dummy items. |
| 111 | + if (bin_type.rect.x == bin_type.rect.y) { |
| 112 | + modified_instance_builder.add_bin_type( |
| 113 | + bin_type.rect.x, |
| 114 | + bin_type.rect.y, |
| 115 | + -1, |
| 116 | + 2 * instance.number_of_items()); |
| 117 | + } else if (bin_type.rect.x > bin_type.rect.y) { |
| 118 | + modified_instance_builder.add_bin_type( |
| 119 | + bin_type.rect.x, |
| 120 | + bin_type.rect.x, |
| 121 | + -1, |
| 122 | + 2 * instance.number_of_items() + bound); |
| 123 | + modified_instance_builder.add_item_type( |
| 124 | + bin_type.rect.x, |
| 125 | + bin_type.rect.x - bin_type.rect.y, |
| 126 | + -1, |
| 127 | + bound); |
| 128 | + } else if (bin_type.rect.x < bin_type.rect.y) { |
| 129 | + modified_instance_builder.add_bin_type( |
| 130 | + bin_type.rect.y, |
| 131 | + bin_type.rect.y, |
| 132 | + -1, |
| 133 | + 2 * instance.number_of_items() + bound); |
| 134 | + modified_instance_builder.add_item_type( |
| 135 | + bin_type.rect.y - bin_type.rect.x, |
| 136 | + bin_type.rect.y, |
| 137 | + -1, |
| 138 | + bound); |
| 139 | + } |
| 140 | + // Add items. |
| 141 | + for (ItemTypeId item_type_id = 0; |
| 142 | + item_type_id < instance.number_of_item_types(); |
| 143 | + ++item_type_id) { |
| 144 | + ItemType item_type = instance.item_type(item_type_id); |
| 145 | + item_type.oriented = true; |
| 146 | + if (item_type.rect.x == item_type.rect.y) { |
| 147 | + modified_instance_builder.add_item_type( |
| 148 | + item_type, |
| 149 | + item_type.profit, |
| 150 | + 2 * item_type.copies); |
| 151 | + } else { |
| 152 | + modified_instance_builder.add_item_type( |
| 153 | + item_type, |
| 154 | + item_type.profit, |
| 155 | + item_type.copies); |
| 156 | + item_type.rect.x = instance.item_type(item_type_id).rect.y; |
| 157 | + item_type.rect.y = instance.item_type(item_type_id).rect.x; |
| 158 | + modified_instance_builder.add_item_type( |
| 159 | + item_type, |
| 160 | + item_type.profit, |
| 161 | + item_type.copies); |
| 162 | + } |
| 163 | + } |
| 164 | + Instance modified_instance = modified_instance_builder.build(); |
| 165 | + |
| 166 | + // Compute the bound on the modified instance. |
| 167 | + DualFeasibleFunctionsParameters modified_parameters; |
| 168 | + modified_parameters.verbosity_level = 0; |
| 169 | + auto modified_output = dual_feasible_functions( |
| 170 | + modified_instance, |
| 171 | + modified_parameters); |
| 172 | + |
| 173 | + // Retrieve the bound of the original instance. |
| 174 | + BinPos bound_cur = (modified_output.bin_packing_bound - 1) / 2 + 1; |
| 175 | + if (bound >= bound_cur) |
| 176 | + break; |
| 177 | + bound = bound_cur; |
| 178 | + algorithm_formatter.update_bin_packing_bound(bound); |
| 179 | + |
| 180 | + if (bin_type.rect.x == bin_type.rect.y) |
| 181 | + break; |
| 182 | + } |
| 183 | + algorithm_formatter.end(); |
96 | 184 | return output;
|
| 185 | + } |
97 | 186 |
|
98 | 187 | // Compute all distinct widths and heights.
|
99 | 188 | std::vector<Length> widths;
|
|
0 commit comments