免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 11300 | 回复: 2

[练习] 尺寸切割方案 [复制链接]

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
发表于 2013-11-29 04:50 |显示全部楼层
本帖最后由 rubyish 于 2013-12-04 02:16 编辑

问题:
解决一个线材切割问题,
例如一根钢材10m,要切割2.5m,2.6m,1.9m三种尺寸,
剩下的废料要小于最小的尺寸。
有以下11种切割方案。

      sum    remain     2.5     2.6     1.9
01|  10.00   0.00       4       0       0
02|   9.70   0.30       0       3       1
03|   9.60   0.40       1       2       1
04|   9.50   0.50       2       1       1
05|   9.50   0.50       0       0       5
06|   9.40   0.60       3       0       1
07|   9.00   1.00       0       2       2
08|   8.90   1.10       1       1       2
09|   8.80   1.20       2       0       2
10|   8.30   1.70       0       1       3
11|   8.20   1.80       1       0       3

表述为数学形式就是,
10-(2.5a+2.6b+1.9c)< 1.9
10-(2.5a+2.6b+1.9c)>= 0


a,b,c=0,1,2,3....
写一个程序,求出这种算法的所有方案,即a,b,c的所有组合。
实际使用中,可能不止三种尺寸,视输入而定。
输出格式类似于表格,也可以转置成纵向表格,这样方便输出。

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
发表于 2013-11-29 04:54 |显示全部楼层
本帖最后由 rubyish 于 2013-12-01 19:45 编辑

v1: del~
v2:
  1. nLENGTH  = 10
  2. aCUT  = [ 2.5, 2.6, 1.9, 3.5, 2.0, 4.0, 4.5, 5, 4.7, 3.2 ]
  3. aCUT.sort! {|a, b| b <=> a }
  4. nMAX  = nLENGTH - aCUT.last
  5. nNUM  = 0

  6. puts ["%9s%10s" % %w[sum remain], *aCUT] * ?\t
  7. aTRY = aCUT.map {|x| [*0 .. nLENGTH / x] }
  8. aTRY.shift.product(*aTRY).reduce([]) {|r, s|
  9.   nSUM, nI = 0, -1
  10.   s.each do |si|
  11.     nSUM += aCUT[nI += 1] * si
  12.     break if nSUM > nLENGTH
  13.   end
  14.   r << [nSUM, nLENGTH - nSUM, *s] if nLENGTH >= nSUM &&  nSUM > nMAX
  15.   r
  16. }.sort {|a, b| b.first <=> a.first }.each {|x|
  17.     puts "%03d|%7.2f%7.2f\t" % [nNUM += 1, *x.shift(2)] << x * ?\t
  18.   }
复制代码

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
发表于 2013-12-04 04:48 |显示全部楼层
v3:
  1. #!/usr/bin/ruby
  2. nlength = 10
  3. adata = [ 5, 4.7, 4.5, 4.0, 3.5, 3.2, 2.6, 2.5, 2.0, 1.9 ]
  4. adata.sort! {|a, b| b <=> a }
  5. scount = 0

  6. def kelect nlength, adata
  7.   nmax, ncheck, nt, ni = nlength - adata[-1], 1, 1, -1
  8.   arange = adata.map {|e| (0 .. nlength / e).to_a }
  9.   aelem  = arange.map {|e| ncheck *= e.size; e.size }
  10.   astep  = [1, *(1...aelem.size).map {|e| nt *= aelem[-e] }].reverse!
  11.   acollection = []

  12.   while (ni += 1) < ncheck
  13.     anum = (0...aelem.size).map {|i| arange[i][ni / astep[i] % aelem[i]] }
  14.     nsum = 0

  15.     for i in 0...aelem.size
  16.       nsum += adata[i] * anum[i]
  17.       next if nsum <= nlength
  18.       njump = (aelem[i] - anum[i]) * astep[i]
  19.       ni += njump - 1
  20.       break
  21.     end

  22.     acollection << [nsum, nlength - nsum, anum] if
  23.       nlength >= nsum && nsum > nmax
  24.   end
  25.   acollection
  26. end

  27. puts "%4s%5s%7s\t" % ['', 'sum', 'rem'] << adata * ?\t
  28. kelect(nlength, adata).sort {|a, b| b[0] <=> a[0] }.each do |e|
  29.   print '%03i'% scount += 1, "| %5.1f%7.2f\t" % e.shift(2), e * ?\t, ?\n
  30. end

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP