Solving a non linear Programming and not getting results
Awaiting user inputDear Gurobi User Community, I have been trying to solve a nonlinear Programing, But for every question that I am introducing m.addGenConstrPow(), I am getting a confusion. I am attaching a question with its Solution.
The solution attempted is as follows:
m=gp.Model('Ware House') X=[5, 10, 0, 12] Y=[10, 5, 12, 0] C=[i for i in range(4)] x=m.addVar(vtype=GRB.CONTINUOUS, name='x') y=m.addVar(vtype=GRB.CONTINUOUS, name='y')
x1=m.addVars(C, vtype=GRB.CONTINUOUS, name='x1') y1=m.addVars(C, vtype=GRB.CONTINUOUS, name='y1')
D=m.addVars(C, vtype=GRB.CONTINUOUS, name='D') d=m.addVars(C, vtype=GRB.CONTINUOUS, name='d') O=m.addVars(C, vtype=GRB.CONTINUOUS, name='O') for i in C: m.addConstr(x1[i]==x-X[i], name='c'+str(i)) m.addConstr(y1[i]==y-Y[i], name='C'+str(i)) m.addConstr(d[i]==(x1[i]*x1[i])+(y1[i]*y1[i]), name='Co'+str(i)) m.addGenConstrPow(d[i], D[i], 0.5) m.setObjective(200*D[0]+150*D[1]+200*D[2]+300*D[3], GRB.MINIMIZE) m.params.NonConvex = 2 m.update() m.optimize() m.printAttr('X')
The results that I am getting are as follows:
Variable X ------------------------- x 12 y 12 x1[0] 7 x1[1] 2 x1[2] 12 y1[0] 2 y1[1] 7 y1[3] 12 D[0] 0.991539 D[1] 0.991539 D[2] 2.69399 D[3] 2.69399 d[0] 53 d[1] 53 d[2] 144 d[3] 144
If we put the values in D, which is supposed to be the square root of d, I am not geiing the results
D[0]=sqrt(d[0])= sqrt(53)=7.28
but in gurobi, it is 0.99
Kindly help in this regard.
Regards,
Biswajit Kar
-
Hi Biswajit,
The behavior you see is caused by the piecewise approximation approach of the \(\sqrt{}\) function. It is necessary to provide tight lower and upper bounds for all variables participating in nonlinear PWL terms. Without good bounds, the constructed PWL approximation is very weak and leads to numerical inaccuracies.
Note that your \(\texttt{x1[i],y1[i]}\) can be negative and a variable's lower bound equals \(0\) per default. Setting the following bounds
x=m.addVar(ub=100,vtype=GRB.CONTINUOUS, name='x')
y=m.addVar(ub=100,vtype=GRB.CONTINUOUS, name='y')
x1=m.addVars(C,lb=-100, ub=100, vtype=GRB.CONTINUOUS, name='x1')
y1=m.addVars(C,lb=-100, ub=100, vtype=GRB.CONTINUOUS, name='y1')
D=m.addVars(C, ub=100, vtype=GRB.CONTINUOUS, name='D')
d=m.addVars(C, ub=100, vtype=GRB.CONTINUOUS, name='d')improves the numerical stability but is still far from perfect.
Did you consider using the Manhattan distance for your coordinates instead of the Euclidean distance? This would avoid using squares and the \(\sqrt{}\) function and use the abs function instead.
Best regards,
Jaromił0
Please sign in to leave a comment.
Comments
1 comment