logo
down
shadow

Proc Optmodel SAS Maintaining Defined Separation within Group


Proc Optmodel SAS Maintaining Defined Separation within Group

By : user2954450
Date : November 22 2020, 01:01 AM
wish help you to fix your issue If I understand this correctly, you need set the non-team leads NEW_XXX variable in an equality constraint. That leaves only the team lead NEW_XXX variables free for the optimization.
Let me know if this is what you are trying to accomplish.
code :
proc optmodel;

*set variables and inputs;
set<string> NAME;
string TEAM{NAME};
number LEAD{NAME};
number GRADE{NAME}; 
number XXX{NAME};
number MIN{NAME};
number MAX{NAME}; 
number YYY{NAME}; 
number RATE{NAME}; 


*read data into procedure;
read data have into
    NAME=[NAME] 
    TEAM
    LEAD
    GRADE
    XXX
    MIN
    MAX
    YYY
    RATE;

set TEAMS = setof{i in NAME} TEAM[i];
set NAMEperTEAM{gi in TEAMS} = {i in NAME: TEAM[i] = gi};

/*Helper array that gives me the team leader for each team*/
str LEADS{TEAMS};
for {i in NAME: LEAD[i] = 1} do;
    LEADS[TEAM[i]] = i;
end;

var NEW_XXX{i in NAME} init XXX[i] >=MIN[i]<=MAX[i];


*state function to optimize;
max  metric=sum{gi in TEAMS}(
        sum{i in NAMEperTEAM[gi]} (
            (NEW_XXX[i])*(1-(NEW_XXX[i]-XXX[i])*RATE[i]/XXX[i])*YYY[i]
        ) 
    );

/*Constrain the non-lead members*/
con NonLeads{i in NAME: LEAD[i] = 0}: NEW_XXX[i] = (1 + (GRADE[i] - GRADE[LEADS[TEAM[i]]]) * 0.1) * NEW_XXX[LEADS[TEAM[i]]] ;

expand;
solve;

*write output dataset;
create data results 
    from [NAME]={NAME} 
            TEAM 
            LEAD
            GRADE
            XXX
            NEW_XXX
            MIN 
            MAX 
            RATE 
            YYY;

*write results to window;
print new_xxx metric;

quit;


Share : facebook icon twitter icon
Not Equals Constraint in PROC OPTMODEL

Not Equals Constraint in PROC OPTMODEL


By : user2370351
Date : March 29 2020, 07:55 AM
should help you out See below for a linear reformulation. However, you may not need it. In SAS 9.4m2 (SAS/OR 13.2), your expression works as written. You just need to invoke the (experimental) CLP solver:
code :
proc optmodel;
/* In SAS/OR 13.2 you can use your code directly.
   Just invoke the experimental CLP solver */
    var x binary, y binary, z binary;
    con sum_con: x+y+z~=1;
    solve with clp / findall;
    print {i in 1 .. _NSOL_} x.sol[i] 
          {i in 1 .. _NSOL_} y.sol[i]
          {i in 1 .. _NSOL_} z.sol[i];
[1] x.SOL y.SOL z.SOL 
  1     0     0     0 
  2     0     1     1 
  3     1     0     1 
  4     1     1     0 
  5     1     1     1 
/* If solve with CLP is not available, you can linearize the disjunction: */
var IsGTZero binary; /* 1 if any variable in the expression is 1 */
con IsGTZeroBoundsExpression: 3 * IsGTZero >= x + y + z;
num atLeast init 2;
con ZeroOrAtLeast: x + y + z >= atLeast * IsGTZero;
min f=0; /* Explicit objectives are unnecessary in 13.2 */
solve;
SAS Proc Optmodel Syntax and Strategy

SAS Proc Optmodel Syntax and Strategy


By : Barnesy
Date : March 29 2020, 07:55 AM
around this issue If you want the value of x2 to be the same for all ids in the same group, then you only need one variable x2 per group. To keep track of which ids are in which group you could use an array of sets indexed by group:
code :
set<num> ID;

string GRP{ID};
set GRPS                 = setof{i in ID} GRP[i];
set IDperGRP{gi in GRPS} = {i in ID: GRP[i] = gi};
max sales = sum{gi in GRPS} sum{i in IDperGRP[gi]} 
            (x2[gi]) * (1-(x2[gi]-x1[i])*y[i]/x1[i]) * z[i];
number MIN{ID};
number MAX{ID}; 
var x2{gi in GRPS} >= max{i in IDperGRP[gi]} MIN[i] 
                   <= min{i in IDperGRP[gi]} MAX[i] 
;
Proc Optmodel Conditional Constraint SAS

Proc Optmodel Conditional Constraint SAS


By : Simond15
Date : March 29 2020, 07:55 AM
I hope this helps you . The biggest problem with the model in the question is that the indexing of the var x2 is incorrect. You could fix that by referring to the group of the ID as such:
code :
con cond_1 {i in ID}: x2[GRP[i]] >= 
        if y[i] < 1 then .95*x1[i] else 0;
con cond_2 {i in ID}: x2[GRP[i]] <= 
        if y[i]>=1 then 1.05*x1[i] else 99999999;
