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

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

Posted 03-12-2014 08:00 AM
(3279 views)

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.

15 REPLIES 15

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

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

**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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

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
- Mute
- RSS Feed
- Permalink
- Report Inappropriate Content

I've attached PROC OPTMODEL code that uses the REIFY and GCC constraints with the CLP solver.

**SAS Innovate 2025** is scheduled for May 6-9 in Orlando, FL. Sign up to be **first to learn** about the agenda and registration!

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.