SAS Optimization, and SAS Simulation Studio

turn on suggestions

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

Showing results for

Find a Community

Topic Options

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

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

03-12-2014 08:00 AM

Hi, I have a **binary** variable x(b) where b ranges from 1 to 5.

Now I have a constraint which says that summation of x(b) over all b is either 0 or 3.

However all the x(b)'s with value 1 need to be together.

For example I can have the following sequences:

0 0 0 0 0

0 0 1 1 1

0 1 1 1 0

1 1 1 0 0

However I cannot have the following sequences.

1 0 1 0 1

0 1 1 0 1

Any help in formulating this constraint will be greatly appreciated.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

03-12-2014 09:42 AM

Not sure if this is what you want, but it seems to me more of a data manipulation question:

data have;

input b1-b5;

cards;

0 0 0 0 0

0 0 1 1 1

0 1 1 1 0

1 1 1 0 0

1 0 1 0 1

0 1 1 0 1

0 1 1 1 1

0 0 1 1 0

;

data want;

set have;

array b b:;

if (find(cats(of b(*)),'111') >0 and sum(of b(*)) =3) or sum(of b(*))=0;

run;

Haikuo

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to Haikuo

03-12-2014 09:47 AM

Thanks for the reply Haikuo. Sorry if I didn't make my question more clear previously: x(b) is the desired output (of the optimization model), it's not the input.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

03-12-2014 12:29 PM - edited 01-03-2018 04:17 PM

Here's a way to do it by using PROC OPTMODEL in SAS/OR:

proc optmodel;

num n = 5;

var x {1..n} binary;

var y binary;

con ZeroOrThree:

sum {j in 1..n} x[j] = 3*y;

/* exclude (1,...,0,...,1) */

con Consecutive {j1 in 1..n-2, j2 in j1+1..n-1, j3 in j2+1..n}:

x[j1] + (1 - x[j2]) + x[j3] <= 2;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

03-13-2014 05:12 AM

Rob, this looks to be a great solution when there is only **one **'0' in the middle with '1's on both sides of it. However I forgot to mention another possible case which needs to be excluded (by using the constraint). In this case, there are **multiple** '0's in the middle with '1's on both sides of it. Example: 1 0 0 1 1

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

03-13-2014 11:03 AM

For each triple (j1,j2,j3) where j1 < j2 < j3, the constraints I suggested exclude x[j1] = 1, x[j2] = 0, x[j3] = 1, even if j1, j2, and j3 are not consecutive. Your example 1 0 0 1 1 is excluded by the constraint indexed by (j1,j2,j3) = (1,2,4). (It is also excluded by a few other triples.)

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

04-17-2015 02:08 PM

I have a constraint of the following form:

x(i)/A-x(i')/B+slack(i,i')-surplus(i,i')=0 for all i,i' such that i=1 to 99, i=2 to 100 and i<i'

However, the set to which i and i' belong is a string, not a number so I can't write "i in 1..100".

Will DO loop be better for this? If yes, can you help me with the syntax?

I couldn't find syntax for "Constraint DO loop" in Google.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

04-17-2015 02:22 PM

The simplest solution, if you will manipulate the strings as numbers, and you can be sure that they will always be numbers, is to create a set of numbers mapped to the set of strings, like this example:

proc optmodel;

set S = / '1' '2' '3' /;

set SNUM = setof{si in S} input(si,best12.);

num n{si in SNUM} = si;

put n

quit;

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to LeoLopes

04-17-2015 02:26 PM

Thanks a lot. But how do I code the constraint:

x(i)/A-x(i')/B+slack(i,i')-surplus(i,i')=0 for all i,i' such that i=1 to 99, i=2 to 100 and i<i'

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

04-17-2015 02:36 PM

The simplest way to index them might be to define this set:

num n ; /* you will initialize n from data */

set PAIRS = {i in 1 .. n,j in i + 1 .. n};

Then index your variables and constraints on PAIRS, e.g.:

con ScaledDifference{<i,iPrime> in PAIRS}: X*/A + Slack[i,iPrime] - Surplus[i,iPrime] = X[iPrime]/B; *

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to LeoLopes

04-17-2015 03:55 PM

Alternatively, you can keep the string indices if you define PAIRS as:

set PAIRS = {i in ISET, iprime in ISET: i < iprime};

where ISET is the common, string-valued index set for i and iprime.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

04-18-2015 03:34 AM

data _null_; array x[5]; n=dim(x); k=-1; nsubs=2**n; do i=1 to nsubs; rc=graycode(k,of x

Xia Keshan

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to abhik_giri

01-03-2018 06:12 AM - edited 01-03-2018 06:13 AM

Remember Permutation/Combination Chapter from +2 days ?

If {for i = 1 to 5} sum x(i) = 3 and x(i)'s are binary then there will be three 1's and two 0's.

Let me reframe the problem in the following way -

In how many ways three 1's and two 0's can be arranged in permutation so that 1's always come together ? We consider three 1's as a single unit(let's say =3) and proceed with the permutation. So it would be 3! total. [For the time being, lets forget as two 0's are actually the same, so total number of permutation would be 3!/2!. Actually I could not find out this option in SAS. Please update me if anybody gets it]

```
proc plan;
factors Block=6 ordered B=3 of 3 perm;
ods output Plan=results;
run;
```

This will produce the following output-

```
Block B1 B2 B3
1 1 2 3
2 1 3 2
3 2 1 3
4 2 3 1
5 3 1 2
6 3 2 1
```

Once you replace the value of B1/B2/B3 as follows you will find few duplication in blocks.

```
data results(keep=Digit);
set results;
format Digit1 Digit2 Digit3 $5.;
if B1 in (1,2) then Digit1='0'; else Digit1 = '1-1-1';
if B2 in (1,2) then Digit2='0'; else Digit2 = '1-1-1';
if B3 in (1,2) then Digit3='0'; else Digit3 = '1-1-1';
Digit = CATX ("-", OF Digit1-Digit3);
run;
```

Results -

```
Digit
0-0-1-1-1
0-1-1-1-0
0-0-1-1-1
0-1-1-1-0
1-1-1-0-0
1-1-1-0-0
```

Dedupe it -

`proc sort data=results nodupkey; by Digit; run;`

And you get the desired results-

```
Digit
0-0-1-1-1
0-1-1-1-0
1-1-1-0-0
```

Use substr function to create 5 column from the Digit column.

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to baralamit0

01-03-2018 04:19 PM - edited 01-03-2018 06:02 PM

Here's a way to do it with the CLP solver in PROC OPTMODEL:

```
proc optmodel;
num n = 5;
var x {1..n} binary;
con ChooseThree:
sum {j in 1..n} x[j] = 3;
/* exclude (...,1,...,0,...,1,...) */
con Consecutive {j1 in 1..n-2, j2 in j1+1..n-1, j3 in j2+1..n}:
x[j1] + (1 - x[j2]) + x[j3] <= 2;
solve with clp / findallsolns;
print {s in 1.._NSOL_, j in 1..n} x[j].sol[s];
quit;
```

SAS Output

x.SOL | |||||
---|---|---|---|---|---|

1 | 2 | 3 | 4 | 5 | |

1 | 0 | 0 | 1 | 1 | 1 |

2 | 0 | 1 | 1 | 1 | 0 |

3 | 1 | 1 | 1 | 0 | 0 |

- Mark as New
- Bookmark
- Subscribe
- RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

Posted in reply to RobPratt

01-03-2018 05:57 PM