标题: [数值计算] 批处理怎样计算出材料最佳下料方法? [打印本页]
作者: xxx3212 时间: 2010-5-24 20:41 标题: 批处理怎样计算出材料最佳下料方法?
铝材长度 6米 和 5.4米
1.8米*10支
1.5米*20支
2.2米*30支
3.1米*15支
计算出最佳切割方法
作者: sgaizxt001 时间: 2010-5-24 20:47
注册时间非常早。
题目有意思
作者: 523066680 时间: 2010-5-24 20:49
神级这个单词小心搞得没人好意思做。
小弟愚昧,连问题都看不懂,囧了……
哦是不是说
1.5米*20支 这样的, 用5跟 6米的钢材分别切割成四份,最适合?
[ 本帖最后由 523066680 于 2010-5-24 20:54 编辑 ]
作者: hanyeguxing 时间: 2010-5-24 20:58
代码没有优化:- @echo off
- for /f "tokens=1* delims=*" %%a in ('more +30^<"%~fs0"') do call:hanye %%a %%b
- pause&exit
- :hanye
- setlocal enabledelayedexpansion
- set n=%1&set m=%2&set n=!n:~0,-1!&set m=!m:~0,-1!&set n=!n:.=!
- :s60
- set/a n_60+=1
- set/a y_60_!n_60!=60-n*n_60,k_60=n_60,x_60_!n_60!=1
- if !y_60_%n_60%! geq %n% goto:s60
- set/a n_60+=1,y_60_0=y_60_!k_60!,v_60=2
- for /l %%a in (%n_60%,1,%m%) do (set/a n_60=%%a,y=%%a%%k_60,w_60+=1
- set/a y_60_%%a=y_60_!y!
- if !w_60! gtr !k_60! (set/a v_60+=1,x_60_%%a=v_60,w_60=1) else set x_60_%%a=!v_60!)
- set/a y_60_0=0,x_60_0=0
- :s54
- set/a n_54+=1
- set/a y_54_!n_54!=54-n*n_54,k_54=n_54,x_54_!n_54!=1
- if !y_54_%n_54%! geq %n% goto:s54
- set/a n_54+=1,y_54_0=y_54_!k_54!,v_54=2
- for /l %%a in (%n_54%,1,%m%) do (set/a n_54=%%a,y=%%a%%k_54,w_54+=1
- set/a y_54_%%a=y_54_!y!
- if !w_54! gtr !k_54! (set/a v_54+=1,x_54_%%a=v_54,w_54=1) else set x_54_%%a=!v_54!)
- set/a y_54_0=0,x_54_0=0
- for /l %%a in (0,1,%m%) do (set/a b=m-%%a
- set/a z_%%a=y_60_%%a+y_54_!b!)
- for /F " tokens=1-3 delims==_" %%a in ('set z_') do if not defined bc (set bc=%%c&set a=%%b) else if %%c lss !bc! set bc=%%c&set a=%%b
- set/a b=m-a
- echo.%1*%2:需要6米的铝材 !x_60_%a%! 根;需要5.4米的铝材 !x_54_%b%! 根.
- Endlocal&goto:eof
- 1.8米*10支
- 1.5米*20支
- 2.2米*30支
- 3.1米*15支
复制代码
结果:1.8米*10支:需要6米的铝材 0 根;需要5.4米的铝材 4 根.
1.5米*20支:需要6米的铝材 5 根;需要5.4米的铝材 0 根.
2.2米*30支:需要6米的铝材 0 根;需要5.4米的铝材 15 根.
3.1米*15支:需要6米的铝材 0 根;需要5.4米的铝材 15 根.
[ 本帖最后由 hanyeguxing 于 2010-5-25 04:27 编辑 ]
作者: xxx3212 时间: 2010-5-24 21:14 标题: 回复 3楼 的帖子
就是这样 要算出最节约材料的方法
作者: hanyeguxing 时间: 2010-5-25 03:08
以1.0米分别分割10支、11支、12支、13支时,结果如下:
10支时需要6米的铝材 0 根;需要5.4米的铝材 2 根.
11支时需要6米的铝材 1 根;需要5.4米的铝材 1 根.
12支时需要6米的铝材 2 根;需要5.4米的铝材 0 根.
13支时需要6米的铝材 0 根;需要5.4米的铝材 3 根.
[ 本帖最后由 hanyeguxing 于 2010-5-25 03:10 编辑 ]
作者: sgaizxt001 时间: 2010-5-25 03:09
一种考虑的是:6米和5.4米等价,切完4种情况,总舍弃的米数和最少
还有一种考虑的是:假设6米和5.4米的等价,切完4种情况,总使用的根数和最少
虽然我不知道两种结果是否都是一样,但是两种结果的切法都不一样时,按哪一种,比如如下两种情况:
- 15根6米切2.2的30根+1.5米15根,丢掉的是15*0.1米,剩余
- 1.8 10
- 1.5 5
- 3.1 15
- 15根5.4米切剩下的所有,则舍弃总和是10*0.5+5*0.8+15*0.1=10.5
- 使用根数总和是:15+5+10=30根
复制代码
- 15根5.4米切3.1的15根+2.2的15根,3根5.4米切1.8的9根,5根6米切1.5米的20根,丢掉的是15*0.1米
- 2.2 15
- 1.8 1
- 7根5.4米切2.2的14根,舍弃7*1米,1根5.4米切2.2的1根+1.8的1根,舍弃1.4米。舍弃总和事7*1+1.4+15*0.1=9.9米。
- 使用根数总和是:15+3+5+7+1=31
复制代码
[ 本帖最后由 sgaizxt001 于 2010-5-25 04:58 编辑 ]
作者: hanyeguxing 时间: 2010-5-25 03:17 标题: 回复 7楼 的帖子
4楼的代码仅是分割一种的情况,没有去处理四种情况同时存在。楼主也没做这个说明。
[ 本帖最后由 hanyeguxing 于 2010-5-25 03:21 编辑 ]
作者: xxx3212 时间: 2010-5-25 08:38 标题: 回复 4楼 的帖子
你的算法太简单了 只是计算同样的材料切割需要多少支 BAT如果能写出来 那真是神了
作者: 523066680 时间: 2010-5-25 08:48 标题: 回复 9楼 的帖子
我感觉答案就是那样啦。
莫非 6 米的钢材可以配合 5.4米的钢材? 但那不是分开的吗……
还是说还有细节,请列举一个“特别处理”“的情况。
批处理算24,平分水,什么的都有呀…… 感觉就算做这道题也没什么称神的。
作者: sgaizxt001 时间: 2010-5-25 09:06
楼主,你可否提供正确答案给我参考参考
作者: hanyeguxing 时间: 2010-5-25 18:28
原帖由 xxx3212 于 2010-5-24 20:41 发表
铝材长度 6米 和 5.4米
1.8米*10支
1.5米*20支
2.2米*30支
3.1米*15支
计算出最佳切割方法
1,楼主没有说明1.8、1.5、2.2、3.1是分别计算,还是统一计算。4楼代码是按分别计算设计的。
2,原帖由 xxx3212 于 2010-5-25 08:38 发表
你的算法太简单了 只是计算同样的材料切割需要多少支 BAT如果能写出来 那真是神了
楼主这里说的“同样的材料”是什么意思?是第一条里的,还是指4楼的代码没有统一计算6米和5.4米的使用?如果是后者,那推荐楼主还是把4楼的代码看完整了再说。
3,4楼代码的设计思路:
1,定义单根范围内6米的分割余数
2,定义最大范围内6米的分割余数
3,定义单根范围内5.4米的分割余数
4,定义最大范围内5.4米的分割余数
5,统计只使用6米、只使用5.4米、同时使用6米和5.4米时的余数
6,比较余数
7,获取最小余数时的分割
作者: netbenton 时间: 2010-5-26 22:55
这种题真的是为难批处理了~~~
搞了半天,还是不能通用!!只能就题解答
- @echo off&setlocal enabledelayedexpansion
-
- ::////////////////////////
- for /f "tokens=1-2 delims=米*支" %%a in (%~nx0) do (
- if "%%a" equ "铝材:" set s=lc&set n=
- if "%%a" equ "切割:" set s=cg&set/a lcx=!n!-1&set n=
- if defined s if defined n set !s!!n!=%%a&set !s!!n!n=%%b&set vars=!vars! !s!!n!
- set /a n+=1
- )
- set/a cgx=!n!-1
- :::://////把数据读入到变量
-
- ::set lc
- ::set cg
- ::set vars
- ::pause
-
- ::////////////////////////
- for %%a in (%vars%) do (
- for /f "delims=. tokens=1,2" %%c in ("!%%a!") do (set ver=%%d0)
- set d=0
- for /l %%b in (0,1,10) do (
- if "!ver:~%%b,1!" neq "" set d=%%b
- )
- set d%%a=!d!
- if !d! gtr !dot! set dot=!d!
- )
- set ver=0000000000
-
- for %%a in (%vars%) do (
- set /a n=dot-d%%a
- for %%b in (!n!) do set d%%a=!%%a:.=!!ver:~,%%b!
- )
- ::set d
- ::pause
- ::////////////小数位调整
-
-
-
- ::////////////////////////
- for /l %%a in (1,1,!cgx!) do (
- for /l %%b in (1,1,!cgx!) do (
- if !cg%%a! leq !cg%%b! set /a bcg%%a+=1
- ))
-
- set n=0
- for /l %%a in (1,1,!cgx!) do (
- for %%b in (mum!bcg%%a!) do (
- set /a n+=1
- set %%b=!%%b! cg%%a
- ))
-
- for /l %%a in (1,1,!n!) do set vv=!vv! !mum%%a!&set bcg%%a=&set num%%a=
- ::echo; !vv!
- ::pause
- ::///////要切割规格排序
-
-
- for %%a in (%vv%) do (
- set vvn=!vv:*%%a=!
- set gnn=!d%%a!
- for /l %%b in (1,1,!lcx!) do (
- set /a nn=dlc%%b %% d%%a
- if !nn! lss !gnn! set gnn=!nn!&set gxx=lc%%b
- for %%c in (!vvn!) do (
- set /a mm=nn %% d%%c
- if !mm! lss !gnn! set gnn=!mm!&set gxx=lc%%b %%c
-
- ))
-
- rem 首先切规格最长的,并且配合其它规格,选最省切法
-
- for /f "tokens=1,2" %%b in ("!gxx!") do (
- set/a ##v=d%%b/d%%a,##y=d%%b %% d%%a,##y=##y/d%%c
-
- set/a ##s1=%%an/##v,##s2=##s1,##xy=%%an %% ##v
-
- set gvv=!d%%a!
- if !##xy! neq 0 (
- set/a ##k=%%an-##s1*##v
- set/a ##s1+=1,##k=d%%b-##k*d%%a
- for %%d in (!vvn! lc1) do (
- set /a mm=##k %% d%%d
- if !mm! leq !gvv! set gvv=!mm!&set gxx=%%d
- )
- )
-
- set/a ##x1=%%an,##x2=##s2*##y,%%an=0
- set/a #d%%b=##s1+#d%%b,%%cn=%%cn-##x2,#lf1=gnn*##s2
-
- echo;使用!%%b!米铝材 !##s1!根
- set /p =切成:!%%a!米长!##x1!根,还差0根<NUL
- if !##y! neq 0 (echo;,!%%c!米长!##x2!根,还差!%%cn!根<NUL) echo;
-
- if !gvv! neq !d%%a! (
- for %%d in (!gxx!) do (
- echo;二次利用:!##k:~,-%d%!.!##k:~-%d%!米 切得:
- set/a ##k1=##k/d%%d, ##k2=##k %% d%%d,%%dn=%%dn-##k1
- echo; !%%d!米长!##k1!根 还差:!%%dn!根,仍剩:0!##k2:~,-%d%!.!##k2:~-%d%!米
- set/a #lf1=#lf1+##k2
- ))
- echo;本次浪费:0!#lf1:~,-%d%!.!#lf1:~-%d%!米
- echo;
-
- set/a #lf=#lf+#lf1
- )
- )
-
- for /l %%a in (1,1,!lcx!) do (
- echo;共用材料:!lc%%a!米,!#dlc%%a!根
- )
- echo;共浪费材料:!#lf:~,-%d%!.!#lf:~-%d%!米
-
- pause
-
- exit/b
-
- ::数据定义
- 铝材:
-
- 6米
- 5.4米
-
- 切割:
-
- 1.8米*10支
- 1.5米*20支
- 2.2米*30支
- 3.1米*15支
复制代码
[ 本帖最后由 netbenton 于 2010-5-26 23:01 编辑 ]
作者: sgaizxt001 时间: 2010-5-26 23:31
不错,用了29跟材料,共浪费2.7米
不过if !##y! neq 0 (echo;,!%%c!米长!##x2!根,还差!%%cn!根<NUL) echo;这里手误多了个echo;
代码先复制下来慢慢研究
作者: terse 时间: 2010-5-27 11:04
线性规划 来了
作者: jackerloo2009 时间: 2010-5-28 00:00 标题: 口头分析了一下因网页有问题全部丢失了,这次只能简单写了
6m 5支 1.5m*20
5.4m 3支 1.8m*9
5.4m 15支 3.1m*15 2.2m*15 余料 5.4m-5.3m=0.1m*15=1.5m
5.4m 1支 1.8m*1 2.2m*1 余料 5.4m-4m=1.4m*1=1.4m
5.4m 7支 2.2m*14 余料 5.4m-4.4m=1m*7=7m
使用 6m 【5支】
使用5.4m 【26支】
使用总长度为 6m*5+5.4m*26=30m+140.4m=170.4m
浪费总长度为 1.5m+1.4m+7m=9.9m
利用率为94.19%
浪费率为5.81%
材料切割和利用在工业行业一直是个很重要也很头疼的问题,你的问题其实口算就差不多了,不适合批处理,因为批处理很难表达其中的逻辑规律,是有些为难批处理了,还有你的问题如果只是作为一个理论来研究代码是可行的,如果实际应用是不大现实的,比如机械切割工具会存在切割宽度的浪费,如果你切割尺寸对公差要求严格的话很难保证的,只是单纯下毛坯料还行的通,但也要具体参考切割工具的宽度,所以说只是这么一个问题就口头分析下就ok,想让批处理表达其中的逻辑技巧,恐怕难以如愿!必须得一个常切割下料,有过充足经验的,深谙其中一些算法和规律的才能给你一个完美答案,以上为浅见,还望指教!
作者: backup 时间: 2010-5-29 21:46 标题: 回复 13楼 的帖子
你好强啊,这么长,头都晕了
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |