SAS Proc Optmodel语法和策略

时间:2014-12-10 16:20:20

标签: optimization sas

我有一个如下所示的数据集(SAS 9.4):

data opt_test;
        input ID GRP $ x1 MIN MAX y z;
cards;
2 F 10 9 11 1.5 100
3 F 10 9 11 1.2 50
4 F 11 9 11 .9 20
8 G 5 4 6 1.2 300
9 G 6 4 6 .9 200
;
run;

我想创建一个新变量x2,它基于x1,x2,y和z最大化函数。

我有两个主要问题:

  1. 我的proc optmodel上的语法有一些我无法解决的错误“下标1可能不是一个集合”,约束声明不完整“。更新:我想出了这部分。

  2. 我需要x2的值对于同一GRP的所有成员都是相同的。因此,id 2,3,4将具有相同的x2。 ID 8和9具有相同的x2。

  3. 以下是我的尝试。这最终将能够与不同数量的ID的不同GRP一起运行。

    提前感谢您的任何帮助。

    proc optmodel;
    
    set<num> ID;
    
    var x2{ID} >= 0;
    string GRP{ID};
    number x1{ID}; 
    number MIN{ID};
    number MAX{ID}; 
    number y{ID}; 
    number z{ID}; 
    
    
    
    
    max sales=sum{i in ID}(x2[i])*(1-(x2[i]-x1[i])*y[i]/x1[i])*z[i];
    
    con floor_METRIC1{i in ID}: x2[i]>=MIN[i];
    con ceiling_METRIC1{i in ID}: x2[i]<=MAX[i];
    
    read data opt_test into
            ID=[ID]
            GRP
            x1 
            MIN 
            MAX 
            y 
            z 
            ;
    
    solve;
    
    print x2;
    quit;
    

1 个答案:

答案 0 :(得分:1)

如果您希望x2的值对于同一组中的所有ID都相同,那么每个组只需要一个变量x2。要跟踪哪些组在哪个组中,您可以使用由组索引的集合数组:

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

当您使用=(而不是init)时,您为OPTMODEL提供了以后不需要更新的功能。如果您更改任何GRP或ID数据,optmodel将根据需要重新计算GRPS和IDperGRP。

现在,您可以使用GRPS集和IDperGRP数组来重写您的目标,以更贴近您的业务规则:

max sales = sum{gi in GRPS} sum{i in IDperGRP[gi]} 
            (x2[gi]) * (1-(x2[gi]-x1[i])*y[i]/x1[i]) * z[i];

以这种方式编写表达式使得(至少对我来说)只要x1yz是常量,就可以进一步简化表达式。

添加新集还可以让我更清楚(至少对我来说)floor_METRIC1ceiling_METRIC1的界限可以合并来收紧x2的域。由于MINMAX是常量,因此您可以通过将>=<=子句添加到x2的声明中,将约束移动到直接变量边界。由于x2现在取决于MINMAX,因此您必须在x2之前声明这些内容。恕我直言,让你的意图更清晰:

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