算法,請先算了再說不要想當然!!想了陣子未有好算法有點難度!

treamboy 2003-12-17 03:11:29
集裝箱裝貨物,不考慮物件的体型只考慮体积,貨物的体积只不超過40cm3,費用是10cm3----300元,15cm3----400元,40cm3-----1000元,問任一批貨物怎樣裝才是最經濟的!!!!!!!
注意事項:1.不管貨物是長方形還是正方形,只考慮他的体积,只不超過40cm3
2.最經濟的裝法
3.10立方体價值是300元,15立方体是400元,40立方体是1000元.

看這很簡單其實覺得是有難度的,我兩天一直都未找到最合理的算法.請做具體分析后再談算法,謝謝.
...全文
47 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
Linevan 2003-12-22
  • 打赏
  • 举报
回复
上面我贴的代码有点问题
现在更正一下:

#include <iostream.h>

const int max=100;

int Wei(int i);
int Worth(int i);

void main()
{
int i,j,n,k,totle,min=9999999,temp,a[max],c[max],w[max],sol[6][max+1];

//Input
cout<<"Input the amount:"<<endl;
cin>>n;

cout<<"Input "<<n<<" weighs :"<<endl;
for (i=0;i<n;i++) {a[i]=0; c[i]=0; w[i]=0;}
for (i=0;i<n;i++)
{
cin>>w[i];
if (w[i]<=10) a[i]=2;
else if (w[i]<=15) a[i]=1;
}

//Solution
c[n]=-1;
while (c[n]<0)
{
for (i=0;i<=n;i++)
for (j=0;j<6;j++) sol[j][i]=0;

for (i=0;i<n;i++) sol[c[i]][sol[c[i]][n]++]=w[i];

//从大到小冒泡排序
for (k=0;k<3;k++)
{
for (j=1;j<sol[k][n];j++)
for (i=0;i<sol[k][n]-j;i++)
if (sol[k][i]<sol[k][i+1])
{
temp=sol[k][i];
sol[k][i]=sol[k][i+1];
sol[k][i+1]=temp;
}
}

//解决子问题
for (i=0;i<3;i++)
{
for (j=0;j<sol[i][n];j++)
{
k=0;
while (sol[i+3][k]+sol[i][j]>Wei(i)) k++;
if (k==sol[i+3][n]) sol[i+3][n]++;
sol[i+3][k]+=sol[i][j];
}
}

//统计最小值
totle=0;
for (i=3;i<6;i++) totle+=sol[i][n]*Worth(i-3);
if (min>totle) min=totle;


c[0]++;
i=0;
while (c[i]>a[i]) { c[i]=0; c[++i]++; }
}
cout<<"The min is :"<<min<<endl;
}

int Wei(int i)
{
if (i==0) return (40);
else if (i==1) return (15);
else return (10);
}

int Worth(int i)
{
if (i==0) return (1000);
else if (i==1) return (400);
else return (300);
}

肯能还会有点问题,大家一起讨论啊!
ejiue 2003-12-22
  • 打赏
  • 举报
回复
楼主的这个问题解决了没有。

1、使用近似的算法,可用贪心算法。按体积贪心,或者按价格贪心。
结果并不能保证一定是最优的,但是大多数情况下是最优的。
(起码也是一个不错的解)

2、使用回溯算法,和分支界定,可以找到最优解。
实际上是一种有记忆的蛮干算法。
具体的算法,楼主还是找本数据结构的书看看。
Linevan 2003-12-20
  • 打赏
  • 举报
回复
#include <iostream.h>

const int max=10;

int Wei(int i);

void main()
{
int i,j,n,k,totle,min=9999,temp,a[max],c[max],w[max],sol[6][max+1];

//Input
cout<<"Input the amount:"<<endl;
cin>>n;

cout<<"Input "<<n<<" weighs :"<<endl;
for (i=0;i<n;i++) {a[i]=0; c[i]=0; w[i]=0;}
for (i=0;i<n;i++)
{
cin>>w[i];
if (w[i]<=10) a[i]=2;
else if (w[i]<=15) a[i]=1;
}

//Solution
c[n]=-1;
while (c[n]<0)
{
for (i=0;i<=n;i++)
for (j=0;j<6;j++) sol[j][i]=0;

for (i=0;i<n;i++) sol[c[i]][sol[c[i]][n]++]=w[i];

//从大到小冒泡排序
for (k=0;k<3;k++)
{
for (j=1;j<sol[k][n];j++)
for (i=0;i<sol[k][n]-j;i++)
if (sol[k][i]<sol[k][i+1])
{
temp=sol[k][i];
sol[k][i]=sol[k][i+1];
sol[k][i+1]=temp;
}
}

//解决子问题
for (i=0;i<3;i++)
{
for (j=0;j<sol[i][n];j++)
{
k=0;
while (sol[i+3][k]+sol[i][j]>Wei(i)) k++;
if (k==sol[i+3][n]) sol[i+3][n]++;
sol[i+3][k]+=sol[i][j];
}
}

//统计最小值
totle=0;
for (i=3;i<6;i++) totle+=sol[i][n]*Wei(i-3);
if (min>totle) min=totle;


c[0]++;
i=0;
while (c[i]>a[i]) { c[i]=0; c[++i]++; }
}
cout<<"The min is :"<<min<<endl;
}

