【数学建模】自动化车床管理(蒙特卡洛模拟法)

1999年全国大学生数学建模竞赛题目A


自动化车床管理
一道工序用自动化车床连续加工某种零件,由于刀具损坏等原因该工序会出现故障,其中刀
具损坏故障占 95%, 其它故障仅占 5%。工序出现故障是完全随机的, 假定在生产任一零件时出现故障的机会均相同。工作人员通过检查零件来确定工序是否出现故障。
现积累有 100 次刀具故障记录,故障出现时该刀具完成的零件数如附表。现计划在刀具加工
一定件数后定期更换新刀具。
已知生产工序的费用参数如下:
故障时产出的零件损失费用 f = 200 f=200 f=200 元/件;
进行检查的费用 t = 10 t=10 t=10 元/次;
发现故障进行调节使恢复正常的平均费用 d = 3000 d=3000 d=3000 元/次(包括刀具费);
未发现故障时更换一把新刀具的费用 k = 1000 k=1000 k=1000 元/次。

1)假定工序故障时产出的零件均为不合格品,正常时产出的零件均为合格品, 试对该工序
设计效益最好的检查间隔(生产多少零件检查一次)和刀具更换策略。
2)如果该工序正常时产出的零件不全是合格品,有 2%为不合格品;而工序故障时产出的零
件有 40%为合格品,60%为不合格品。工序正常而误认有故障仃机产生的损失费用为 1500 元/次。
对该工序设计效益最好的检查间隔和刀具更换策略。
3)在 2)的情况, 可否改进检查方式获得更高的效益。

附:100 次刀具故障记录(完成的零件数)
459 362 624 542 509 584 433 748 815 505
612 452 434 982 640 742 565 706 593 680
926 653 164 487 734 608 428 1153 593 844
527 552 513 781 474 388 824 538 862 659
775 859 755 649 697 515 628 954 771 609
402 960 885 610 292 837 473 677 358 638
699 634 555 570 84 416 606 1062 484 120
447 654 564 339 280 246 687 539 790 581
621 724 531 512 577 496 468 499 544 645
764 558 378 765 666 763 217 715 310 851

question1

