【问题标题】:proc optmodel syntax for multiple constraints用于多个约束的 proc optmodel 语法
【发布时间】:2016-01-08 07:50:49
【问题描述】:

从昨天开始,我一直在努力解决这个问题,并且已经阅读了大量关于 stackoverflow 的材料和一些答案。 我还创建了一个基本代码,并粘贴在下面。

背景

我们有药物的单位数据,这些数据可以组合成一个组合,称为方案。例如,drug1+drug2 为方案 1,drug1+drug2+drug3 为方案 2,drug1+drug2+drug4 为方案 3。 我们的最终目标是找出接受治疗方案的患者人数。这只能通过找出每种方案对市场的贡献百分比(称为患者份额)来实现(由于方案中的多种用途,我们无法直接从单位计算它)。

基本上

units = patientshare * dosing * compliance * duration of therapy * total patients

我们知道治疗的单位、剂量和持续时间 患者总数、依从性和患者份额将是有界变量。

我的问题是变量和约束处于不同的级别。

  • 单位处于药品级别(和月份);

  • 剂量处于药物水平;

  • 合规性在药物层面;

  • 治疗持续时间处于方案水平;

  • 患者份额处于方案级别

这是我的代码,如果有人能告诉我哪里出错(在我怀疑的数组中),我将不胜感激。

   PROC OPTMODEL;


   SET <STRING> DRUG;
   SET <STRING> REGIMEN;
   SET <STRING> MONTH;

   NUMBER DOSING{DRUG};
   READ DATA DRUG_DATA INTO DRUG=[DRUG] DOSING;
   /*PRINT DOSING;*/

   NUMBER COMPLIANCE{DRUG};
   READ DATA DRUG_DATA INTO DRUG=[DRUG] COMPLIANCE;
   /*PRINT COMPLIANCE;*/

   NUMBER DOT{drug, regimen};
   READ DATA REGIMEN INTO drug=[drug] 
   {R in regimen}< DOT [drug, R]=col(R)>;
   PRINT DOT;

   NUMBER UNITS{MONTH, DRUG};
   READ DATA DATASET INTO MONTH=[MONTH]
   {D IN DRUG}< UNITS[MONTH, D]=COL(D)>;
   /*PRINT UNITS;*/

     NUMBER RATIO{MONTH};
    READ DATA RATIO_1 INTO MONTH=[MONTH] RATIO;
   /*PRINT RATIO;*/

   /*DEFINE THE PARAMETERS*/

   var ps {MONTH,DRUG} init 0.1 >=0 <=1,
   annualpatients init 7000 <=7700 >=6300, 
  compliance init 0.1 >=0.3 <=0.8,
    DOSING[RIB] INIT 5 >=6 <=4;

   /*SET THE OBJECTIVE*/
    min sse = sum{M IN MONTH}( (units[M,D in drug]-(ps[M,R IN     REGIMEN]*annualpatients*ratio[M]*dosing[D]*compliance[D]*dot[R]*7 ))**2 );


   /*SET THE CONSTRAINTS*/
   constraint  MONTHLY_patient_share {M IN MONTH}:  sum{r is regimen}(ps[R IN REGIMEN])=1;
   constraint  total_patients sum{M in months, r in regimen} : ps[m,r in regimen]*annualpatients*ratio[m]=annual_patients;

 expand;
 solve with nlpc;
 quit;

这是日志:

       2824  PROC OPTMODEL;
       2825
