全球FlexSim系统仿真中文论坛

标题: 【琢磨琢磨推拉】该用推式还是拉式? [打印本页]

作者: zorsite    时间: 2016-5-8 16:07
标题: 【琢磨琢磨推拉】该用推式还是拉式?
本帖最后由 zorsite 于 2016-5-8 16:19 编辑 3 z5 D( A4 f6 a- ~7 N3 b

  G" Z, x8 v6 p7 {. H估计这将是一篇冷贴,高手不屑看,新手看了脑袋大。
3 \' i: `- F- I; a4 z, eQQ群里有人在问某案例如果不用拉式策略该怎么办?
- f$ I! `, C( z" N" x, j# Y这是一个很简单但又很经典的一个案例,布局如下:' q4 \1 G" D# U1 z, L
[attach]3084[/attach]
. ^5 }/ j! s' a1 h% }) g这个案例的核心要求是:上面两台处理器只处理临时实体类型1,下面三台处理器只处理临时实体类型2.& |+ M( l9 U4 f0 h  t
解决方法1:
/ x9 x4 k; L; i" x9 T( X4 X; m如果使用拉式策略,在处理器中设置拉入条件即可:2 j. W0 V9 f( N) P2 v4 w
[attach]3085[/attach]# `/ R% q# H+ R3 O: e8 s5 W

( r% _5 H" Y0 F; Z( G0 g" `6 l解决方法2:
# ]( w+ F  H; g" a! N9 I
有人坚持要用推式策略
3 N" D5 m- K  U1 R% r/ w% g在暂存区的发送至端口中编写以下代码:
  1. if (getitemtype(item)==1) return duniform(1,2);
      A1 D, [: s+ w4 `  X
  2. else return duniform(3,5);
复制代码
简单粗暴,问题解决。注意,记得把处理器中的拉式策略取消。
# e; o) D" I* V0 _3 O
但是有一个问题,有可能随机产生的端口所连接的处理器正在使用中,而另外有处理器处于空闲状态。如何把临时实体发往处于空闲状态的那个处理器呢?
, o( m5 Z$ ]4 e2 {0 P0 ^0 X解决方法3:, _5 w+ Y0 J; `3 h
删掉上面那两行代码,输入以下代码:
  1. int totalop;0 t5 c! j4 k4 D  M, s5 P! g( H
  2. int startop;
    6 o9 H7 `; f% W, Q+ p
  3. if (getitemtype(item)==1)   : d# Z6 g; X9 t& A! ?4 P
  4. { startop=1;( N9 D0 X1 z' Q7 J
  5. totalop=2;
    8 c, [  K! U! t! ]
  6. }
    5 f3 ~& J6 S8 V8 K
  7. else   
    % w, s( ^' _/ O
  8. {
    2 Q9 m4 W% j' g2 s" R
  9. startop=3;$ ]7 D- c' M# y; L
  10. totalop=3;
    " G# e' e  }* V. E& F% f
  11. }
    ( _  H+ n/ `9 X) w4 I- ?0 L
  12. doublearray openports = makearray(totalop);
    % d7 {8 H0 \/ h% p5 l& Q
  13. int nrofportsopen = 0;
    ! l" A7 I" E) g( B7 @4 `1 i( y5 G, r& c
  14. for ( int index = startop; index < startop+totalop; index++)
    $ U7 Q% e" B% a% j" r, p
  15. {2 h8 x9 t( B$ J* H4 H* ]6 q2 \
  16. if (opavailable(current,index))
    " l& w/ W3 n) b# l" e; ^, l$ e
  17. {' }3 s! O* j: ]" O
  18.   nrofportsopen++;& t+ `8 @3 F% C' N1 u
  19.   openports[ nrofportsopen ] = index;+ [  }( A1 U( E
  20. }
    - L4 F9 E! Z8 z0 Y6 ]8 V% d0 k
  21. }
    2 E4 y" ?# n' H  H, d4 t! T, l
  22. double returnvalue;
    % t9 e5 b, Z9 [. r0 E5 D- Z% I
  23. if (nrofportsopen > 0) 4 W( x: ^* Y; F5 w6 t. [( V) ?
  24. {
    1 U' |6 I$ f% c6 A. w/ V; s  q
  25. int returnindex = duniform(1, nrofportsopen);. ?- e4 G8 H' k" S4 [7 I( O) t
  26. returnvalue = openports[returnindex];
    & C3 ^* H/ y+ k# r* P  \/ W- G
  27. } else4 @5 }/ e" M$ r7 {% x
  28.    returnvalue = duniform(startop,startop+totalop-1);6 S: ]0 F6 ^1 p' \: w5 F2 J
  29. return returnvalue;
复制代码
这段代码是由系统自带的“随机可用端口”稍作修改得到的,在这个案例中其实也不完美,比如说,3台暂存区都处于加工状态,这个时候来了新的临时实体,发往哪个端口?代码中设置的是随机端口。可是这3台处理器加工完毕的时间有先有后,能不能发送至最先加工完的那个处理器上?对不起,这段代码做不到。9 g) k7 D( r2 c
为了能够直观的观察这段代码的缺陷,可以把发生器的发生时间间隔设置小一些,比如均值设置为6或者3,重置模型后点击步进按钮来观察模型。
$ G7 x  C1 f( b# d/ u$ A1 q解决方法4:
" U6 _- [$ A% K) P8 P; `9 j
转换一下思路,如果要解决上面的问题,就必须要知道每一台处理器还剩多少时间能加工完毕,然后找到最先加工完的那一台。这样一来,目标就转换成了找到剩余加工时间最短的那一台处理器。8 m5 ^: c% Y5 w( g; ]& m# t
剩余加工时间=安装时间+加工时间+进入时间-当前时间
, K/ e1 X0 J# z# w4 H删掉以上代码,输入以下代码:
  1. int totalop;) y( r; V2 j2 n6 G( D2 F; S' E
  2. int startop;' w' |1 b0 q. G) [- C
  3. if (getitemtype(item)==1)   & g) B. Z/ P4 P! c" A
  4. {
    % r6 b/ D+ z/ f
  5. startop=1;
    ; Q: z0 w. ~6 o; S$ [" l" c4 R* n
  6. totalop=2;
    . l* x5 s, G4 `) j
  7. }! E. F7 Q9 {/ n( K  f( r; s3 ~: d- I
  8. else   
    : Z! l+ ]4 F2 n  g8 B1 D
  9. {; z$ J7 l2 b: f  T0 K: w
  10. startop=3;
    2 M& O. K. r9 {) O1 P/ V- F
  11. totalop=3;
    * P/ y! p& l7 M) g( _0 V
  12. }# h7 m2 H9 D! s* g' }; t
  13. double minitime= 2147483647;
    ; r8 P& E) h* \
  14. int returnvalue=0;
    8 S$ Q3 ], a( c; a+ |/ M8 S/ L
  15. for (int i = startop; i < totalop+startop ; i++) 4 c# i( Y; E7 Z$ B/ R2 U: ]
  16. {
    * [, P  ^7 L! Z  g
  17. double protime=getitemvar(rank(outobject(current,i),1),2);9 a% X1 S5 r1 P/ D
  18. double setuptime=getitemvar(rank(outobject(current,i),1),3);
    7 m% G2 @' ~. I# n% `' ~
  19. double entrytime=getentrytime(rank(outobject(current,i),1));5 c1 a8 P2 c+ ?) J: Z
  20. double remainingtime=protime+setuptime+entrytime-time();7 ]) G+ S8 S! L
  21. if (remainingtime<minitime)) ^% Q* x  w" b3 N' n
  22. {- e# `( ~" Q$ I( n2 t% z
  23.   minitime=remainingtime;
    1 H0 c1 o9 k5 F& Y; B
  24.   returnvalue=i;4 y& [5 H* _. O; D
  25. }
    : S1 g+ w2 B# D# I) p$ Y% c8 t0 x
  26. }  D& j$ K* ^' V: ~9 [5 |
  27. return returnvalue;
    ' c5 W) z$ ]' _- E4 t5 x
复制代码
终于把问题解决了,缺点是这段代码不具备随机性。把这段代码加入到上一次代码的else区域试一下?此时可以把发生时间的均值改回10,然后步进模型查看效果。( s3 P$ U$ e/ x

; E- Z. R/ n# F( `9 o" v# \该出手时就出手,该用拉式就用拉式吧,原谅我写代码不加注释吧!) x2 O% w) M' w& A
[attach]3086[/attach]

作者: Kimver    时间: 2016-5-8 22:30
我也想过这个问题,学习了,点个赞
作者: 慧娴亚伦    时间: 2016-5-9 09:22
用 FlexSim建模要重点领会flex这个词。8 v: R, S& \; q  T% e: H
在FlexSim仿真世界中,抵达一个目的地有无数条路,对于实际建模需求而言,只要能够抵达,那么这条“路”就不孬。但是选择一条更好的更快捷的“路”是一个仿真建模师从入门到精通必须要掌握的一个过程,也是真正区分高手的方法。+ M# E3 }) h. s2 ~8 Y  O
加老师给出的思考过程,对于深入学习FlexSim是非常重要的,学习仿真过程中提出“能不能用其他方式来完成这个建模要求”只是第一步,更为关键的是能不能通过进一步的思考和测试,通过自己的力量去实现新的解决方式。
! D1 e* r, @' J但是在这个过程中,千万不要“钻牛角尖”,作为学习是可以尝试各种不同的方法,但是在实际应用中请务必使用最简单最直观的方法。此外,也不要想着一口气就将所有的原理弄透,把一些暂时无法理解的东西记录下来,只要坚持学习使用,就会在逐步深入的过程中“顿悟”原先那些看上去非常不合理的存在。
/ |; L1 b  }2 q7 C4 I8 R" w: B3 o- m# I( O2 i( l
感谢加老师分享。
作者: ldl89772962    时间: 2016-9-30 10:52
感谢老师分享




欢迎光临 全球FlexSim系统仿真中文论坛 (http://www.flexsimasia.com/) Powered by Discuz! X3.3