请帮忙看看此算法。谢谢

quanquan626 2003-12-06 09:12:18
有一批订单,订单中需要有长度为L1的钢材N1根,长度为L2的钢材N2根,……长度为LK的钢材NK根。钢材每切割一次,将会有长度为DL的损耗。现有长度为L的钢材一根,要求从订单中选出若干根,使得钢材损耗最少(即L1.L2..LK都是用户自己输入。需要的N1,N2...NK也是用户自己输入)(最好能用vb解决。。实在不行用数学方法解决也可以)
...全文
5 点赞 收藏 35
写回复
35 条回复
boodweb 2003年12月18日
怎么个不好法?在我说的范围之内的话就算是正常的了
回复 点赞
quanquan626 2003年12月17日
谁试过 几组数据么?我试的结果不是很好啊!有的还没有手工 优化的好
回复 点赞
boodweb 2003年12月12日
to quanquan:
没明白你说的什么意思,举例说明把
回复 点赞
zhang_jiang 2003年12月12日
to quanquan626(圈圈):

for(;i<n;i++) // 循序搜索定单中的n个钢材
if(l-DL-s[i]>=0) // 如果第i根刚才能放下的话,这跟就在这条L中截取
{
Insert(Ans[index],s[i]); // 把s[i]放入练表Ans[index]
s[i]=无穷大; // 使得这根定单中的钢材在下次搜索中不能被采纳,当然
// 你取成L+1也可。:)
}
回复 点赞
quanquan626 2003年12月12日
boodweb(TTT):我是按照你说的(就是先从小到大排序,然后从小到大一个一个的往里面填,)这样做的,但可以在降序、或升序的大前提下,但不完全按照降序或升序的往里填!也是可行的!但是这里该怎么写
回复 点赞
boodweb 2003年12月12日
btw:可以证明,我上面说的贪心算法解出的钢条数与理论最优解的比值<=4/3+1/3m,其中m是理论最优解
回复 点赞
quanquan626 2003年12月11日
我的命怎么这么苦啊。。。本来就不懂数学。。现在还这样折腾我。。好。。我去google搜索bin packing去。。。哼。。。。我就不信这个邪。。。。。
回复 点赞
boodweb 2003年12月11日
就是先从小到大排序,然后从小到大一个一个的往里面填,当然这是仅对第一个条件而言的一个简单的近似算法
全部填完就找到近似解了
回复 点赞
amdcwf 2003年12月11日
用贪心?
我想问一下,什么情况下可以断言说找到解了?
(除了S=0的情况下,可以)
即,停机条件是什么?
而且,还要考虑在什么样的停机条件下,所得出的结果的可信度高??
也就是说,即使楼主使用近似算法,还是需要考虑N多东东的
当然,这里不是劝楼主不要试图解决这个问题,
我的意思是劝楼主不要试图完美解决这个问题。

也许你看看专家系统方面的东东会有帮助的。



回复 点赞
boodweb 2003年12月11日
告诉楼主一个不幸的消息,即使只考虑第一个条件,你的问题也是一个算法上的难题,即所谓的bin packing问题,其中大多数情况都是NPC的,至今没有多项式算法,建议用近似算法(比如上面的贪心)

google上搜索bin packing能搜到好多,希望对你有用
回复 点赞
quanquan626 2003年12月10日
对!是这样的,但是我写到一半就进行不下去了,总是觉得理论是对的,可是实现来很困难!
如果用户需要
20种长度的钢管,他们的数量是一般不相同的,所以导致在写的时候,很不对劲!
假设现在已经有几个结果,实际上需要, 最后在不同的结果中,再一次比较他们的损耗总和,损耗最小的,才应该是实际工作中真正要用到的。
我做了几个,结果是,给他们不同的一组数据,最后得到的结果却不同。也就是说,第一种方法,在这一组数据中,得到的最优解,但是在另一组数据中得到的却不是最优解!这怎么解决?
所以,还是希望那位能给一个较好的算法/1!
谢谢!
回复 点赞
amdcwf 2003年12月10日
剩料A组: 230,568,651,7,
剩料B组: 7,30,168,1265,
结果能,我们宁愿选择 B组,因为剩料中,有一个比较大的值,这个1265长度,还可以在下一个工程切割中使用,因为剩料<600的情况下,我们都扔掉了,已经没有实际利用价值了,但是这个600,却不是定数,所以,最好的算法是 还能够控制剩料的大小范围!比如 400---900之间是可以利用的等等,这2个数也不是定值!
______________________________________________
按楼主这样的说法,那么就要增加一个条件了:
8)若L-(L1*x1+L2*x2+..+Ln*xn)>=Min并且L-(L1*x1+L2*x2+..+Ln*xn)<=Max 则
有 L-(L1*x1+L2*x2+..+Ln*xn)等于0
Min与Max是要求的剩料长度
显然,这个条件并不能减少求解空间,因为程序还是要判断某种组合是不是使得条件8)成立







