Having negative value for non basic variable gives a non feasible solution in simplex method? - linear-programming

Objective function => x1 - 2x2
Subject to =>
x2 <= 5
x1 - x2 >= 2
x1 ,x2, x3 >= 0
Maximize?
convert to standard form :
Maximize -> -x1 + 2x2
Subject to ->
x2 <= 5
-x1 + x2 <= -2
convert to slack form :
Z = -x1 + 2x2
x3 = 5 - x2
x4 = -2 +x1 -x2
Basic solution (0,0,5,-2)
Can I found optimal solution in here? If not why?

Related

National competition in programming math problem

I encountered this problem practicing for an upcoming national competition. The problem goes as follows: You need to create a mixture of two ingredients being in relation to 1:1. You are given N different mixtures, each having its own weight Wi, and its relation in the mixture between the ingredients Mi, Ti (Each value, N, Wi, Mi, and Ti, will be less than 100). We need to find the biggest possible weight of the final mixture, keeping the relation to 1:1. We can take from each given mixture how much we want, we don't necessarily need to take the whole mixture, we can take some portion of it.
So with the given relation 1:1 in the final mixture, we know that we need to have an equal amount of weight from both ingredients possible. After that I need to know if I take K grams of some mixture, how much weight that is for ingredients A and B. So I came up with the following formula:
Let W be the weight in grams, and M and T be the relation between the ingredients respectively. If we want to take K (K <= W) grams we have the following:
Weight of ingredient A = M * (K / (M+T))
Weight of ingredient B = T * (K / (M+T))
#include <bits/stdc++.h>
using namespace std;
class state{
public:
int weight;
int A;
int B;
};
int n;
vector<state> arr;
double ans= 0;
void f(double weight_A, double weight_B, int idx){
if(weight_A == weight_B)
ans = max(ans, weight_A + weight_B);
if(idx >= n)
return;
int weight = arr[idx].weight, relA = arr[idx].A, relB = arr[idx].B;
for(int K = 0; K <= weight; K++){
f(weight_A + relA * (K * 1.0/(relA + relB)), weight_B + relB * (K * 1.0/(relA + relB)), idx+1);
}
}
int main(){
cin>>n;
for(int i = 0; i < n; i++){
state in;
cin>>in.weight>>in.A>>in.B;
arr.push_back(in);
}
f(0.0, 0.0, 0);
cout<<fixed<<setprecision(8);
cout<<ans<<endl;
}
The problem I encountered was that we don't necessarily need to take integer weights, some times to achieve the maximum possible weight of the final product we need to take decimal weights. Let's take a look at this example:
5
14 3 2
4 1 3
4 2 2
6 6 1
10 4 3
We have N = 5, and in each row are given 3 integers, Wi, Mi, and Ti. The weight of the ith mixture and its relation. My solution for this example gives 20.0000, and the correct solution for the above example is 20.85714286. Looking back my initial idea won't work because of the decimal numbers. I suppose there is some formula but I can't figure it out, can anyone help?
This is a Linear Programming problem, so you can solve it by constructing the problem in standard form, and then solve it with an optimization algorithm, like the simplex algorithm.
The objective is to maximize the quantity of medicine (from the original problem), that is the sum of quantities taken from each jar (I'll call the quantities x1, x2, ...).
The quantities are bounded to be lower than the weight Wi available in each jar.
The constraint is that the total amount of honey (first ingredient) is equal to the total amount of tahini (second ingredient). This would mean that:
sum(Mi/(Mi+Ti)*xi) = sum(Ti/(Mi+Ti)*xi)
You can take the second summation to the LHS and get:
sum((Mi-Ti)/(Mi+Ti)*xi) = 0
In order to get integer multipliers just multiply everything by the least common multiple of the denominators lcm(Mi+ti) and then divide by the gcd of the coefficients.
Using your example, the constraint would be:
(3-2)/(3+2) x1 + (1-3)/(1+3) x2 + (2-2)/(2+2) x3 + (6-1)/(6+1) x4 + (4-3)/(4+3) x5 = 0
that is
1/5 x1 -2/4 x2 + 0/4 x3 + 5/7 x4 + 1/7 x5 = 0
Multiply by the lcm(5,4,4,7,7)=140:
28 x1 -70 x2 + 0 x3 + 100 x4 + 20 x5 = 0
divide by 2:
14 x1 -35 x2 +0 x3 + 50 x4 + 10 x5 = 0
We are ready to solve the problem. Let's write it in CPLEX format:
maximize
quantity: x1 + x2 + x3 + x4 + x5
subject to
mix: 14 x1 -35 x2 +0 x3 + 50 x4 + 10 x5 = 0
bounds
x1 <= 14
x2 <= 4
x3 <= 4
x4 <= 6
x5 <= 10
end
Feed it to GLPK:
#include <stdio.h>
#include <stdlib.h>
#include <glpk.h>
int main(void)
{
glp_prob *P;
P = glp_create_prob();
glp_read_lp(P, NULL, "problem.cplex");
glp_adv_basis(P, 0);
glp_simplex(P, NULL);
glp_print_sol(P, "output.txt");
glp_delete_prob(P);
return 0;
}
And the output is:
Problem:
Rows: 1
Columns: 5
Non-zeros: 4
Status: OPTIMAL
Objective: quantity = 20.85714286 (MAXimum)
No. Row name St Activity Lower bound Upper bound Marginal
------ ------------ -- ------------- ------------- ------------- -------------
1 mix NS 0 0 = 0.0714286
No. Column name St Activity Lower bound Upper bound Marginal
------ ------------ -- ------------- ------------- ------------- -------------
1 x1 B 2.85714 0 14
2 x2 NU 4 0 4 3.5
3 x3 NU 4 0 4 1
4 x4 NL 0 0 6 -2.57143
5 x5 NU 10 0 10 0.285714
Karush-Kuhn-Tucker optimality conditions:
KKT.PE: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality
KKT.PB: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality
KKT.DE: max.abs.err = 0.00e+00 on column 0
max.rel.err = 0.00e+00 on column 0
High quality
KKT.DB: max.abs.err = 0.00e+00 on row 0
max.rel.err = 0.00e+00 on row 0
High quality
End of output
Of course given your input you should construct the problem in memory and feed it to the simplex algorithm without going through a file. Additionally, there's no need to get integer coefficients, it was just to allow a nicer problem formulation.

LPSolve IDE cannot find solution

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!

Setting up an Minimizing the sum of absolute deviation linear programing problem in CPlex

I am new to CPLEx and trying to set up my first problem. What I want to do set up a LP to minimise the sum of absolute deviations. I have set up the below as a start (based on googling possibilities). This is only a single deviation. I thought I would get this to work and then add to ti. It loads ok but won't solve. Can anyone shed some light on where I need to go next?
Minimize
obj: y1pos + y1neg
Subject To
c1: x0 + x1 + x2 + x3 = 1
c2: y1pos - y1neg + 451320 x0 + 500870 x1 + 483425 x2 + 447330 x3 = 58999
Bounds
0 <= x0 <= 1
0 <= x1 <= 1
0 <= x2 <= 1
0 <= x3 <= 1
y1pos >= 0
y1neg <= 0
End
As Erwin Kalvelagen suggested, changing y1neg <= 0 to y1neg >= 0 was the answer since our our error factor in our constraint is y1pos - y1neg which we want to minimise.

Is there an algorithmic way to either of these two tasks in programming? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm doing research in math and I need to perform the following tasks:
Given an unspecified set of vectors, determine which ones can sum to identity vector (1, 1, ..., 1)
For example, consider the vectors
x1 = (1 0 0)
x2 = (0 1 1)
x3 = (1 0 0)
If you add vectors x1 and x2 together, you get (1, 1, 1).
Or for a bigger example
x1 = (1 0 0 0)
x2 = (0 1 1 0)
x3 = (0 0 1 1)
x4 = (0 0 0 1)
If you add vectors 1, 2, and 4 together, you get (1, 1, 1, 1).
I need an algorithm that can do this in general.
The second task... given an unspecified set of numbers, determine which ones sum to 1.
For example:
x1 = 0.2
x2 = 0.5
x3 = 0.6
x4 = 0.4
x5 = 0.3
x6 = 0.1
x1 + x2 + x5 = 0.2 + 0.5 + 0.3 = 1
But also, x1 + x4 + x5 + x6 = 1
I need to be able to program the computer to do one of the above tasks to further my research.
For the first task, it is a variation of the subset sum problem, which can be solved by dynamic programming. The difference between the subset sum problem and your problem is that subset sum problem only have one dimension. In your case, you need to extend its dynamic programming approach to work with multiple dimensions.
For your second task, it is identical to the subset sum problem.
Yeah, research...
How about starting with brute force: create all the 2^N subsets of your set, and for each such candidate make the sum, if it matches the target, store it.

What would this look like as pseudocode?

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.