BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
Lucassss
Obsidian | Level 7

Hello, 

 

I am a first time user of SAS optmodel procedure in SAS Enterprise Guide. I am wondering if the following code is a valid syntax/expression of the constraint.

 

con worse_con{i in bucket, j in AMOUNTS, k1 in 0..(10-i), k2 in 0..(17000-j) by 1000}: IF Move[i,j] = 1 THEN Move[i+k1, j+k2] = 0;

 I get this error and don't understand what it means:

ERROR: The NLP solver does not allow integer variables.

The full code is here for reference:

proc optmodel;
/* Index Sets */
set bucket;
set AMOUNTS=2000..17000 by 1000;

/* Parameters */
number orig_amount {bucket, AMOUNTS} init 0;
number loss_amount {bucket, AMOUNTS} init 0;
number profit {bucket, AMOUNTS} init 0;

/* Binary decision variables--approve (1) or deny (0) an amount per customer */
var Move {bucket, AMOUNTS} binary;

read data GRP1 nomiss
   into bucket=[BK_Group]
   	    
   {a in AMOUNTS} < loss_amount[BK_Group,a]=col("LO"||a)
					profit[BK_Group,a]=col("PR"||a)>;
print loss_amount;

/* Set up amount max and profit max objectives */
min Total_delta_loss = sum{c in bucket, a in AMOUNTS} loss_amount[c,a] * Move[c,a];

/* Approve exactly one loan amount per customer */
con One_Amount_con{c in bucket}: sum{a in AMOUNTS} Move[c,a] <= 1;

con worse_con{i in bucket, j in AMOUNTS, k1 in 0..(10-i), k2 in 0..(17000-j) by 1000}: IF Move[i,j] = 1 THEN Move[i+k1, j+k2] = 0;

impvar Total_Profit = sum{c in bucket, a in AMOUNTS} profit[c,a] * Move[c,a];

/* profit constraint: loss no more than 200,000 of profit */
con profit_con: Total_Profit >= -200000;

problem Problem1 include
   Move
   Total_delta_loss
   One_Amount_con worse_con profit_con;

use problem Problem1;
solve;

print Move;

create data solution
		from [BK_Group LO]
			={c in bucket, g in AMOUNTS: Move[c,g]^=0}
			amount=Move;
quit;

Any help is appreciated!

Lucas

 

1 ACCEPTED SOLUTION

Accepted Solutions
RobPratt
SAS Super FREQ

When you use an IF-THEN/ELSE expression in the body of a constraint, you introduce nonlinearity, so the default solver is NLP, which does not allow integer (in this case, binary) variables. To capture the desired logical implication between binary variables, you can use the following linear constraint instead:

Move[i,j] <= 1 - Move[i+k1, j+k2];

Check the two cases Move[i,j] = 1 and Move[i,j] = 0 to see how it works.

View solution in original post

4 REPLIES 4
RobPratt
SAS Super FREQ

When you use an IF-THEN/ELSE expression in the body of a constraint, you introduce nonlinearity, so the default solver is NLP, which does not allow integer (in this case, binary) variables. To capture the desired logical implication between binary variables, you can use the following linear constraint instead:

Move[i,j] <= 1 - Move[i+k1, j+k2];

Check the two cases Move[i,j] = 1 and Move[i,j] = 0 to see how it works.

Lucassss
Obsidian | Level 7

Hi Rob,

 

Thanks for the quick reply. The code ran without error, but produced a result seemed not correct. (all cells are 0's) 

 

Without the following constraint,

Move[i,j] <= 1 - Move[i+k1, j+k2],

the optimal result seemed more reasonable (although not correct):

Move

 

2000

3000

4000

5000

6000

7000

8000

9000

10000

11000

12000

13000

14000

15000

16000

17000

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

2

0

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

3

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

4

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

5

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

6

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

7

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

0

8

0

0

0

0

0

0

0

1

0

0

0

0

0

0

0

0

9

0

0

0

0

0

1

0

0

0

0

0

0

0

0

0

0

10

0

0

0

0

0

1

0

0

0

0

0

0

0

0

0

0

 

What I want is that if a cell is 1, then all the cells to the right and below should not be 1. More precisely, 

if cell[i,j] = 1, then cell[i+n, j+m] = 0 for all 1<=n<=9, 1<=m<=15 where n+i <= 10 and m+j <= 16

Something like the following table is my expected result:

Move

 

2000

3000

4000

5000

6000

7000

8000

9000

10000

11000

12000

13000

14000

15000

16000

17000

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

2

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

3

0

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

4

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

5

0

0

0

0

0

0

0

0

0

0

0

0

0

1

0

0

6

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

7

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

8

0

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

9

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

10

0

0

0

0

0

0

0

0

0

0

1

0

0

0

0

0

 

Do you know how can I modify my constraint statement in order to derive at this result?

 

Again, thanks for your help.

 

Lucas

RobPratt
SAS Super FREQ

Start k1 and k2 at 1 instead of 0.  What you have now forces 2*Move[i,j] <= 1, which by integrality implies Move[i,j] = 0.

Ready to join fellow brilliant minds for the SAS Hackathon?

Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.

Register today!
Multiple Linear Regression in SAS

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.

Discussion stats
  • 4 replies
  • 974 views
  • 0 likes
  • 2 in conversation