-
Notifications
You must be signed in to change notification settings - Fork 0
/
mlbpformulation.cpp
123 lines (110 loc) · 3.14 KB
/
mlbpformulation.cpp
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
#include "mlbpformulation.h"
#include "instance.h"
#include "solution.h"
#include "users.h"
void MLBPFormulation::createDecisionVariables(IloEnv env, const Instance<MLBP>& inst)
{
// decision variables x_{kij}
x = IloArray<IloArray<IloNumVarArray>>(env, inst.m+1);
int var_x_count = 0;
for (int k : inst.M) {
x[k] = IloArray<IloNumVarArray>(env, inst.n[k-1]);
for (int i = 0; i < inst.n[k-1]; i++) {
x[k][i] = IloNumVarArray(env, inst.n[k], 0, 1, ILOBOOL);
var_x_count += inst.n[k];
}
}
MIP_OUT(TRACE) << "created " << var_x_count << " x_{kij} variables" << std::endl;
// decision variables y_{kj}
y = IloArray<IloNumVarArray>(env, inst.m+1);
int amount_of_bins = 0;
for (int k : inst.M) {
y[k] = IloNumVarArray(env, inst.n[k], 0, 1, ILOBOOL);
amount_of_bins += inst.n[k];
}
MIP_OUT(TRACE) << "created " << amount_of_bins << " y_{kj} variables" << std::endl;
}
void MLBPFormulation::addConstraints(IloEnv env, IloModel model, const Instance<MLBP>& inst)
{
//1. All items must be put into level 1
int num = 0;
for (int i = 0; i < inst.n[0]; i++) {
IloExpr sum(env);
for (int j = 0; j < inst.n[1]; j++) {
sum += x[1][i][j];
}
model.add(sum == 1);
sum.end();
num++;
}
MIP_OUT(TRACE) << "added " << num << " constraints to enforce the packing of each item" << std::endl;
//2. All used bins (level 1+) must be put into the next level
num = 0;
for (int k = 2; k <= inst.m; k++) {
for (int i = 0; i < inst.n[k - 1]; i++) {
IloExpr sum(env);
for (int j = 0; j < inst.n[k]; j++) {
sum += x[k][i][j];
}
model.add(sum == y[k - 1][i]);
sum.end();
num++;
}
}
MIP_OUT(TRACE) << "added " << num << " constraints to enforce the packing of each used bin to the next level" << std::endl;
//3. All bins' capacity must be greater than the size of its contents
num = 0;
for (int k : inst.M) {
num += inst.n[k];
for (int j = 0; j < inst.n[k]; j++) {
IloExpr sum(env);
for (int i = 0; i < inst.n[k - 1]; i++) {
sum += x[k][i][j] * inst.s[k-1][i];
}
model.add(sum <= y[k][j] * inst.w[k][j]);
sum.end();
}
}
MIP_OUT(TRACE) << "added " << num << " capacity constraints" << std::endl;
}
void MLBPFormulation::addObjectiveFunction(IloEnv env, IloModel model, const Instance<MLBP>& inst)
{
IloExpr sum(env);
for (int k : inst.M) {
for (int j = 0; j < inst.n[k]; j++) {
sum += y[k][j] * inst.c[k][j];
}
}
model.add(IloMinimize(env, sum));
sum.end();
}
void MLBPFormulation::extractSolution(IloCplex cplex, const Instance<MLBP>& inst, Solution<MLBP>& sol)
{
// add cost of each bin that has been used
sol.total_bin_cost = 0;
for (int k : inst.M) {
for (int j = 0; j < inst.n[k]; j++) {
if (cplex.getValue(y[k][j]) > 0.5) {
sol.total_bin_cost += inst.c[k][j];
}
}
}
// initalize sol.item_to_bins (size = m x n[0])
for (int i = 0; i < inst.m; i++) {
sol.item_to_bins[i].assign(inst.n[0], -1);
}
for (int j = 0; j < inst.n[0]; j++) {
int i = j;
for (int k = 1; k < inst.m + 1; k++) {
int res = -1;
for (int h = 0; h < inst.n[k]; h++) {
if (cplex.getValue(x[k][i][h]) > 0.5) {
res = h;
break;
}
}
sol.item_to_bins[k - 1][j] = res;
i = res;
}
}
}