简单线性规划问题SAS编程之二

钢管长度定制问题:

假设实际生产需要303mm,251mm,202mm,151mm,107mm的钢管各100根【理论上需要一根(303+251+202+151+107)*100=101400的长钢管,这样才不会多余的边角料浪费,实际上这么长的一根钢管供货商是不便于提供的】。现供货商只能提供长度相同且长度范围为1300mm至1650mm的钢管,请问需要向订货商定制多少根和长度为多少的钢管才能保证浪费最少(即边角料的总长度最小)?

引用:http://www.mysas.net/forum/viewtopic.php?f=4&t=4768&start=10   ID:tianlai888

ps:原文中的表达不够清晰,且10根算起来不过瘾,故修改。

代码:

options nomprint;

data ex;
input  _type_$ _rhs_;
cards;
ge 100
ge 100
ge 100
ge 100
ge 100
min .
upperbd .
integer .
;
run;
%macro sxl(out=out);

proc sql;
create table &out.
  (
    numm num format = 12.       label = ‘number’,
    i  num format = 12. label = ‘length’

  );
quit;

%do i = 1300 %to 1650;

data _aa (keep=c d e f g i );
   a1=int(&i./303);
   a2=int(&i./251);
   a3=int(&i./202);
   a4=int(&i./151);
   a5=int(&i./107);
   w=&i.-107;
    do c=0 to a1;
          do d=0 to a2;
              do e=0 to a3;
                  do f=0 to a4;
                     do g=0 to a5;
                        x=303*c+251*d+202*e+151*f+107*g;
                        y=&i.-x;
                         if x>w and x<=&i. then do;
                                                     i+1;
                                                     output;
                                                  end;
                      end;
                  end;
             end;
           end;
     end;
run;

proc sort data=_aa out=_aa(drop=i);
by descending i ;
run;

data _null_;
set _aa(drop=_all_) nobs=rows;
call symput(‘nobs’,rows);
stop;
run;

data _collect(drop=i);
LENGTH _VAR_ $8.;
set _aa;
i+1;
_VAR_=catt(‘COL’,i);
run;

proc transpose data=_aa out=_aa1;
run;
data _bb(drop=i);
do i =1 to &nobs.;
    a=1;
    b=100;
    c+1;
    output;
    end;
    run;
    proc transpose data=_bb out=_bb1;
    run;

data ex1(drop=_NAME_);
set _aa1 _bb1;
run;

data ex2;
merge ex1 ex ;
run;

ods listing close;
ods output solutionsummary=_p;
proc lp data=ex2  IMAXIT=500;
run;
ods _all_ close;
ods listing ;

proc sql noprint;
select CVALUE1  
   into :numm from _p;

    data _tem;
      numm=&numm.;
      i  = &i.;
    run;

    proc sql;       
      insert into
        &out.
      select
        *
      from
        _tem;
    quit;

%end;
data &out.;
   set &out.;
   length=numm*i;
   if numm ne lag(numm) then output;
   run;

proc sort data=&out. out=&out.;
   by length ;
   run;
proc print data=&out.;
run;
%mend sxl;
%sxl;

result:

Obs            numm               i    length

  1              69            1471    101499
  2              67            1515    101505
  3              65            1562    101530
  4              72            1411    101592
  5              63            1613    101619
  6              77            1320    101640
  7              75            1360    102000
  8              78            1310    102180
  9              70            1460    102200
10              68            1509    102612
11              66            1557    102762
12              73            1408    102784
13              64            1608    102912
14              76            1357    103132
15              79            1307    103253
16              71            1457    103447
17              80            1300    104000
18              74            1406    104044

从结果中看出,当定制1471mm的钢管时,浪费最少。需要定制69根,浪费101499-101400=99mm。

小结:实际程序跑了100s,理论上猜测应该少于30s,代码还有待优化。


相关博文

《简单线性规划问题SAS编程之二》上的2个想法

发表评论

电子邮件地址不会被公开。 必填项已用*标注