簡體   English   中英

Proc Optmodel條件約束SAS

[英]Proc Optmodel Conditional Constraint SAS

我很新興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;

我將在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] < - 壞!

問題中模型的最大問題是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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM