【问题标题】:Proc Optmodel Conditional Constraint SASProc Optmodel 条件约束 SAS
【发布时间】:2014-12-16 16:07:04
【问题描述】:

我对 proc optmodel 还很陌生,在整理某些语法时遇到了麻烦。

这是我的数据集。

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
1 H 21 18 22 1.2 300
7 H 20 18 22 .8 1000
;
run;

这里发生了一些事情:

GRP 中的 ID 必须具有相同的 x2,它受 MIN 和 MAX 的约束。我现在希望根据 y 的值进一步限制 x2 的增加/减少。如果 y1,我不希望 x2 超过 1.05*x1。我在网上查看并尝试了一些方法来实现这一点。这是我最近的尝试,cond_1 和 cond_2 是感兴趣的问题,因为其他一切都有效:

proc optmodel;

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

number x1{ID}; 
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] 
;
impvar x2byID{i in ID} = x2[GRP[i]];
number y{ID}; 
number z{ID}; 

read data opt_test into
        ID=[ID]
        GRP
        x1 
        MIN 
        MAX 
        y 
        z 
        ;

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

con cond_1 {i in ID}: x2[i] >= 
        if y[i]<1 then .95*x1[i] else 0;
con cond_2 {i in ID}: x2[i] <= 
        if y[i]>=1 then 1.05*x1[i] else 99999999;

solve;

create data results from [ID]={ID} x2=x2byID GRP x1 MIN MAX y z;

print x2 maximize;
quit;

【问题讨论】:

  • 是的,您不能在约束中使用条件。 y 是否严格 >=0 ?
  • 是的,y 总是大于 0。这是我在尝试形成 support.sas.com/documentation/cdl/en/ormpug/59679/HTML/default/… 语法时引用的站点之一
  • 一个问题是 x2 是由 GRPS 集(字符串)定义的,而不是 ID 集(数字)。所以 '{i in ID} x2[i]' 不会解决。
  • 另外,假设 X2 是在组上定义的,y 是在 id 上定义的,你想如何处理 y 在每个组的条件两侧的事实?您只是在寻找 X2 上最严格的约束条件吗?
  • 我不想让任何给定的 ID 超出基于其特定 y 值的约束,从而限制整个组。

标签: optimization sas


【解决方案1】:

我会在 PROC OPTMODEL 之外的数据步骤中计算全局最大值和最小值,然后设置值。像这样:

data opt_test;
set opt_test;
if y < 1 then
    min2 = .95*x1;
else
    min2 = 0;

if y>=1 then
    max2 = 1.05*x1;
else
    max2 = 9999999999;

Min_old = min;
max_old = max;

MIN = max(min,min2);
MAX = min(max,max2);
run;

但是 G 组有问题。使用 expand 来查看。

proc optmodel;

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

number x1{ID}; 
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] 
;
impvar x2byID{i in ID} = x2[GRP[i]];
number y{ID}; 
number z{ID}; 

read data opt_test into
        ID=[ID]
        GRP
        x1 
        MIN 
        MAX 
        y 
        z 
        ;

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

/*con cond_1 {i in ID}: x2[i] >= 
        if y[i]<1 then .95*x1[i] else 0;
con cond_2 {i in ID}: x2[i] <= 
        if y[i]>=1 then 1.05*x1[i] else 99999999;*/

expand;
solve;

create data results from [ID]={ID} x2=x2byID GRP x1 MIN MAX y z;

print x2 maximize;
quit;

你会看到 X2[G] 是不可行的:

Var x2[G] >= 5.7 <= 5.25

X2[G] 从 [4,6] 开始;

对于 ID=8、X=5 和 Y=1.2。根据您的逻辑,这会将最大值设置为 5.25 (5*1.2)。

现在 [4,5.25] 中的 X2[G]

对于 ID=9、X=6 和 Y=0.9。根据您的逻辑,这会将最小值设置为 5.7 (0.95*6)。

[5.7,5.25] 中的 X2[G]

【讨论】:

  • 是的。我同意。这使得在优化过程之外声明这些值更有意义。并感谢分享扩展声明。这将有助于调试。
  • 这是一个很好的解决方案,但 Leo 的回答正确地解决了上述问题。感谢您的帮助。
【解决方案2】:

问题中模型最大的问题是varx2的索引不正确。您可以通过引用 ID 组来解决此问题:

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

在任何一种情况下,由于约束 Cond2v2,问题变得不可行,正如您可以看到使用 expand(正如 @DomPazz 指出的那样),特别是 expand / iis 选项,当它打印冲突约束时可以确定它们:

solve with nlp / iis=on;
expand / iis;

【讨论】:

  • 嗯,好的。所以逻辑是正确的,但索引是错误的。这是我在 optmodel 过程中遇到的最大问题。你有什么资源可以推荐吗? SAS 文档并不是很有帮助,因为示例太少且太简单。谢谢。
  • 这是我的最佳推荐:support.sas.com/documentation/cdl/en/ormpex/67518/HTML/default/…。它通过直接用 OPTMODEL 编写的示例补充了一本备受推崇的教科书。
猜你喜欢
  • 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
相关资源
最近更新 更多