Hi,
We trying to solve the next optimization problem?
We have:
The searching result is matrix of 3 x 30 of binary values Xij with next conditions:
Constraints:
Objective: Optimize:
Is it possible to solve the problem by the lpsolve or milpsolve subroutine?
Is there another predefined subroutine in SAS/IML which can be used to solve this problem? We haven’t the SAS/OR.
Thank you in advance,
Boriana
The key to this problem is understanding that the variables in your program need to be expressed as vectors, even though you are thinking of them as matrices,
Let's use a smaller matrix as an example. Instead of 3x30, consider a 3x4 matrix of probabilities called P. Then the binary solution vector X contains nrow(P)*ncol(P) elements. To make X into a vector, string out the elements of X rowwise, so that the first row comes first, then the second, then the third.
There are two linear constraints, the row constraints and the column constraints. The row constraints say that the sum of the i_th row of X is less than a specified b_i. The column constraints say that there is only one 1 in each column.
The following program solves a 3x4 example. I don't have time to explain it all, so study the MILP blog post and carefully study how I constructed the constraint matrices for rows and columns. If I wrote the program well and didn't make any errors, you should only need to input your probability matrix for P and specify the values of the B1 vector.
At the end of the program, the solution vector is reshaped into a matrix, for easy interpretation.
proc iml;
/* Probability matrix */
P = {0.5 0.5 0 0,
0 0.5 0.5 0,
0.5 0 0 0.5};
/* The binary solution vector X has nrow(P)*ncol(P) elements.
There are nrow(P) constraints on the row sums.
There are ncol(P) constraints on the column sums. */
/* information about variables */
colType = j(nrow(P)*ncol(P), 1, 'B'); /* binary */
/* objective function */
c = shape(P, 1); /* reshape into vector for objective function c*x */
/* linear constraints */
S = j(1, ncol(P), 1);
A1 = I(nrow(P)) @ S; /* constraint that sum across row <= B[i] */
print A1;
A2 = j(1,nrow(P),1) @ I(ncol(P)); /* constraint that sum of rows is 1 */
print A2;
A = A1 // A2; /* both constraints */
b1 = {2, 3, 2}; /* RHS of constraint for A1 */
b2 = j(ncol(P), 1, 1); /* RHS of constraint for A2 */
b = b1 // b2;
/* specify symbols for constraints:
'L' for less than or equal
'E' for equal
'G' for greater than or equal */
LEG1 = j(nrow(P),1, "L"); /* constraints for A1 */
LEG2 = j(ncol(P),1,"E"); /* constraints for A2 */
LEG = LEG1 // LEG2;
/* control vector for optimization */
ctrl = {-1, /* maximize objective */
1}; /* print level */
CALL MILPSOLVE(rc, objVal, result, relgap, /* output variables */
c, A, b, /* objective and linear constraints */
ctrl, /* control vector */
coltype, LEG);
X = shape(result, nrow(P), ncol(P));
print rc objVal, X;
What you want is probably the MILPSOLVE (Mixed Integer Linear Program) subroutine well described in this article:
http://blogs.sas.com/content/iml/2017/01/18/milp-sas.html
Documentation:
I tried to do this with next construction
proc iml;
object = { 7 19 30};
coef = { 0.0756 0.0782 0.0241,
0.2657 0.1985 0.1728,
0.1269 0.1101 0.0609,
0.3941 0.5391 0.6155,
0.2516 0.1239 0.1977,
0.1269 0.1405 0.0609,
0.4798 0.3912 0.3524,
0.2262 0.2216 0.2696,
0.3540 0.1645 0.2696,
0.0367 0.0728 0.0808,
0.7796 0.6506 0.7071,
0.7618 0.3593 0.3524,
0.4556 0.2055 0.1863,
0.7796 0.6242 0.5432,
0.7870 0.4469 0.4759,
0.0298 0.0498 0.0241,
0.0137 0.0498 0.0241,
0.5738 0.2264 0.1224,
0.8033 0.7063 0.5289,
0.0367 0.0970 0.0474
};
b ={ 1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1,
1};
rowsense = {L,L};
cntl = -1;
call milpsolve(rc,objv,x,relgap,object,coef,b,cntl,,rowsense);
print objv, x, relgap;
quit;
But it doesn't work. What I should change?
It is written that the output is vector. I want to 3 x 30 dimension matrix.
The key to this problem is understanding that the variables in your program need to be expressed as vectors, even though you are thinking of them as matrices,
Let's use a smaller matrix as an example. Instead of 3x30, consider a 3x4 matrix of probabilities called P. Then the binary solution vector X contains nrow(P)*ncol(P) elements. To make X into a vector, string out the elements of X rowwise, so that the first row comes first, then the second, then the third.
There are two linear constraints, the row constraints and the column constraints. The row constraints say that the sum of the i_th row of X is less than a specified b_i. The column constraints say that there is only one 1 in each column.
The following program solves a 3x4 example. I don't have time to explain it all, so study the MILP blog post and carefully study how I constructed the constraint matrices for rows and columns. If I wrote the program well and didn't make any errors, you should only need to input your probability matrix for P and specify the values of the B1 vector.
At the end of the program, the solution vector is reshaped into a matrix, for easy interpretation.
proc iml;
/* Probability matrix */
P = {0.5 0.5 0 0,
0 0.5 0.5 0,
0.5 0 0 0.5};
/* The binary solution vector X has nrow(P)*ncol(P) elements.
There are nrow(P) constraints on the row sums.
There are ncol(P) constraints on the column sums. */
/* information about variables */
colType = j(nrow(P)*ncol(P), 1, 'B'); /* binary */
/* objective function */
c = shape(P, 1); /* reshape into vector for objective function c*x */
/* linear constraints */
S = j(1, ncol(P), 1);
A1 = I(nrow(P)) @ S; /* constraint that sum across row <= B[i] */
print A1;
A2 = j(1,nrow(P),1) @ I(ncol(P)); /* constraint that sum of rows is 1 */
print A2;
A = A1 // A2; /* both constraints */
b1 = {2, 3, 2}; /* RHS of constraint for A1 */
b2 = j(ncol(P), 1, 1); /* RHS of constraint for A2 */
b = b1 // b2;
/* specify symbols for constraints:
'L' for less than or equal
'E' for equal
'G' for greater than or equal */
LEG1 = j(nrow(P),1, "L"); /* constraints for A1 */
LEG2 = j(ncol(P),1,"E"); /* constraints for A2 */
LEG = LEG1 // LEG2;
/* control vector for optimization */
ctrl = {-1, /* maximize objective */
1}; /* print level */
CALL MILPSOLVE(rc, objVal, result, relgap, /* output variables */
c, A, b, /* objective and linear constraints */
ctrl, /* control vector */
coltype, LEG);
X = shape(result, nrow(P), ncol(P));
print rc objVal, X;
Thank you for the solution.
It is worked!!!
We have to applie for the large number of customers.
When I check the same with this data I receive the next:
ERROR: The number of variables or constraints exceeds 500 limit, which will require a SAS/OR product license.
ERROR: Either the SAS/OR product with which MILPSOLVE is associated is not licensed for your system or the product license has expired. Please contact your SAS installation representative.
Is it possible to extend this size of constraints by setting for SAS/IML?
The documentation for the MILSOLVE call says "For complete functionality the SAS/OR product must also be installed, otherwise the maximum number of variables and maximum number of constraints is restricted to 500."
Registration is now open for SAS Innovate 2025 , our biggest and most exciting global event of the year! Join us in Orlando, FL, May 6-9.
Sign up by Dec. 31 to get the 2024 rate of just $495.
Register now!
Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.
Find more tutorials on the SAS Users YouTube channel.