con Cond_1v2 {i in ID: y[i] < 1} : x2[GRP[i]] >=  .95 * x1[i]; 
con Cond_2v2 {i in ID: Y[i] >= 1}: x2[GRP[i]] <= 1.05 * x1[i];
solve with nlp / iis=on;
expand / iis;
SAS Proc Optmodel Constraint Syntax

SAS Proc Optmodel Constraint Syntax


By : user3027840
Date : March 29 2020, 07:55 AM
hop of those help? The main difficulty is that in your application, decisions are indexed by (Item,Location) pairs and Weeks, but in your code you have merged (Item,Location,Week) triplets. I rather like that use of the data step, but the result in this example is that your code is unable to refer to specific weeks and to specific pairs.
The fix that changes your code the least is to add these relationships by using defined sets and inputs that OPTMODEL can compute for you. Then you will know which triplets refer to each combination of (Item,Location) pair and week:
code :
/* This code creates a set version of the Item x Location pairs 
   that you already have as strings */ 
set ITM_LCTS = setof{ilw in ITM_LCT_WK} itm_lct[ilw];
/* For each Item x Location pair, define a set of which 
   Item x Location x Week entries refer to that Item x Location */
set ILWperIL{il in ITM_LCTS} = {ilw in ITM_LCT_WK: itm_lct[ilw] = il};
proc optmodel;

*set variables and inputs;

set<string> ITM_LCT_WK;
number ITM_NBR{ITM_LCT_WK};
string ITM_DES_TXT{ITM_LCT_WK};
string ITM_LCT{ITM_LCT_WK};
number LCT_NBR{ITM_LCT_WK};
number WEEK{ITM_LCT_WK}; 
number LY_UNITS{ITM_LCT_WK}; 
number ELAST{ITM_LCT_WK}; 
number COST{ITM_LCT_WK}; 
number PRICE{ITM_LCT_WK};
number TOTAL_INV{ITM_LCT_WK}; 

*read data into procedure;
read data opt_test_mkdown_raw into
    ITM_LCT_WK=[ITM_LCT_WK]
    ITM_NBR
    ITM_DES_TXT
    ITM_LCT
    LCT_NBR
    WEEK
    LY_UNITS
    ELAST
    COST
    PRICE
    TOTAL_INV; 

var    NEW_PRICE{i in ITM_LCT_WK} <= price[i];
impvar FRC_UNITS{i in ITM_LCT_WK} = 
       (1-(NEW_PRICE[i]-PRICE[i])*ELAST[i]/PRICE[i]) * LY_UNITS[i];

* Moved to bound
con ceiling_price {i in ITM_LCT_WK}: NEW_PRICE[i] <= PRICE[i];

con supply_last{i in ITM_LCT_WK}: FRC_UNITS[i] >= LY_UNITS[i];

/* This code creates a set version of the Item x Location pairs 
   that you already have as strings */ 
set ITM_LCTS = setof{ilw in ITM_LCT_WK} itm_lct[ilw];
/* For each Item x Location pair, define a set of which 
   Item x Location x Week entries refer to that Item x Location */
set ILWperIL{il in ITM_LCTS} = {ilw in ITM_LCT_WK: itm_lct[ilw] = il};
/* I assume that for each item and location 
   the inventory is the same for all weeks for convenience,
   i.e., that is not a coincidence */
num inventory{il in ITM_LCTS} = max{ilw in ILWperIL[il]} total_inv[ilw];
con inv_cap {il in ITM_LCTS}: 
    sum{ilw in ILWperIL[il]} Frc_Units[ilw] = inventory[il]; 

num lastWeek = max{ilw in ITM_LCT_WK} week[ilw];
/* Concatenating indexes is not the prettiest, but gets the job done here*/
con Price_down_or_same {il in ITM_LCTS, w in 2 .. lastWeek}: 
    New_Price[il || w] <= New_Price[il || w - 1];*/

*state function to optimize;
max  margin=sum{i in ITM_LCT_WK}
    (NEW_PRICE[i]-COST[i])*(1-(NEW_PRICE[i]-PRICE[i])*ELAST[i]/PRICE[i])*LY_UNITS[i];

expand;
solve;

*write output dataset;
create data results_MKD_maxmargin
    from 
    [ITM_LCT_WK]={ITM_LCT_WK} 
    ITM_NBR
    ITM_DES_TXT
    LCT_NBR
    WEEK
    LY_UNITS
    FRC_UNITS
    ELAST
    COST
    PRICE
    NEW_PRICE
    TOTAL_INV; 

*write results to window;
print 
    NEW_PRICE FRC_UNITS
    margin
;

quit;
Reading in Datasets to Proc Optmodel

Reading in Datasets to Proc Optmodel


By : ShiGuiLin
Date : March 29 2020, 07:55 AM
I wish this help you I have a dataset called zip5size that looks like this: , In proc optmodel, set is the index-set. For example:
code :
data dat; 
   input zip $ district $ volume;
datalines;
22123  springfield  1234
10001  new york      567
20001  dc           8910
20005  dc           1112
10005  new york     1314
;

proc optmodel;
  set <str> model_zips;
  set <str> model_dist;
  num vol_zips{model_zips};
  num vol_dist{model_dist};
  read data dat into model_zips=[zip] vol_zips=volume;
  read data dat into model_dist=[district] vol_dist=volume;
  print vol_zips;
  print vol_dist;
quit; 
shadow
Privacy Policy - Terms - Contact Us © ourworld-yourmove.org