分析问题可知:
如果进行检查要花费 t = 10 t=10 t=10元/次
检查有两种结果,花费 { d = 3000 , 发现故障 0 , 未发现故障 \begin{cases} d=3000 , 发现故障\\ 0 , 未发现故障 \end{cases} {d=3000,发现故障0,未发现故障
注:说的是 未发现故障时 更换一把新刀具费用是 k = 1000 k=1000 k=1000元,前置条件是未发现故障,判断要执行的动作是更换一把新刀具,如果要换才花 k k k元,这里假定了假定工序故障时产出的零件均为不合格品,正常时产出的零件均为合格品,因此未发现故障,刀一定没坏,所以不换,花费为 0 0 0元。

我们先对100 次刀具故障记录(完成的零件数) 的数据进行处理:
先用C++跑出 出现的故障记录(完成的零件数) 对应的次数是多少

map<int,int>cnt;
void solve(){
   int x;
   for(int i=0;i<100;i++){
       cin >> x;
       cnt[x]++;
   }
   for(pair<int,int> k:cnt){
       cout << k.first << ' ' << k.second << '\n';
   }
}

改个打印格式再放进MATLAB里面画出柱状图

x =[84 120 164 217 246 280 292 310 339 358 362 378 388 402 416 428 433 434 447 452 459 468 473 474 484 487 496 499 505 509 512 513 515 527 531 538 539 542 544 552 555 558 564 565 570 577 581 584 593 606 608 609 610 612 621 624 628 634 638 640 645 649 653 654 659 666 677 680 687 697 699 706 715 724 734 742 748 755 763 764 765 771 775 781 790 815 824 837 844 851 859 862 885 926 954 960 982 1062 1153];
y =[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1];
bar(x,y)

在这里插入图片描述

可以很明显的看出线条集中在600偏左一点,出现次数为2的周边,查看之前的数据是593
算一下期望

double ex = 0;
    for(pair<int,int> k:cnt){
       ex += (double)k.first * (double)k.second/100;
    }
    cout << ex;

算一下期望得到 E ( x ) = 600 E(x) = 600 E(x)=600
并且分析上图推测该数据满足正态分布。

C++算标准差/方差:

double ex = 0;
    double ex2 = 0;
    for(pair<int,int> k:cnt){
       ex += (double)k.first * (double)k.second/100;
        ex2 += (double)k.first*(double)k.first * (double)k.second/100;
    }
    cout << ex2-ex*ex << '\n';
    double dx = 0;
    for(pair<int,int> k:cnt){
        dx += ((double)k.first-ex)*((double)k.first-ex) * (double)k.second/100;
    }
    cout << sqrt(dx);

得到方差为38276.4,标准差为195.644
用MATLAB画出正态分布图,如下图
在这里插入图片描述

上面这一步应该是拟合

假设检验

建立模型

综上所述,最好的检查间隔是600个零件/次,每次检查都换刀具

开始建立模型:
已知:
故障时产出的零件损失费用 f = 200 f=200 f=200 元/件;
进行检查的费用 t = 10 t=10 t=10 元/次;
发现故障进行调节使恢复正常的平均费用 d = 3000 d=3000 d=3000 元/次(包括刀具费);
未发现故障时更换一把新刀具的费用 k = 1000 k=1000 k=1000 元/次。

那么假设完成的零件数在 x x x时会故障,如果完成的零件数在 y y y时候检查,总花费 g ( y ) g(y) g(y)
g ( y ) = { ( y − x ) ∗ f + d + t , x ≤ y t , x > y g(y) = \begin{cases} (y-x)*f + d + t , x \le y\\ t, x \gt y \end{cases} g(y)={(yx)f+d+t,xyt,x>y

到目前为止难点就在于未发现故障时要不要更换一把新刀具并且其中刀具损坏故障占 95%, 其它故障仅占 5%。工序出现故障是完全随机的这个条件还没考虑到。
这里先直接假设刀具更换策略和检查策略分开,并且上述难点均分为刀具更换策略。

假设未检查到故障就不换刀,那么检查策略模型:
{ g ( y ) = { ( y − x ) ∗ f + d + t , x ≤ y t , x > y h ( x ) = 1 2 π σ e − ( x − μ ) 2 2 σ 2 min ⁡ E ( g ( y ) ) = ∫ g ( y ) h ( x ) d x μ = 600 , σ 2 = 38276.4 \begin{cases} g(y) = \begin{cases} (y-x)*f + d + t , x \le y\\ t, x \gt y \end{cases}\\ h(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}\\ \min E(g(y)) = \int g(y)h(x)dx\\ \mu = 600 , \sigma^2 =38276.4 \end{cases} g(y)={(yx)f+d+t,xyt,x>yh(x)=2π σ1e2σ2(xμ)2minE(g(y))=g(y)h(x)dxμ=600,σ2=38276.4
求出检查间隔是 y y y个零件/次

刀具更换策略模型:
假设完成的零件数在 x x x时会故障,如果完成的零件数在 y y y时候换刀
因为刀具损坏故障占 95%所以
g ′ ( y ) = { ( y − x ) ∗ f + d , x ≤ y 95 % k , x > y g'(y) = \begin{cases} (y-x)*f + d, x \le y\\ 95\%k, x \gt y \end{cases} g(y)={(yx)f+d,xy95%k,x>y

{ h ( x ) = 1 2 π σ e − ( x − μ ) 2 2 σ 2 min ⁡ E ( g ( y ) ) = ∫ g ′ ( y ) h ( x ) d x μ = 600 , σ 2 = 38276.4 \begin{cases} h(x) = \frac{1}{\sqrt{2\pi}\sigma}e^{-\frac{(x-\mu)^2}{2\sigma^2}}\\ \min E(g(y)) = \int g'(y)h(x)dx\\ \mu = 600 , \sigma^2 =38276.4 \end{cases} h(x)=2π σ1e2σ2(xμ)2minE(g(y))=g(y)h(x)dxμ=600,σ2=38276.4
求出换刀间隔是 y y y个零件/次

重新建立模型

1.确立检查间隔 n n n(检查间隔相同)
2.确立刀具更换周期 m = s n m=sn m=sn,即使不发生故障也要更换
总费用期望最低为目标
已知刀具寿命服从正态分布 N ( 600 , 195.64 4 2 ) N(600,195.644^2) N(600,195.6442)

1.预防更换费用(刀具寿命超过更换周期 m m m)
刀具更换前检查 s − 1 s-1 s1
c 1 = ( s − 1 ) t + k c_1 = (s-1)t+k c1=(s1)t+k 概率为 1 − F ( m ) 1-F(m) 1F(m)
i i i次检查发现故障更换费 ( i = 1 , . . , s − 1 ) (i=1,..,s-1) (i=1,..,s1)
c 2 i = i t + d + f ( n + 1 ) / 2 c_{2i}=it+d+f(n+1)/2 c2i=it+d+f(n+1)/2 概率为 F ( i n ) − F ( ( i − 1 ) n ) F(in)-F((i-1)n) F(in)F((i1)n)
(第 i − 1 i-1 i1到第 i i i次检查种平均生产 n + 1 2 \frac{n+1}{2} 2n+1不合格零件)

随机化求解

已知:
故障时产出的零件损失费用 f = 200 f=200 f=200 元/件;
进行检查的费用 t = 10 t=10 t=10 元/次;
发现故障进行调节使恢复正常的平均费用 d = 3000 d=3000 d=3000 元/次(包括刀具费);
未发现故障时更换一把新刀具的费用 k = 1000 k=1000 k=1000 元/次。

定一个 n n n m m m
每次随机一个 x x x服从正态分布 N ( 600 , 195.64 4 2 ) N(600,195.644^2) N(600,195.6442),相当于换新刀,随机生成刀的寿命
花费 W = { ( ⌈ x / n ⌉ ) t + d + ( ⌈ x / n ⌉ n − x ) f , x ≤ m ( m / n ) t + k , x > m W = \begin{cases} (\lceil x/n \rceil)t + d + (\lceil x/n \rceil n - x)f,x\le m\\ (m/n)t + k,x \gt m \end{cases} W={(⌈x/n⌉)t+d+(⌈x/nnx)f,xm(m/n)t+k,x>m
生产个数 T = { x , x ≤ m m , x > m T = \begin{cases} x,x\le m\\ m,x \gt m \end{cases} T={x,xmm,x>m
计算生成每个零件平均价值 W T \dfrac{W}{T} TW
随机 k k k x x x得到平均值 ∑ i = 1 k W T k \dfrac{\displaystyle\sum_{i=1}^{k} \dfrac{W}{T}}{k} ki=1kTW
取平均值最小的 n n n, m m m为解即可

蒙特卡洛模拟
matlab

t = 10; %进行检查的费用
k = 1000; %未发现故障时更换一把新刀具的费用
d = 3000; %发现故障进行调节使恢复正常的平均费用
f = 200; %故障时产出的零件损失费用
ans_n = 0;
ans_m = 0;
ans_wt = 1e9;
x = abs(normrnd(600,195.644,10000));
for n = 1:50
    for s = 1:100
        m=s*n;
        wt = 0;
        for i = 1:length(x);
            w = 0;
            t = 0;
            if x(i) < m
                w = w+ceil(x(i)/n)*t+d+(ceil(x(i)/n)*n-x(i))*f;
                t = t+x(i);
            else
                w = w+s*t+k;
                t = t+m;
            end
            wt = wt + w/t;
            if ans_wt*1000 < wt
                break;
            end
        end
        if ans_wt > wt/1000
            ans_n = n;
            ans_m = m;
            ans_wt = wt/1000;
        end
    end
end
disp(ans_n);
disp(ans_m);
  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值