我是一个相当新的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的增加/减少。如果y <1,我不希望x2低于.95 * x1。如果y> 1,我不希望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;
答案 0 :(得分:3)
我会在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。根据你的逻辑,这将min设置为5.7(0.95 * 6)。
[5.7,5.25]中的X2 [G]&lt; -BAD!
答案 1 :(得分:2)
问题中模型的最大问题是var
x2
的索引不正确。你可以通过引用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;