数学建模-托盘最优化摆放解法(大学时期留下的算法)

曾记否,忘了>_<!

概述:

大二暑假,在家无聊,给一个“火急火燎”的同学写的东西。一个数学建模选拔赛的题目,利用托盘的尺寸和货物的尺寸计算出货物的最优摆放方法。给出的解法是一个博士的论文(刚好是我们学校学报上的文章)。看了一天的论文,半夜灵感爆发写出来的,最后又调整了一版。

题目:

托盘装载问题

随着我国经济的发展,物资流动日益频繁,以散装、人工搬运为主的传统运输存储方式已远远不能现代物流的需要,托盘已成为衡量一个国物流效率水平的重要标志之一。中国作为世界制造业中心,托盘市场潜力巨大,但是根据中国物流与采购联合会托盘专业委员会于2009年发布的《第二次全国托盘现状研究报告》,我国目前拥有的托盘总量仅为1.9亿至2.2亿,而美国现拥有托盘总量约为20亿、日本7亿、欧盟30亿。可以预计今后我国托盘的总量将会以惊人的速度增长,物流托盘应用前景广阔,根据德国人Janer/Graefentein的设计法则,托盘面积的利用率增加5%,其包装成本约降低10%,因此研究如何在一个托盘中正交且不重叠地放置数目最多同尺寸的长方体箱子,即装盘装载问题(Pallet loading problem,PLP),对降低物流运输成本,提高托盘的使用效率具有重要的现实意义。

请查阅我国使用的托盘规格标准(4种),解答如下问题:

1200mm×l000mml200mm×800mm1140mm×l140mm1219mm×l016mm4个托盘规格。

1. 若某箱子的长为86cm、宽为34cm,将其放在长、宽分别为1200cm、1000cm的托盘上,怎样放置箱子(包括个数、图谱),才能使托盘面积的利用率最大?

2. 附表列出了某大型企业用于包装产品的各种箱子的规格尺寸,建立模型并求出分别将这些箱子放到长、宽分别为1200cm、1000cm的托盘上使其表面利用率达到最大的放置箱子个数及方式?

3. 探讨建立一般模型,以此求出将任意规格的箱子放到某一规格的托盘上使其利用率达到最大的装箱方式?

附表:某企业生产纸箱的规格尺寸(单位:cm)

序号

序号

1

310

222

31

185

94

2

319

275

32

113

57

3

326

190

33

188

94

4

322

193

34

214

106

5

352

197

35

190

93

6

251

190

36

384

186

7

277

237

37

393

189

8

551

362

38

220

105

9

309

231

39

183

86

10

319

276

40

148

69

11

548

361

41

148

69

12

330

195

42

293

134

13

327

295

43

223

101

14

320

314

44

223

100

15

308

224

45

313

140

16

284

264

46

197

87

17

364

251

47

289

127

18

341

251

48

162

70

19

305

222

49

155

67

20

357

250

50

275

118

21

273

261

51

124

53

22

279

170

52

237

100

23

319

207

53

371

155

24

269

181

54

178

74

25

534

417

55

335

137

26

343

273

56

213

87

27

311

253

57

186

75

28

355

253

58

375

150

29

397

269

59

289

115

30

442

290

60

288

113

 

算法引用的论文:

C语言简单的算法实现:

#include<stdio.h>

//#include<stdlib.h>
#include<math.h>