2826  /*DEFINE THE DATA LEVELS (SETS) OF DRUGS, MONTH AND REGIMEN*/
2827
2828  SET <STRING> DRUG;
2829  SET <STRING> REGIMEN;
2830  SET <STRING> MONTH;
2831
2832  NUMBER DOSING{DRUG};
2833  READ DATA DRUG_DATA INTO DRUG=[DRUG] DOSING;
NOTE: There were 4 observations read from the data set WORK.DRUG_DATA.
2834  /*PRINT DOSING;*/
2835
2836  /*NUMBER COMPLIANCE{DRUG};*/
2837  /*READ DATA DRUG_DATA INTO DRUG=[DRUG] COMPLIANCE;*/
2838  /*PRINT COMPLIANCE;*/
2839
2840  NUMBER DOT{drug, regimen};
2841  READ DATA REGIMEN INTO drug=[drug]
2842  {R in regimen}< DOT [drug, R]=col(R)>;
ERROR: The symbol 'REGIMEN' has no value at line 2842 column 7.
2843  PRINT DOT;
ERROR: The symbol 'REGIMEN' has no value at line 2840 column 18.
2844
2845  NUMBER UNITS{MONTH, DRUG};
2846  READ DATA DATASET INTO MONTH=[MONTH]
2847  {D IN DRUG}< UNITS[MONTH, D]=COL(D)>;
NOTE: There were 12 observations read from the data set WORK.DATASET.
2848  /*PRINT UNITS;*/
2849
2850  NUMBER RATIO{MONTH};
2851  READ DATA RATIO_1 INTO MONTH=[MONTH] RATIO;
NOTE: There were 12 observations read from the data set WORK.RATIO_1.
2852  /*PRINT RATIO;*/
2853
2854  /*DEFINE THE PARAMETERS*/
2855
2856  var ps {MONTH,DRUG} init 0.1 >=0 <=1,
2857      annualpatients init 7000 <=7700 >=6300,
2858      compliance init 0.1 >=0.3 <=0.8,
2859      DOSING[RIB] INIT 5 >=6 <=4;
                -
                22
                200
          ------
          528
