Generate an array of random numbers

Dear Friends,
I have defined set W and parameter Coef(W) as follows:

Set W /1*10/;
Parameter Coef(W);

I would like to randomly assign binary values to Coef(W); where about %A of elements in W get 1, and %(100-A) of them get 0. For instance, if A is equal to 70, therefore, Coef(W) could be one of the following arrays:

[1 1 0 1 1 0 1 1 0 1]
or
[0 1 1 1 0 0 1 1 1 1]
or
...

Can anyone please help me?

Kind regards,
Amirhossein

Hi, this is a good challenged! I think this can work.

*reset the seed for the random number generator.
execseed = 1 + gmillisec(jnow);

Set W /1*10/
select(W);
alias(W,Wp);
select(W)=NO;

Parameter Coef(W)
          p
          A /70/
;
loop(W$(ord(w) le floor(A*card(W)/100)),
p = uniformInt(1,card(W));
while( sum(Wp$(ord(Wp) eq p),1) eq sum(Wp$(ord(Wp) eq p and select(Wp)),1),
p = uniformInt(1,card(W));
);
select(Wp)$(ord(Wp) eq p) = yes;
Coef(Wp)$(ord(Wp) eq p) = 1;
);

Coef(Wp)$(not select(Wp)) = 0;


display Coef;

Bye!

This does what you want. Setting the seed for the random number generator is not required, but it is useful to get different results for different runs.

Set W /1*10/;
Parameter Coef(W);
scalar a / 0.7 /;
* set the seed in some random way, based on the time
execseed = gmillisec(jnow);
coef(w) = [uniform(0,1) < a];
display coef;

Hi dirkse, i like your compact implementation.
I tested your code but sometimes I got less than seven items with a value of 1 and sometimes more.
i’m right?

You are right. Unfortunately, the compact method of Mr. dirkse does not always work properly. The suggested method by Mr. Manassaldi works perfectly. Thanks.

It seems we need to clarify what the original poster intended. If the intent was to draw a number of samples from a {0,1} distribution, then you would expect to get different numbers of 1s when using different random number seeds. But perhaps the intent was to just permute a given number of 1s. In that case, the problem could be stated more clearly, without using percentages. For example, how would you get 70% of 11 items? If what you want is to randomly set k members of a parameter to 1, you can do this with the shuffle option:

https://www.gams.com/latest/docs/UG_OptionStatement.html?search=shuffle

set i /1*10/;
parameter c(i);
scalar k 'number of 1s in c' / 4 /;
c(i)$[ord(i) <= k] = 1;
* set the seed in some random way, based on the time
execseed = gmillisec(jnow);
option shuffle = c;
display c;

I did not know the shuffle option. Thanks for sharing dirkse!