钢管长度定制问题:
假设实际生产需要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,代码还有待优化。