is there any chance to solve a logarithmic objective function using lpsolve?
indeed, I want to change the first line of the following code in lpsolve IDE to log(x11 b11 + x12 b12 + x21 b21 + x22 b22), but lpsolve can not solve it then. Does anybody here have dealt with this situation before? thanks.
max: x11 b11 + x12 b12 + x21 b21 + x22 b22;
x11 + x21 = 1;
x12 + x22 = 1;
54 = b11 x11 + b11 x12;
54 = b12 x11 + b12 x12;
54 = b21 x21 + b21 x22;
54 = b22 x21 + b22 x22;
bin x11, x12, x21, x22;
You don't need to include the log. The problem
max log(c'x)
st. Ax=b
has the same optimal solution as
max c'x
st. Ax=b
(I assume c'x > 0 as otherwise the log() can not be evaluated).
Related
I have following problem that I try to solve with LPSolve IDE:
min: x1;
r_1: 1.08 - k <= x1;
r_2: -1.08 + k <= x1;
c_1: y1 + y2 + y3 = k;
c_2: 2.29 a1 y1 + 2.28 a2 y1 + 2.27 a3 y1 = 1;
c_3: 1.88 b1 y2 + 1.89 b2 y2 + 1.9 b3 y2 = 1;
c_4: 8.98 c1 y3 + 8.99 c2 y3 + 9.0 c3 y3 = 1;
c_14: a1+a2+a3=1;
c_15: b1+b2+b3=1;
c_16: c1+c2+c3=1;
bin a1,a2,a3,b1,b2,b3,c1,c2,c3;
Not sure why I get output from LPSolve as INFEASIBLE when I can use following param values to solve this:
a1=0, a2=1, a3=0
b1=0, b2=1, b3=0
c1=0, c2=1, c3=0
0 + 2.28 0.438596491 + 0 = 1
0 + 1.89 0.529100529 + 0 = 1
0 + 8.99 0.111234705 + 0 = 1
0.438596491 + 0.529100529 + 0.111234705 = 1.0789 (this is k)
1.08 - 1.0789 == 0.0011 <= x1
-1.08 + 1.0789 == -0.0011 <= x1
x1 = 0.0011
Am I formulating the problem in a wrong way, or doing something else wrong? If I relax that =1 constraint to >=1 there are some results, but I need it to be 1 (as it is in my solution).
Lpsolve is for linear models only. You have products of variables in the model such as 2.29 a1 y1. Lpsolve can not solve such quadratic models.
Too bad you don't get a good error message. I guess they never expected this input.
It is noted that products of binary and continuous variables can be linearized resulting in so-called big-M constraints (see link).
This is really a duplicate of lpsolve - unfeasible solution, but I have example of 1. Embarrassingly, this was an earlier question from the same poster!
I have tried adding parenthesis to the code but lindo gives an error stating that its a variable. According to lindo documentation "(" should be accepted as a parenthesis but this does not occur. Removing the parenthesis causes the code to terminate as soon as it encounters the division symbol. Does anybody know what I'm missing in my code? (error occurs on the 4th, 5th and 6th line of code).
min Y1 + Y2 + Y3 + Y4 + Y5 + Y6
ST
Y1 + Y2 + Y3 + Y4 + Y5 + Y6 >= 1
5X11 + 10X12 + 2X13 + 5X14 + 4X15 + 4X16 / Y1 <= 10
5X21 + 10X22 + 2X23 + 5X24 + 4X25 + 4X26 / Y2 <= 10
5X31 + 10X32 + 2X33 + 5X34 + 4X35 + 4X36 / Y3 <= 10
This stems from beam equations. How do I extract and order constants in matrixes to solve a system of equations rather than doing so by hand?
If I start with the differential equation d4 v / dx4 = q. I integrate 4x, and obtain 4 (more) equations, and thus 4x constants/unknown. For example:
v(x) = q x4 / 24 + c1 x3 / 6 + c2 x2 / 2 + c3 x + c4
If I apply the boundary condition v(5) = 0 this equation becomes
v(5) = q × 54 / 24 + c1 × 53 / 6 + c2 × 52 / 2 + c3 × 5 + c4 = 0, or
c1 × 53 / 6 + c2 × 52 / 2 + c3 × 5 + c4 = -q × 54 / 24
Of course to solve for 4 coefficients the other 3 DEs are used with 3 more boundary conditions. I was wondering if any one knows how I could sort and extract the constants to built up the system of equations rather than doing so by hand.
I was trying to solve the following problem, using the GLPSOL solver:
Fred has $5000 to invest over the next five years. At the beginning of each year he can invest money in one- or two-year time deposits. The bank pays 4% interest on one-year time deposits and 9 percent (total) on two-year time deposits. In addition, West World Limited will offer three-year certificates starting at the beginning of the second year. These certificates will return 15% (total). If Fred reinvest his money that is available every year, formulate a linear program to show him how to maximize his total cash on hand at the end of the fifth year.
I came up with the following LP model:
Being xij the amount invested in option i at year j, we look to
maximize z = 1,04x15 + 1,09x24 + 1,15x33,
subject to:
x11 + x12 <= 5000
x31 = x34 = x35 = 0
x12 + x22 + x32 <= 1,04 x11
x13 + x23 + x33 <= 1,04 x12 + 1,09 x21
x14 + x24 <= 1,04 x13 + 1,09 x22
x15 <= 1,04 x14 + 1,09 x23 + 1,15 x32
xij >= 0
And tried to write it in GMPL:
/* Variables */
var x{i in 1..3, j in 1..5} >= 0;
/* Objective */
maximize money: 1.04*x[1,5] + 1.09*x[2,4] + 1.15*x[3,3];
/* Constraints */
s.t. x[1,1] + x[2,1] <= 5000;
s.t. x[3,1] = x[3,4] = x[3,5] = 0;
s.t. x[1,2] + x[2,2] + x[3,2] <= 1.04 * x[1,1];
s.t. x[1,3] + x[2,3] + x[3,3] <= 1.04 * x[1,2] + 1.09 * x[2,1];
s.t. x[1,4] + x[2,4] <= 1.04 * x[1,3] + 1.09 * x[2,2];
s.t. x[1,5] <= 1.04 * x[1,4] + 1.09 * x[2,3] + 1.15 * x[3,2];
/* Resolve */
solve;
/* Results */
printf{j in 1..5}:"\n* %.2f %.2f %2.f \n", x[1,j], x[2,j], x[3,j];
end;
However, I'm getting the following error:
inv.mod:14: x multiply declared
Context: ...[ 1 , 5 ] + 1.09 * x [ 2 , 4 ] + 1.15 * x [ 3 , 3 ] ; s.t. x
MathProg model processing error
Does anyone have any thoughts about this?
You have to give a unique name to each constraint. Multiple assignments are not allowed.
This works on my machine:
/* Variables */
var x{i in 1..3, j in 1..5} >= 0;
/* Objective */
maximize money: 1.04*x[1,5] + 1.09*x[2,4] + 1.15*x[3,3];
/* Restrições */
s.t. c1: x[1,1] + x[2,1] <= 5000;
s.t. c2: x[3,1] = 0;
s.t. c3: x[3,4] = 0;
s.t. c4: x[3,5] = 0;
s.t. c5: x[1,2] + x[2,2] + x[3,2] <= 1.04 * x[1,1];
s.t. c6: x[1,3] + x[2,3] + x[3,3] <= 1.04 * x[1,2] + 1.09 * x[2,1];
s.t. c7: x[1,4] + x[2,4] <= 1.04 * x[1,3] + 1.09 * x[2,2];
s.t. c8: x[1,5] <= 1.04 * x[1,4] + 1.09 * x[2,3] + 1.15 * x[3,2];
/* Resolve */
solve;
/* Results */
printf{j in 1..5}:"\n* %.2f %.2f %2.f \n", x[1,j], x[2,j], x[3,j];
end;
It prints:
* 0.00 5000.00 0
* 0.00 0.00 0
* 0.00 0.00 5450
* 0.00 0.00 0
* 0.00 0.00 0
Good luck!
I'm trying to implement this: from https://docs.google.com/viewer?url=http://www.tinaja.com/glib/bezdist.pdf&pli=1
The following BASIC program uses the method of finding distance. The
program also searches for the minimum squared distance between points and
a curve.
REM BEZIER.BAS JIM 20DEC92 12:37
DATA 2,3,5,8,8,14,11,17,14,17,16,15,18,11,-1
DATA 2,10,5,12,8,11,11,8,14,6,17,5,19,10,-1
DATA 2,5,5,7,8,8,12,12,13,14,12,17,10,18,8,17,7,14,8,12,12,8,15,7,18,5,-1
OPEN "BEZIER.OUT" FOR OUTPUT AS #1
OPEN "BEZ.ps" FOR OUTPUT AS #2
CLS
psscale = 20
FOR example% = 1 TO 3
REDIM rawdata(32)
FOR I% = 0 TO 32
READ rawdata(I%)
IF rawdata(I%) < 0! THEN EXIT FOR
NEXT I%
n% = I% - 1
PRINT "Example "; example%; (n% + 1) \ 2; " points"
PRINT #1, ""
PRINT #1, "Example "; example%; (n% + 1) \ 2; " points"
PRINT #1, " #
x
y"
J% = 0
FOR I% = 0 TO n% STEP 2
J% = J% + 1
PRINT #1, USING "### ####.### ####.###"; J%; rawdata(I%); rawdata(I% + 1)
LPRINT USING "####.### ####.### 3 0 360 arc fill"; rawdata(I%) * psscale; rawdata(I% + 1) * psscale
PRINT #2, USING "####.### ####.### 3 0 360 arc fill"; rawdata(I%) * psscale; rawdata(I% + 1) * psscale
NEXT I%
x0 = rawdata(0)
y0 = rawdata(1)
x1 = rawdata(2)
y1 = rawdata(3)
x2 = rawdata(n% - 3)
y2 = rawdata(n% - 2)
x3 = rawdata(n% - 1)
y3 = rawdata(n%)
IF example% = 3 THEN
’special guess for loop
x1 = 8 * x1 - 7 * x0
y1 = 8 * y1 - 7 * y0
x2 = 8 * x2 - 7 * x3
y2 = 8 * y2 - 7 * y3
ELSE
x1 = 2 * x1 - x0
y1 = 2 * y1 - y0
x2 = 2 * x2 - x3
y2 = 2 * y2 - y3
END IF
GOSUB distance
LPRINT ".1 setlinewidth"
PRINT #2, ".1 setlinewidth"
GOSUB curveto
e1 = totalerror
FOR Retry% = 1 TO 6
PRINT
PRINT "Retry "; Retry%
PRINT #1, "Retry "; Retry%
PRINT #1, " x1
y1
x2
y2
error"
e3 = .5
x1a = x1
DO
x1 = x1 + (x1 - x0) * e3
GOSUB distance
e2 = totalerror
IF e2 = e1 THEN
EXIT DO
ELSEIF e2 > e1 THEN
x1 = x1a
e3 = -e3 / 3
IF ABS(e3) < .001 THEN EXIT DO
ELSE
e1 = e2
x1a = x1
END IF
LOOP
e3 = .5
y1a = y1
DO
y1 = y1 + (y1 - y0) * e3
GOSUB distance
e2 = totalerror
IF e2 = e1 THEN
EXIT DO
ELSEIF e2 > e1 THEN
y1 = y1a
e3 = -e3 / 3
IF ABS(e3) < .01 THEN EXIT DO
ELSE
e1 = e2
y1a = y1
END IF
LOOP
e3 = .5
x2a = x2
DO
x2 = x2 + (x2 - x3) * e3
GOSUB distance
e2 = totalerror
IF e2 = e1 THEN
EXIT DO
ELSEIF e2 > e1 THEN
x2 = x2a
e3 = -e3 / 3
IF ABS(e3) < .01 THEN EXIT DO
ELSE
e1 = e2
x2a = x2
END IF
LOOP
e3 = .5
y2a = y2
DO
y2 = y2 + (y2 - y3) * e3
GOSUB distance
e2 = totalerror
IF e2 = e1 THEN
EXIT DO
ELSEIF e2 > e1 THEN
y2 = y2a
e3 = -e3 / 3
IF ABS(e3) < .01 THEN EXIT DO
ELSE
e1 = e2
y2a = y2
END IF
LOOP
IF Retry% = 6 THEN
LPRINT "1 setlinewidth"
PRINT #2, "1 setlinewidth"
END IF
GOSUB curveto
NEXT Retry%
LPRINT "100 200 translate"
PRINT #2, "100 200 translate"
NEXT example%
LPRINT "showpage"
PRINT #2, "showpage"
CLOSE #1
CLOSE #2
END
’
Bezier:
x = a0 + u * (a1 + u * (a2 + u * a3))
y = b0 + u * (b1 + u * (b2 + u * b3))
dx4 = x - x4: dy4 = y - y4
dx = a1 + u * (2 * a2 + u * 3 * a3)
dy = b1 + u * (2 * b2 + u * 3 * b3)
z = dx * dx4 + dy * dy4
s = dx4 * dx4 + dy4 * dy4
RETURN
’
distance:
totalerror = 0!
a3 = (x3 - x0 + 3 * (x1 - x2)) / 8
b3 = (y3 - y0 + 3 * (y1 - y2)) / 8
a2 = (x3 + x0 - x1 - x2) * 3 / 8
b2 = (y3 + y0 - y1 - y2) * 3 / 8
a1 = (x3 - x0) / 2 - a3
b1 = (y3 - y0) / 2 - b3
a0 = (x3 + x0) / 2 - a2
b0 = (y3 + y0) / 2 - b2
FOR I% = 2 TO n% - 2 STEP 2
x4 = rawdata(I%)
y4 = rawdata(I% + 1)
stepsize = 2 / (n% + 1)
FOR u = -1! TO 1.01 STEP stepsize
GOSUB Bezier
IF s = 0! THEN u1 = u: z1 = z: s1 = s: EXIT FOR
IF u = -1! THEN u1 = u: z1 = z: s1 = s
IF s < s1 THEN u1 = u: z1 = z: s1 = s
NEXT u
IF s1 <> 0! THEN
u = u1 + stepsize
IF u > 1! THEN u = 1! - stepsize
DO
GOSUB Bezier
IF s = 0! THEN EXIT DO
IF z = 0! THEN EXIT DO
u2 = u
z2 = z
temp = z2 - z1
IF temp <> 0! THEN
u = (z2 * u1 - z1 * u2) / temp
ELSE
u = (u1 + u2) / 2!
END IF
IF u > 1! THEN
u = 1!
ELSEIF u < -1! THEN
u = -1!
END IF
IF ABS(u - u2) < .0001 THEN EXIT DO
u1 = u2
z1 = z2
LOOP
END IF
totalerror = totalerror + s
NEXT I%
PRINT totalerror;
PRINT #1, USING "####.### ####.### ####.### ####.### ######.###"; x1; y1; x2; y2; totalerror
RETURN
’
curveto:
LPRINT USING "####.### ####.### moveto"; x0 * psscale; y0 * psscale
PRINT #2, USING "####.### ####.### moveto"; x0 * psscale; y0 * psscale
F$ = "####.### ####.### ####.### ####.### ####.### ####.### curveto stroke"
LPRINT USING F$; x1 * psscale; y1 * psscale; x2 * psscale; y2 * psscale; x3 * psscale; y3 * psscale
PRINT #2, USING F$; x1 * psscale; y1 * psscale; x2 * psscale; y2 * psscale; x3 * psscale; y3 * psscale
RETURN
I want to implement it in c++ because I'm trying to get my algorithm to best fit beziers from points.
What would the above look like in pseudo-code or c / c++?
thanks
The best approach here is to split the code bit by bit and do minor refactorings until it's in a usable state. Data can be changed into global variables at first.
Then start taking small chunks of the code and turning them into functions. At first they'll just use a bunch of global data. As you rewrite the pieces into C++ things will become more clear.
Once you have most of the code built out functionally, then you can start refactoring the variables. The goal would be to remove all the global non-const data and have all the working data be locals. const values can remain namespace level initialized data.
Finally once you have it procedure-based, you can decide if it's worth the effort to encapsulate the work into objects and methods. Depending on how long the program needs to be maintained grouping the data and methods may be a good long-term step.