Operations Research topics: SAS/OR,
SAS Optimization, and SAS Simulation Studio

Reading multidimensional sets into proc optmodel

Accepted Solution Solved
Reply
Occasional Contributor
Posts: 5
Accepted Solution

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};

read data Company_Data into Customers=[customer];

/*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.

Thanks for the reply!

View solution in original post


All Replies
Super Contributor
Posts: 339

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.

Thanks for the reply!

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: 448

    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.

    Need further help from the community? Please ask a new question.

    Discussion stats
    • 5 replies
    • 384 views
    • 6 likes
    • 3 in conversation