ERROR 22-322: Syntax error, expecting one of the following: ;, ',', <=, >=, BINARY, INIT,
              INTEGER, {.

ERROR 200-322: The symbol is not recognized and will be ignored.

ERROR 528-782: The name 'DOSING' is already declared.

2860
2861  /*SET THE OBJECTIVE*/
2862  min sse = sum{M IN MONTH}( (units[M,D in drug]-(ps[M,R IN
                                          -        -         --        -
-
-
-
                                          537      651       631       651
537
537
648
ERROR 537-782: The symbol 'D' is unknown.

ERROR 651-782: Subscript 2 must be a string, found a number.

ERROR 648-782: The subscript count does not match array 'DOT', 1 NE 2.

                                            --
-
                                            631
647
ERROR 631-782: The operand types for 'IN' are mismatched, found a number and a set<string>.

ERROR 647-782: The name 'compliance' must be an array.

2862! min sse = sum{M IN MONTH}( (units[M,D in drug]-(ps[M,R IN
                                                           -
-
-
                                                           537
651
537
2862! REGIMEN]*annualpatients*ratio[M]*dosing[D]*compliance[D]*dot[R]*7 ))**2 );
ERROR 537-782: The symbol 'R' is unknown.

ERROR 651-782: Subscript 1 must be a string, found a number.

2863
2864
2865  /*SET THE CONSTRAINTS*/
2866  constraint  MONTHLY_patient_share {M IN MONTH}:  sum{r in regimen}(ps[R IN REGIMEN])=1;
                                                                                        -
                                                                                        648
ERROR 648-782: The subscript count does not match array 'ps', 1 NE 2.

2867  constraint  total_patients sum{M in months, r in regimen} : ps[m,r in
                                 ---
                                 22
                                 76
2867! regimen]*annualpatients*ratio[m]=annual_patients;
ERROR 22-322: Syntax error, expecting one of the following: !!, (, *, **, +, -, .., /, :, <=, <>,
              =, ><, >=, BY, CROSS, DIFF, ELSE, INTER, SYMDIFF, TO, UNION, [, ^, {, ||.

ERROR 76-322: Syntax error, statement will be ignored.

2868
2869       expand;
NOTE: Previous errors might cause the problem to be resolved incorrectly.
ERROR: The constraint 'MONTHLY_patient_share' has an incomplete declaration.
NOTE: The problem has 50 variables (0 free, 0 fixed).
NOTE: The problem has 0 linear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: The problem has 0 nonlinear constraints (0 LE, 0 EQ, 0 GE, 0 range).
NOTE: Unable to create problem instance due to previous errors.
2870       solve with nlpc;
ERROR: No objective has been specified at line 2870 column 6.
2871       quit;
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE OPTMODEL used (Total process time):
      real time           0.07 seconds
      cpu time            0.07 seconds

【问题讨论】:

  • 您可以发布您遇到的错误吗?它会给我们一个更容易开始寻找的地方。
  • @StuSztukowski,嗨,感谢您的调查。我实际上已经在代码方面取得了一些进展,这样我就可以在没有任何错误的情况下运行它,但我不认为它正在“运行”,因为 proc optmodel 在相同的练习中继续运行(超过 10 分钟) excel用了不到3分钟。我在上面添加了新代码
  • 那么你已经取得了很好的进展!我可以向您保证 optmodel 确实在运行,但是在您的约束或目标函数中存在错误指定的内容。当optmodel 需要很长时间才能运行时,通常意味着它每次迭代都要进行大量计算。这可能来自一个极其复杂的问题,或者某些东西没有被正确地总结。通常是后者。在您的情况下,我会检查以确保您的目标函数指定正确。当你点击停止时,检查日志。它会给你它做了多少次迭代。这也有帮助。
  • 我现在已经添加了编辑后的代码(纠正了一个逻辑错误)并且它抛出了错误!
  • 嗨@DeepthiPullarkat,感谢您将答案标记为正确,但如果您也“回滚”该问题会很有帮助。否则答案并不正确。要回滚版本,您可以单击问题下方的“编辑”,然后在标有“修订”的组合框中查看修订。不要忘记将您当前的问题复制为新问题(如果该问题仍未解决)。

标签: sas proc


【解决方案1】:

第一个错误(在日志第 2842 行)发生是因为 OPTMODEL 在您引用它时没有设置 REGIMEN 的数据。

我看不到您的数据集,但您似乎有一个 DRUG-by-REGIMEN 矩阵。 因此,在使用它读取列之前,您需要告诉 OPTMODEL REGIMEN 的列表。以下是将列名读入 OPTMODEL 的两种有效方法:

/* a simple example matrix with numbers and their squares */
data m_by_n (drop=i);
    do i = 1 to 3;
        n = i;
        n_square = i * i;
        output;
    end;
run;

/* get the variable names in the `name` column, plus other information */
proc contents data=m_by_n out=contents_of_m_by_n; quit;

proc optmodel;
    set      ROWS;
    set<str> COLS;
    num val{ROWS,COLS};

    /* use the output from PROC CONTENTS */
    read data contents_of_m_by_n  into COLS=[name];
    read data m_by_n              into ROWS=[_N_] 
        { j in COLS }< val[_N_,j] = col( j ) >; 
    put val[*]=;

    /* Or, all within OPTMODEL */
    num dsid init open('m_by_n');
    set COLS2 = setof{i in 1 .. attrn(dsid,'nvars')} varname(dsid,i);
    read data m_by_n              into ROWS=[_N_] 
        { j in COLS2 }< val[_N_,j] = col( j ) >; 
    put val[*]=;
quit;

【讨论】:

  • 感谢您指出我哪里出错了!我已经粘贴了上面的新代码,它在我知道正确读取的数据集中抛出了一个错误。
  • 我很高兴它有帮助。我看到你是新来的。以下是您获得更好答案的方法:如果您能够根据自己的需要调整上面的 sn-p,那么您应该将此答案标记为正确,以便其他用户可以根据错误消息中的关键字搜索找到答案,并且输入了一个带有下一个错误的新问题。现在这个答案对这个问题毫无意义,只会让其他读者感到困惑。
猜你喜欢
  • 2015-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-22
  • 2021-04-13
相关资源
最近更新 更多