int Wei(int i)
{
if (i==0) return (40);
else if (i==1) return (15);
else return (10);
}
Linevan 2003-12-20
  • 打赏
  • 举报
回复
先用一个数组表示要装的货,设为a[1]....a[n],初值为0;
然后将每个货与10,15,40比较一下
如果第i个货物<=10,则a[i]=2;
else <=15 则a[i]=1;
这样表示后就是说,当a[i]=0时,表示只能装进40的
1时,表示能装40或15的
2时,表示3种情况都能装!
然后可以用c[1]....c[n]来表示一个高精度的数,是a[i]进制的
c[i]即表示第i个货物选取第几个装货方案(是10,还是15,或是40的)!
然后c[1..n]=0,c[1]=-1;

{c[1]++;
i=1;
while (c[i]>a[i]) { c[i]=0; c[++i]++; }//枚举出所有情况!
然后统计c[i](i=1到n);
0表示装到40的,1表示装到15的,2表示装到10;

然后就是将货物分成了3份,分别装到40,15,10的箱子里!
问题被分成了3个等同的子问题,
就是:有m个数,要用尽量个数少的容量为q,来装这每个m个货物
(q分别等于10,15,40),m个货物就是刚才统计出的用于装进q容量的货物!

//原问题就得到简化!
解决子问题;
}
Linevan 2003-12-19
  • 打赏
  • 举报
回复
楼主你把你的算法先贴出来吧
大家讨论讨论
至于我本人是比较惭愧了,
能力有限
还未曾想到有效的算法!
treamboy 2003-12-19
  • 打赏
  • 举报
回复
////////////////////////////////////////////////////////
nkscorpion(蝎子) ( )
试试排列组合。
设10cm3-->A
15cm3-->B
40cm3-->C;
对任一批货物,依次求各种排列组合的权:
先装满A,再装满B,接着装满C; 1
先装满A,再装满C,接着装满B; 2
...
/////////////////////////////////////////////////
謝謝!
這個算法早試過,就是先裝箱后再排序算出最优值.
這個算法肯頂保證可以裝的入箱子,但請仔細想想它,如此類似的方案我也考慮過是否把所有的裝箱方法都算入,最后得出的最优方案是否真是最优?我分析后得出是否定的.看上去還可以但可能遺漏了



////////////////////////////////////////////////////////////////
①“10cm3----300元,15cm3----400元,40cm3-----1000元,” 与
“10立方体價值是300元,15立方体是400元,40立方体是1000元.”
是什么关系,10立方体是指什么哦?
②集装箱没有体积限制?
这还真不是当年那个题,当年那个叫“平板车装货问题”(前面记错了),当时的平板车有长度限制。
////////////////////////////////////////////////////////////////
1.....是什么关系,10立方体是指什么哦?
答:10cm3就是容器体积,10立方体的意思(應該是10m3),我想強調的是体积(不管是正方体還是長方体),裝入的物件也是一樣.

2.②集装箱没有体积限制?
这还真不是当年那个题,当年那个叫“平板车装货问题”(前面记错了),当时的平板车有长度限制。
答;總体积是無限,只是三個規格的容器,容器數量可以任意多,貨物是隨機給出.我想三個規格的容器是不是你所說的"集装箱体积限制"?如果是就是三個規格的的容器分別是10,15,40
//////////////////////////////////////////////////////////////////
应该是说,随机给一组货物,比如说:12cm^3,12cm^3,6cm^3
然后让求出一个方案,从上述三个装货方案中挑出几个,可以重复
可以是1个40的,或者2个15的1个10的
然后,由背包问题把这些货物装进去
比如:12+12+6全装到40的中去,需要1000元
或者,12-》15,12-》15,6-》10,需要1100元
要使的总价钱最小!
显然前一种方案好!