回复 点赞
boodweb 2003年12月10日
直觉上如果只要满足最少根数那应该可以用dp,如果还要那个可能会麻烦些
回复 点赞
boodweb 2003年12月10日
To amdcwf:
那你怎么知道一定要考察所有可能呢?有些问题可以用dp或者greedy解就不需要啊
回复 点赞
quanquan626 2003年12月10日
啊~~~~~~~~~~~~~~~~~~~上帝啊~~~~~~~~~~~杀了我吧~~~~~~~~~~~~~
我晕拉~~~~~~~~~~~~~~~~~
回复 点赞
amdcwf 2003年12月10日
to boodweb(TTT) :
我说的不是解空间,是求解空间,也就是说,要找全局最优解的情况下,如果非要找到最小损耗的组合,就必须对所有的组合进行考察,就像你要在一组数中,找一个最小数一样。你说的dp,Greedy只是在求解空间很小的情况下,才能使用, 但因为这个问题的求解空间与问题的规模是n^n的关系,所以是不能使用的。

当然,也不一定是说非要考察完所有的组合,因为,当有一种组x1,x2,..xn使得S等于0,则就找到解了,但是在最坏的情况下,就得考察完所有的组合!

to 楼主:
我们当然有直觉一看就知道有一大半是不符合条件的。
但你要机器自动解决,它怎么知道有一大半不符要求??难道不需要指令进行判断吗?

在空循环下,计算机要执行10^20次的空循环,注意这里循环是空循环!


回复 点赞
quanquan626 2003年12月10日
amdcwf(谈,我爱你) :解的空间是这样大的,可有一大半是不符合条件的!啊,运行时非要我们死机么?
要求用的最少根L,这只是一个条件,
然后在用最少根L的情况下,剩的钢材最少,但剩的钢材并不一定要求累加和最少,
经2种算法计算,假设剩料如下:
剩料A组: 230,568,651,7,
剩料B组: 7,30,168,1265,
结果能,我们宁愿选择 B组,因为剩料中,有一个比较大的值,这个1265长度,还可以在下一个工程切割中使用,因为剩料<600的情况下,我们都扔掉了,已经没有实际利用价值了,但是这个600,却不是定数,所以,最好的算法是 还能够控制剩料的大小范围!比如 400---900之间是可以利用的等等,这2个数也不是定值!

zhang_jiang(windforce|]---}->) :
for(;i<n;i++)
if(l-DL-s[i]>=0)
{
Insert(Ans[index],s[i]);
s[i]=无穷大;
}
没有看懂!
回复 点赞
boodweb 2003年12月10日
那用料最省又是指的什么呢?是所用的长度为L的钢材的数目最少马?
回复 点赞
quanquan626 2003年12月10日
boodweb(TTT) 我的意思是钢材的长度已经固定了就是L。。而这L有很多根。。。然后用户根据自己的需要来输入不同长度的钢材和每种钢材对应的数量。。比如。。用户输入L1长的刚才为N1根。。L2的为N2根。。依次类推。。。LK的为NK根。。怎么样来根据已有的长度就是L根的刚才来截取。(每截取一次就损耗DL长度的钢材)。。怎么样截取使用料最省。。。。(固定长度L的钢材有很多)
回复 点赞
boodweb 2003年12月10日
“解决损耗问题。将L、L1、L2.......Ln都加上DL。计算的时候就可以不管DL了”
还是要管一下的吧,每次浪费的材料除了最后剩下的,还有k*DL(其中k为截的次数),真的不管的话显然可以化成上面的01背包问题,不过我不知道你到底要求的是什么,是求应该挑哪些钢材才能这根钢材浪费的最少吗?

To amdcwf(谈,我爱你) :你说的N1*N2*...是所有的可能的解数,不代表所有算法复杂度都要这么大,不然dp,greedy还有什么用啊,
btw: NP问题是说至今还没有多项式算法的一类问题,是不是NP也要证明的,而不是看解空间的大小
回复 点赞
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.0w+

社区成员

3.4w+

社区内容

数据结构与算法相关内容讨论专区
社区公告
暂无公告