-
Notifications
You must be signed in to change notification settings - Fork 69
Description
The method descibed in https://optimization.cbe.cornell.edu/index.php?title=Optimization_with_absolute_values
uses a binary (and Mixed-Integer Linear Programming) to resolve the non convexity issue.
I made the following test (extracted from a larger app) which does not not result in the optimal solution (the binary is 0, while 1 would deliver the optimal result).
Help is appreciated. Rob
--------------------------- %< ----------------------------------
// absolute value handling method for constraint |d| >= C:
// introduce binary B and large constant N (> maximal d + C)
// (a) d:min -> d >= C - NB
// (b) d:max -> d <= -C + N(1-B)
// (c) d can be negative, so must be set to 'unrestricted'
// absolute value handling method for optimizing b: introduce b+ and b-
// (a): replace b by b+ - b-;
// (b): replace |b| by b+ + b-;
// (c): (implicit) -> b+ >= 0;
// (d): (implicit) -> b- >= 0
let W = 600;
let p1 = W/3;
let p2 = W/3*2;
let w1 = 200;
let w2 = 200;
let sep = 20;
let N = W * 2;
let mind12 = (w1 + w2)/2+sep;
let model = {
variables: {
'I1': {
'I1:max': 1,
'd12:def': -1,
'b1_def': -1,
},
'I2': {
'I2:max': 1,
'd12:def': 1,
'b2_def': -1,
},
'd12': {
'd12:def': 1,
'd12:min': 1,
'd12:max': 1,
},
'bin': {
'd12:min': N,
'd12:max': N,
},
'b1_pos': {
'b1_def': 1,
'bndOpt': 1,
},
'b1_neg': {
'b1_def': -1,
'bndOpt': 1,
},
'b2_pos': {
'b2_def': 1,
'bndOpt': 1,
},
'b2_neg': {
'b2_def': -1,
'bndOpt': 1,
},
},
constraints: {
'I1:max': { max: W - w1 },
'I2:max': { max: W - w2 },
'd12:def': { equal: (w1 - w2)/2 },
'd12:min': { min: mind12 },
'd12:max': { max: N-mind12 },
'b1_def': { equal: w1/2 - p1 },
'b2_def': { equal: w2/2 - p2 },
},
binaries: {
'bin': 1
},
unrestricted: {
'd12': 1,
},
optimize: 'bndOpt',
opType: 'min',
};
let result = solver.Solve(model);
console.log(JSON.stringify(result));
// result:
// {"feasible":true,"result":420,"bounded":true,"isIntegral":true,"b2_neg":120,
// "I1":400,"b1_pos":300,"I2":180,"d12":220}
// so |b1| + |b2| = 300 + 120 = 420
// this is because bin = 0
// expected result:
// {"feasible":true,"result":20,"bounded":true,"isIntegral":true,
// "I1":80,"d12":220,"I2":300,"b1_neg":20 ,"bin":1}
// so |b1| + |b2| = 20 + 0 = 20 which is OK!