Turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Options

- RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

🔒 This topic is **solved** and **locked**.
Need further help from the community? Please
sign in and ask a **new** question.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Posted 02-26-2019 04:46 AM
(643 views)

I have below data:

id $ cost profit_1 profit_2 score;

A -1 10 11 500

B -0.6 10 5 700

C -0.75 10 10.5 700

D -0.75 10.5 10 600

E -0.65 12 11 300

F -0.65 12 13 350;

Following code does the work when considering profits only:

proc optmodel;

set <str> ITEMS;

num cost {ITEMS};

set CASES = 1..2;

num profit {ITEMS, CASES};

read data have into ITEMS=[id] cost {j in CASES} <profit[id,j]=col('profit_'||j)>;

var X {ITEMS, CASES} binary;

max TotalProfit = sum {i in ITEMS, j in CASES} profit[i,j] * X[i,j];

con ChooseOne {i in ITEMS}: sum {j in CASES} X[i,j] <= 1;

con Budget: sum {i in ITEMS, j in CASES} cost[i] * X[i,j] <= 1.5;

solve;

print X;

quit;

but I want to add another constraint on score.

Something like SCORE must be greater than 500, i tried inserting following -

num score {ITEMS}

then in read data statement- SCORE[id] = col('SCORE')

And finally the constraint- con MinScore SCORE{i in ITEMS}: SCORE[id]>=500

but this is leading to infeasible solution because of cases where SCORE >=500.

Can anyone help in how to do this and what am I doing wrong?

1 ACCEPTED SOLUTION

Accepted Solutions

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Here are four ways, in increasing order of efficiency.

1. Impose explicit constraint:

```
/* if X[i,j] = 1 then score[i] >= 500 */
con MinScore {i in ITEMS, j in CASES}: score[i] >= 500 * X[i,j];
```

2. Fix variables to 0:

```
/* if score[i] < 500 then X[i,j] = 0 */
for {i in ITEMS: score[i] < 500} for {j in CASES} fix X[i,j] = 0;
```

3. Modify index set after reading data:

```
read data have into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
ITEMS = {i in ITEMS: score[i] >= 500};
```

4. Use WHERE= in READ DATA:

```
read data have(where=(score >= 500)) into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
```

See also this doc example.

4 REPLIES 4

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Here are four ways, in increasing order of efficiency.

1. Impose explicit constraint:

```
/* if X[i,j] = 1 then score[i] >= 500 */
con MinScore {i in ITEMS, j in CASES}: score[i] >= 500 * X[i,j];
```

2. Fix variables to 0:

```
/* if score[i] < 500 then X[i,j] = 0 */
for {i in ITEMS: score[i] < 500} for {j in CASES} fix X[i,j] = 0;
```

3. Modify index set after reading data:

```
read data have into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
ITEMS = {i in ITEMS: score[i] >= 500};
```

4. Use WHERE= in READ DATA:

```
read data have(where=(score >= 500)) into ITEMS=[id] cost score {j in CASES} <profit[id,j]=col('profit_'||j)>;
```

See also this doc example.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks a lot for your response. I was able to do 3 and 4, but it was subsetting my observations in output, so wasn't inclined. Finally I found 2 but was quite sure that this can be done in CON statement. Thanks again for 1. Very grateful for what I am learning from you.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Glad to help. By the way, because of the ChooseOne constraint, you can tighten the MinScore constraint as follows:

`con MinScore {i in ITEMS}: score[i] >= 500 * sum {j in CASES} X[i,j];`

In either case, the MILP presolver will force X[i,j] to 0 if score[i] < 500.

- Mark as New
- Bookmark
- Subscribe
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

Thanks again 🙂

Registration is open! SAS is returning to Vegas for an AI and analytics experience like no other! Whether you're an executive, manager, end user or SAS partner, SAS Innovate is designed for everyone on your team. Register for just $495 by 12/31/2023.

**If you are interested in speaking, there is still time to submit a session idea. More details are posted on the website. **

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.