Closed ramnathv closed 8 years ago
Problem:
Rows: 10
Columns: 15
Non-zeros: 36
Status: UNDEFINED
Objective: obj = 0 (MAXimum)
No. Row name St Activity Lower bound Upper bound Marginal
------ ------------ -- ------------- ------------- ------------- -------------
1 R0 B 0 0
2 R1 B 0 0
3 R2 B 0 0
4 R3 B 0 0
5 R4 B 0 0
6 R5 B 0 0
7 R6 B 0 0
8 R7 B 0 0
9 R8 B 0 0
10 R9 B 0 20
No. Column name St Activity Lower bound Upper bound Marginal
------ ------------ -- ------------- ------------- ------------- -------------
1 r0 NL 0 0 1 < eps
2 r1 NL 0 0 1 < eps
3 r2 NL 0 0 1 < eps
4 r3 NL 0 0 1 < eps
5 r4 NL 0 0 1 < eps
6 r5 NL 0 0 1 < eps
7 r6 NL 0 0 1 < eps
8 r7 NL 0 0 1 < eps
9 r8 NL 0 0 1 < eps
10 t0 NL 0 0 1 < eps
11 t1 NL 0 0 1 < eps
12 t4 NL 0 0 1 < eps
13 t2 NL 0 0 1 < eps
14 t3 NL 0 0 1 < eps
15 t5 NL 0 0 1 < eps
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 = 1.20e+03 on column 5
max.rel.err = 9.99e-01 on column 5
DUAL SOLUTION IS WRONG
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
I have problems to get sensitivity reports on a very simple problem. The first part of code using glpkAPI gives me an pretty empty sensitivity analysis report. The second part of the code shows, Rglpk can give the correct answer.
library(Rglpk)
library(glpkAPI)
library(AlteryxPrescriptive)
mylp <- initProbGLPK()
readLPGLPK(mylp, getSampleData('table_chair.lp'))
#solFile <- tempfile(fileext = '.txt')
printSolGLPK(mylp, "sol.txt")
file.edit("sol.txt")
## Useing Rglpk, it gives correct solution
file <- "table_chair.lp"
x <- Rglpk_read_file(file, type = "CPLEX_LP")
Rglpk_solve_LP(obj = x$objective, mat = x$constraints[[1]], dir = x$constraints[[2]],
rhs = x$constraints[[3]], max = x$maximum)
Here's the file "table_chair.lp"
Maximize
70 t + 50 c
Subject To
c0: 4 t + 3 c <= 240
c1: 2 t + c <= 100
End
I'm able to manually input the problem above and get the sensitivity report though. But man, I don't ever want to manually input -- it takes 40 lines of code to specify such a simple one!
## Table Chair with glpkAPI ----
prob <- initProbGLPK()
setProbNameGLPK(prob, "table_chair")
setObjDirGLPK(prob, GLP_MAX)
addRowsGLPK(prob, 2)
addColsGLPK(prob, 2)
setRowNameGLPK(prob, 1, "p")
setRowNameGLPK(prob, 2, "q")
setColNameGLPK(prob, 1, "x1")
setColNameGLPK(prob, 2, "x2")
setRowBndGLPK(prob, 1, GLP_UP, 0, 240)
setRowBndGLPK(prob, 2, GLP_UP, 0, 100)
lb <- c(0, 0)
ub <- c(240, 100)
type <- rep(GLP_UP, 2)
setRowsBndsGLPK(prob, 1:2, lb, ub, type)
#Set the type and bounds of the columns.
setColBndGLPK(prob, 1, GLP_LO, 0, 0)
setColBndGLPK(prob, 2, GLP_LO, 0, 0)
#Set the objective function.
setObjCoefGLPK(prob, 1, 70)
setObjCoefGLPK(prob, 2, 50)
#Set the type and bounds of columns and the objective function using a function which
#has the ability to work with vectors.
lb <- c(0, 0)
ub <- lb
type <- rep(GLP_LO, 2)
obj <- c(70, 50)
setColsBndsObjCoefsGLPK(prob, 1:2, lb, ub, obj, type)
#Load the constraint matrix.
ia <- c(1, 1, 2, 2)
ja <- c(1, 2, 1, 2)
ar <- c(4, 3, 2, 1)
loadMatrixGLPK(prob, 4, ia, ja, ar)
#Solve the problem using the simplex algorithm.
solveSimplexGLPK(prob)
printSolGLPK(prob, "table_sol.txt")
file.edit("table_sol.txt")
mylp <- initProbGLPK()
readLPGLPK(mylp, getSampleData('table_chair.lp'))
#solFile <- tempfile(fileext = '.txt')
# you need this line here
solveSimplexGLPK(mylp)
printSolGLPK(mylp, "sol.txt")
file.edit("sol.txt")
Just to document it here, so we are aware of this: sensitivity analysis report doesn't always return Limiting variable. See the last line and the last column of the following. I'll need to modify my code for this :alien:
GLPK 4.47 - SENSITIVITY ANALYSIS REPORT Page 1
Problem: value
Objective: 296.2166065 (MINimum)
No. Row name St Activity Slack Lower bound Activity Obj coef Obj value at Limiting
Marginal Upper bound range range break point variable
------ ------------ -- ------------- ------------- ------------- ------------- ------------- ------------- ------------
1 yield NS 2000.00000 . 2000.00000 1995.06864 -Inf 296.28365 bin3
-.01360 2000.00000 2014.03479 +Inf 296.02579 cu
2 fe NU 60.00000 . -Inf 55.89016 -Inf 306.77162 bin4
-2.56823 60.00000 62.69978 2.56823 289.28294 bin3
3 cu BS 83.96751 16.03249 -Inf 93.88467 -.30613 270.51157 mn
. 100.00000 79.98213 .21474 314.24798 bin5
4 mn NU 40.00000 . -Inf 34.42336 -Inf 299.25255 bin4
-.54440 40.00000 41.68691 .54440 295.29825 bin3
5 mg BS 19.96029 10.03971 -Inf 24.74427 -1.79618 260.36433 bin1
. 30.00000 9.40292 .28757 301.95652 mn
6 al NL 1500.00000 . 1500.00000 1485.78425 -.25199 292.63444 cu
.25199 +Inf 1504.92126 +Inf 297.45669 bin3
7 si1 NL 250.00000 . 250.00000 235.32871 -.48520 289.09812 cu
.48520 +Inf 255.06073 +Inf 298.67206 bin3
8 si2 BS 250.00000 50.00000 -Inf 255.06073 -.48520 174.91697 si1
. 300.00000 250.00000 +Inf +Inf
@kuol I think we can close this, since you have already incorporated sensitivity analysis into the code.
yep definitely
Here is one way of doing it using the
glpkAPI
package@kuol Gurobi probably has a different format in the way it returns the sensitivity analysis report. I think we should write an S3 class that extracts the sensitivity analysis data for different solvers.