void main()
{
float x,y,x1,y1,x2,y2;//这些参量用于调试,后期可能无用
int i,j,k=0;
int NLl=0,NLw=0,NWl=0,NWw=0;
float L,W,L1,W1,L2,W2;
float l,w;
float min1,min2,t,a1,b1,a2,b2;
int DH,DV;
float s1;
int sum,a3,b3,sum1,a4,b4;
int Dd;//干涉时减少箱子的个数
printf("请输入托盘的长宽\n");
scanf("%f %f",&L,&W);
printf("请输入货物的长宽\n");
scanf("%f %f",&l,&w);
loop1: if(L>l&&W>w)//判断是否能装上平台,对应算法一第1步
{
        k++;
a1=L/l;
b1=L/w;
min1=L;
for(i=0;i<=a1;i++)//求NLl类,对应算法一第2步
{
for(j=0;j<=b1;j++)
{
t=L-i*l-j*w;
if(min1>t&&t>=0)
{
min1=t,NLl=i,NLw=j;
}
}
}


printf("第%d次环绕结果,NLl=%d,NLw=%d,min1=%f\n",k,NLl,NLw,min1);
a2=W/l;
b2=W/w;
min2=W;
for(i=0;i<=a2;i++)//求NWl类,对应算法一第3步
{
for(j=0;j<=b2;j++)
{
t=W-i*l-j*w;
if(min2>t&&t>=0)
{
min2=t,NWl=i,NWw=j;
}
}
}
printf("第%d次环绕结果,NWl=%d,NWw=%d,min2=%f\n",k,NWl,NWw,min2);
if(NLl*NLw*NWl*NWw!=0)//&&(L-NLl*l*2)*(W-NWl*l*2)>0
printf("第%d次环绕堆放了%d个箱子\n",k,2*(NLl*NWw+NLw*NWl));
L1=abs(L-NLl*l*2);
W1=abs(W-NWl*l*2);
printf("L1=%f,W1=%f\n",L1,W1);
if(NLl*NLw*NWl*NWw==0)//判断以便分类算法,对应算法一第4步
{
if(NLl==0&&NWw==0)
{
a3=(int)(L/w);
b3=(int)(W/l);
sum=a3*b3;
printf("该区域采用图8a的排列方法,能容纳%d个\n",sum);


}


//调用算法三,这里会很长,还没来得及看
if(NLw==0&&NWl==0)
{
a3=(int)(L/l);
b3=(int)(W/w);
sum=a3*b3;
printf("该区域采用图8b的排列方法,能容纳%d个\n",sum);


}
if(NLw==0&&NWw==0)
{
a3=(int)(L/w);
b3=(int)(W/l);
sum=a3*b3;
a4=(int)(L/l);
b4=(int)(W/w);
sum1=a3*b3;
if(sum>sum1)
{
printf("该区域采用图8a的排列方法,能容纳%d个\n",sum);


}
else
{
printf("该区域采用图8b的排列方法,能容纳%d个\n",sum1);


}


}
if(NLl==0&&NWl==0)
{
a3=(int)(L/w);
b3=(int)(W/l);
sum=a3*b3;
a4=(int)(L/l);
b4=(int)(W/w);
sum1=a4*b4;
printf("sum=%d,sum1=%d\n",sum,sum1);
if(sum>sum1)
{
printf("该区域采用图8c的排列方法,能容纳%d个\n",sum);
L1=L;
W1=W-b3*l;
if(L1>W1)
{
L=L1;
W=W1;
}
else
{
L=W1;
W=L1;
}
goto loop1;
}
else
{
printf("该区域采用图8d的排列方法,能容纳%d个\n",sum1);
L1=L-a4*l;
W1=W;
if(L1>W1)
{
L=L1;
W=W1;
}
else
{
L=W1;
W=L1;
}
printf("L1=%f,W1=%f\n",L1,W1);
printf("a4=%d\n",a4);
goto loop1;


}


}
if(NLl==0&&(NLw*NWl*NWw))
{
a3=(int)(L/l);
sum=NLw*NWl+NWw*a3;
printf("该区域采用图8e的排列方法,能容纳%d个\n",sum);
L1= L-(int)(L/l)*l;
W1=W-NWl*l;
if(L1>W1)
{
L=L1;
W=W1;
}
else
{
L=W1;
W=L1;
}
goto loop1;
}
if(NLw==0&&(NLl*NWl*NWw))
{
//a3=(int)(L/l);
b3=(int)(L/w);
sum=NWw*NLl+b3*NWl;
printf("该区域采用图8f的排列方法,能容纳%d个\n",sum);


}
if(NWl==0&&(NLl*NLw*NWw))
{
b3=(int)(W/l);
sum=NWw*NLl+NLw*b3;
L1=W-NLl*l;
W1=W-(int)(W/l)*l;
printf("该区域采用图8g的排列方法,能容纳%d个\n",sum);
if(L1>W1)
{
L=L1;
W=W1;
}
else
{
L=W1;
W=L1;
}
//L=L1;
//W=W1;
goto loop1;
}
if(NWw==0&&(NLl*NLw*NWl))
{
b3=(int)(W/w);
sum=NLw*NWl+NLl*b3;
printf("该区域采用图8h的排列方法,能容纳%d个\n",sum);
}
}
else//对应算法一第5步
{
s1=(L-NLl*l*2)*(W-NWl*l*2);
// x=L-NLl*l*2;
// y=W-NWl*l*2;
// printf("x=%f,y=%f\n",x,y);
// printf("s1=%f\n",s1);
if(s1>0) 
{
L=L1,W=W1;
//x1=NLl*l;
//x2=NLw*w;
//y1=NWl*l;
//y2=NWw*w;
//printf("x1=%f,x2=%f,y1=%f,y2=%f\n",x1,x2,y1,y2);
goto loop1;//使用goto语句跳转到算法一的第1步
}
else//调用算法二对应算法一的第6步,产生干涉用算法二调整
{
//x1=NLl*l;
//x2=NLw*w;
//y1=NWl*l;
//y2=NWw*w;
//printf("x1=%f,x2=%f,y1=%f,y2=%f\n",x1,x2,y1,y2);
if(NLl*l<NLw*w&&NWl*l>NWw*w)//A区发生干涉
{ 
DH =(int)(W1/l-0.1)+1;
DV= (int)(L1/w-0.1)+1;
Dd=DH*DV;
//printf("DH=%d,DV=%d\n",DH,DV);
printf("因为A区发生干涉,因减掉%d行,%d列,共%d个\n",DH,DV,Dd);
L2=DV*w;
W2=DH*l-W1;
printf("L2=%f,W2=%f\n",L2,W2);
if(L2>W2)
{
L=L2;
W=W2;
}
else
{
L=W2;
W=L2;
}
goto loop1;


}
if(NLl*l>NLw*w&&NWl*l<NWw*w)//B区发生干涉
{
DH =(int)(W1/w-0.1)+1;
DV= (int)(L1/l-0.1)+1;
Dd=DH*DV;
//printf("DH=%d,/V=%d\n",DH,DV);
printf("因为B区发生干涉,因减掉%d行,%d列,共%d个\n",DH,DV,Dd);
L2=DV*l-L1;
W2=DH*w;
printf("L2=%f,W2=%f\n",L2,W2);
if(L2>W2)
{
L=L2;
W=W2;
}
else
{
L=W2;
W=L2;
}
goto loop1;
}
//goto loop1;

}
}

}


}//haha制作者代码00110111101000001111011011111001001011

 

 

 

 

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值