至于算法,还在考虑中。。。 。。。
/////////////////////////////////////////////////////////////////
其中:可以是1个40的,或者2个15的1个10的
就要求把所有方法窮舉出來,得考慮不會遺漏任一可能方案,先試試寫出這個算法,也許我走入物區了怎麼算都有遺漏的.
Linevan 2003-12-18
  • 打赏
  • 举报
回复
我先说说我对题目的看法

应该是说,随机给一组货物,比如说:12cm^3,12cm^3,6cm^3
然后让求出一个方案,从上述三个装货方案中挑出几个,可以重复
可以是1个40的,或者2个15的1个10的
然后,由背包问题把这些货物装进去
比如:12+12+6全装到40的中去,需要1000元
或者,12-》15,12-》15,6-》10,需要1100元
要使的总价钱最小!
显然前一种方案好!

至于算法,还在考虑中。。。 。。。
lyr311 2003-12-18
  • 打赏
  • 举报
回复
对了,楼主,刚才仔细看了一下提,你的这个题我没大看懂(笨),问一下:

①“10cm3----300元,15cm3----400元,40cm3-----1000元,” 与
“10立方体價值是300元,15立方体是400元,40立方体是1000元.”
是什么关系,10立方体是指什么哦?
②集装箱没有体积限制?
这还真不是当年那个题,当年那个叫“平板车装货问题”(前面记错了),当时的平板车有长度限制。

ZhangYv 2003-12-18
  • 打赏
  • 举报
回复
2001年全美数学建模赛有类似的,不过是球形装箱,使用模拟退火算法。
不过这种NP类的问题,都没有什么好算法,还好问题是规则长方体或许有好的方法。
lyr311 2003-12-18
  • 打赏
  • 举报
回复
楼主,不好意思,当时参加数学建模竞赛学校选拔人,让我们先编几个程序,我们当时是3人一组,我不是负责程序的,是在是一点也记不起了,过后也没想那么多,当时有个“锁具装箱问题”是我自己编出来的,而这个问题我实在做不出来,我最开始是用的穷举(不是数学专业的,也不是计算机专业,当时一点也不了解算法),根本作不出来,后来知道有个分支定界法可以解决整数规划问题,不用穷举了,但是我们后面通过选拔的那个程序之一的“集装箱装运问题”绝对不是用的分支定界法,就是想不起了,远去了,那段历史,盼望高人??????!!!!!!!
ZhangYv 2003-12-18
  • 打赏
  • 举报
回复
背包问题不存在有效算法。有种按体积/价格(密度)来算的贪心算法是近似的。
蝎子i软件 2003-12-18
  • 打赏
  • 举报
回复
试试排列组合。
设10cm3-->A
15cm3-->B
40cm3-->C;
对任一批货物,依次求各种排列组合的权:
先装满A,再装满B,接着装满C; 1
先装满A,再装满C,接着装满B; 2
...
ningzhiyu 2003-12-18
  • 打赏
  • 举报
回复
mark
treamboy 2003-12-18
  • 打赏
  • 举报
回复
lyr311(老刘:CSDN上瘾只为学习C++!)
老兄,能否提供你那改進后的算法的點點線索????
treamboy 2003-12-18
  • 打赏
  • 举报
回复
謝謝各位!!
集装箱的总体积是多少?
体积是無限,只是三個規格的容器,容器數量可以任意多,貨物是隨機給出.
上述算法仔細考慮也沒解決.
lyr311 2003-12-17
  • 打赏
  • 举报
回复
这好像不是当年的集装箱装运问题(数学建模的那个典型案例),我们编那个集装箱装运问题的程序,用一般的方法是基本上算不出来的,我曾经让机子算了一天也没算出来,但是如果改进算法(至今我也不知道当时用的什么算法)一分钟不到就出来了。你的这个问题估计也不简单,除非有很聪明的老大找到好的算法。
严重关注中!!!
zhuang1415 2003-12-17
  • 打赏
  • 举报
回复
回溯法和分之限界法也可以
随便找本算法书看看就可以了
祝楼主早日解决
zhuang1415 2003-12-17
  • 打赏
  • 举报
回复
就是用动态规划法
集装箱的总体积是多少?
wildcat1984 2003-12-17
  • 打赏
  • 举报
回复
0-1背包问题,可以用动态规划.
怎么做还没有想出来^_^
dot99 2003-12-17
  • 打赏
  • 举报
回复
启发式算法可找到次优解
否则用动态规划可疑找到最优解
加载更多回复(2)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