Reading multidimensional sets into proc optmodel

Solved
Occasional Contributor
Posts: 5

Reading multidimensional sets into proc optmodel

Hi fellow SAS-users!

After much frustration and a lot of reading up on the proc optmodel and examples I turn to you.

Essentially I am trying, by using sets, to read in some data which varies in the number of elements in several dimension. A simplified example of what I want would is:

data Company_Data;

input Customer Bill;

datalines;

cust1 B1

cust1 B2

cust1 B3

cust2 B4

cust3 B5

;

proc optmodel;

set<string> Customers init {};

set<string> Bills{c in Customers};

/*Magic to get Bills read into the model */

?

?

?

/*What I want*/

Customers={'cust1','cust2','cust3'};

Bills['cust1'] = {'B1', 'B2', 'B3'};

Bills['cust2'] = {'B4'};

Bills['cust3'] = {'B5'};

/* End of model */

I have tried looking into different constructions of the read into as well as looping over the members of Bills, but unable to get the right data into the model. This feels like a thing that should be fairly easy. Alas I just cannot get it right.

Any thoughts?

Accepted Solutions
Solution
‎07-14-2015 08:59 AM
Occasional Contributor
Posts: 5

Re: Reading multidimensional sets into proc optmodel

The example I showed was just part of bigger program and the parts in question is used to generated sets which I iterate over.

Basically what I am doing is defing the set I and J where J(i \in I).

I will look into if I can use the idea of mapping everything into a set of several string (would be something like set<string,string,string, string> in my case) and then use SetOf to create the indices after reading the data.

All Replies
Super Contributor
Posts: 346

Re: Reading multidimensional sets into proc optmodel

Shouldn't you have values to read in for proc optmodel? Anyway, maybe this code-snippet is helpful, even though I'm pretty sure, it's not what you are trying to (eventually!) accomplish. :-)

data Company_Data;
input Customer $Bill$ Value;
datalines;
cust1 B1 1
cust1 B2 2
cust1 B3 3
cust2 B4 4
cust3 B5 5
;

Proc Optmodel;
Set <Str,Str> c_b;
Num Comp_Data{c_b};
Set Customer =SetOf{<c,b> in c_b} c;
Set Bill =SetOf{<c,b> in c_b} b;
Read Data Company_Data into c_b=[Customer Bill] Comp_Data=Value;

Print Comp_Data;

Run;

Solution
‎07-14-2015 08:59 AM
Occasional Contributor
Posts: 5

Re: Reading multidimensional sets into proc optmodel

The example I showed was just part of bigger program and the parts in question is used to generated sets which I iterate over.

Basically what I am doing is defing the set I and J where J(i \in I).

I will look into if I can use the idea of mapping everything into a set of several string (would be something like set<string,string,string, string> in my case) and then use SetOf to create the indices after reading the data.

Occasional Contributor
Posts: 5

Re: Reading multidimensional sets into proc optmodel

Got it!

One can use the setof function to extrapolate the data. The drawback is that one has to read all the data into the model, but for my reasonably small problems this will be no problem at all.

The following code does what I want.

data Company_Data;

input Customer $Bill$;

datalines;

cust1 B1

cust1 B2

cust1 B3

cust2 B4

cust3 B5

;

proc optmodel;

set<string> Customers init {};

set<string> Bills{c in Customers};

set<string, string> AllData;

read data Company_Data into AllData=[customer Bill];

/*This is what I want */

Customers = (setof{<i,j> in AllData} i);

for {c in Customers} Bills = (setof{<i,b> in AllData: i=c} b);

put Customers;

put Bills

• ;
• quit;

SAS Employee
Posts: 538

Re: Reading multidimensional sets into proc optmodel

Glad you got it working.  Below is an alternative approach that passes through the data only once (instead of once per customer) after reading it.  For large data, you might see a performance improvement.

proc optmodel;

set<string> Customers init {};

set<string> Bills{c in Customers} init {};

set<string, string> AllData;

read data Company_Data into AllData=[customer Bill];

/*This is what I want */

for {<i,j> in AllData} do;

Customers = Customers union {i};

Bills = Bills union {j};

end;

put Customers;

put Bills

• ;
• quit;

Occasional Contributor
Posts: 5

Re: Reading multidimensional sets into proc optmodel

Hi RobPratt,

Your approach surely seem to be more efficient! I will try it out for my final implementation.

Thanks!

🔒 This topic is solved and locked.