【问题标题】:SAS Proc Optmodel Syntax and StrategySAS Proc Optmodel 语法和策略
【发布时间】:2014-12-10 16:20:20
【问题描述】:

我有一个如下所示的数据集(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. 我需要相同 GRP 的所有成员的 x2 值相同。因此,id 2,3,4 将具有相同的 x2。 ID 8 和 9 将具有相同的 x2。

以下是我的尝试。这最终将能够与不同数量的 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;

【问题讨论】:

    标签: optimization sas


    【解决方案1】:

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

    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 的声明中添加&gt;=&lt;= 子句来将约束移动到直接变量边界。由于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] 
    ;
    

    【讨论】:

    • 非常感谢您的帮助,Leo。这很棒。如果可以的话,还有一个问题......这如何改变我的 create data 语句的语法?我有:从 [ID]={ID} x2 GRP x1 MIN MAX y z 创建数据结果;
    • 最简单的方案是声明一个隐式变量:impvar x2byID{i in ID} = x2[GRP[i]];,然后在你的create data语句中引用隐式变量:create data results from [ID]={ID} x2=x2byID GRP x1 MIN MAX y z;
    • 感谢所有的帮助,Leo。
    猜你喜欢
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多