全球FlexSim系统仿真中文论坛

搜索
查看: 4107|回复: 3
打印 上一主题 下一主题

【琢磨琢磨推拉】该用推式还是拉式?

[复制链接]
跳转到指定楼层
1#
zorsite 发表于 2016-5-8 16:07:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zorsite 于 2016-5-8 16:19 编辑   J" L6 h6 c: i) S. v5 N+ d& v' N" e

" j2 b0 f5 @& ^- b( k估计这将是一篇冷贴,高手不屑看,新手看了脑袋大。; m$ B0 e* Y- D) D0 E5 w& D
QQ群里有人在问某案例如果不用拉式策略该怎么办?& I; k! u7 R; X( a' I
这是一个很简单但又很经典的一个案例,布局如下:# H- F( _6 K: {/ p( V

& z; L; w( S& C, O; i: m/ y这个案例的核心要求是:上面两台处理器只处理临时实体类型1,下面三台处理器只处理临时实体类型2.
- Q% y, q6 o' y  y3 a4 J" A4 I解决方法1:
% ?  w3 j8 H6 Z+ L如果使用拉式策略,在处理器中设置拉入条件即可:4 m( Z8 u: H$ E. v

- D; t0 m' F2 l- f  H& B
: J9 ~4 m+ m. [# n1 {解决方法2:& \' S+ h& [8 v9 k0 Y
有人坚持要用推式策略 ! e5 K- j9 B/ n! p
在暂存区的发送至端口中编写以下代码:
  1. if (getitemtype(item)==1) return duniform(1,2);. W' b7 y8 D7 S6 g0 F
  2. else return duniform(3,5);
复制代码
简单粗暴,问题解决。注意,记得把处理器中的拉式策略取消。

1 S/ Z/ d/ F# ?. L但是有一个问题,有可能随机产生的端口所连接的处理器正在使用中,而另外有处理器处于空闲状态。如何把临时实体发往处于空闲状态的那个处理器呢?* ?. W6 G/ Z' L+ n' b; J& n
解决方法3:
. k0 N  F; T  g3 _删掉上面那两行代码,输入以下代码:
  1. int totalop;
    9 a+ j  G' W* i- q( T2 u
  2. int startop;
    ! j6 a3 j% s/ ^6 s" n9 @
  3. if (getitemtype(item)==1)   
    0 @$ {0 H4 y/ X* Q
  4. { startop=1;
    , f" J8 l" B+ B
  5. totalop=2;0 J" N1 D5 `; J- a2 S) m  u
  6. }5 v) X: U: u" a1 j7 N6 B: }
  7. else   / t& [; J1 B, t8 u. o7 a
  8. {
    ' q4 [. d* c' T# J- Q5 ?
  9. startop=3;
    3 J% ^9 X1 g" l& e
  10. totalop=3;' y% V/ n' Q' ]8 F$ o4 Z
  11. }! l4 ?; A+ T. m* O
  12. doublearray openports = makearray(totalop);
    1 B+ a6 y# N; l
  13. int nrofportsopen = 0;
    3 T+ Y* B+ a) I6 ?) [
  14. for ( int index = startop; index < startop+totalop; index++) & o; g7 L0 ~: [5 B' S
  15. {5 {# K$ `# A$ S6 S! n
  16. if (opavailable(current,index))
    / x6 \- J# j6 k! ^: x; N
  17. {
    5 j: t1 f, K: F4 `- p# t
  18.   nrofportsopen++;
    8 K! L  j8 N' V
  19.   openports[ nrofportsopen ] = index;
    3 F' I% }' K1 D
  20. }5 B" F6 R6 C" `  O6 l
  21. }9 Y) T  d* Q7 H( ^& K: n; j! A. V  e
  22. double returnvalue;5 t7 R" j3 s9 C1 u( u+ S
  23. if (nrofportsopen > 0)
    # H  Y# I1 i; E4 R- @, T( m. Q
  24. {$ h! F7 J* y; ~+ p. R8 B7 ~% V1 |
  25. int returnindex = duniform(1, nrofportsopen);. e  s! m7 a/ o& k# b. e
  26. returnvalue = openports[returnindex];
    2 I% P. W$ t2 c8 @5 J1 ?
  27. } else; ~% d& W0 }1 k6 h2 e; ?# ~6 s
  28.    returnvalue = duniform(startop,startop+totalop-1);
    - u% f: V# @( f, i/ H
  29. return returnvalue;
复制代码
这段代码是由系统自带的“随机可用端口”稍作修改得到的,在这个案例中其实也不完美,比如说,3台暂存区都处于加工状态,这个时候来了新的临时实体,发往哪个端口?代码中设置的是随机端口。可是这3台处理器加工完毕的时间有先有后,能不能发送至最先加工完的那个处理器上?对不起,这段代码做不到。
+ C) s  Q& j+ W0 n为了能够直观的观察这段代码的缺陷,可以把发生器的发生时间间隔设置小一些,比如均值设置为6或者3,重置模型后点击步进按钮来观察模型。
6 X& h% {  |; W2 C6 {$ c8 y解决方法4:
3 v7 a8 ~" [6 `- [
转换一下思路,如果要解决上面的问题,就必须要知道每一台处理器还剩多少时间能加工完毕,然后找到最先加工完的那一台。这样一来,目标就转换成了找到剩余加工时间最短的那一台处理器。: M) |) U) t0 V- u5 a1 |- O8 G# h- c% p
剩余加工时间=安装时间+加工时间+进入时间-当前时间
$ L# Y/ P/ D. d' C删掉以上代码,输入以下代码:
  1. int totalop;
    + A9 C$ ]) c4 v* m% F
  2. int startop;
    ! K9 ~% i( I( D  r
  3. if (getitemtype(item)==1)   
    # [7 g/ y8 T- R& f1 V4 f& Z
  4. {
    - \( ^  a( {( @7 x2 H( i0 {
  5. startop=1;
    3 v5 d" C. ^% p6 [; }; r0 {9 s
  6. totalop=2;) N- w8 [8 F8 ]$ e% ]/ C
  7. }. `$ \# o/ L% @  F% [7 ?
  8. else   / k$ M& |; ^# r
  9. {8 Q, `! ~' Q/ c# W' y  {
  10. startop=3;
    ' p4 }: @& B% O1 Q
  11. totalop=3;. N4 Z" D) h8 T" x; C; k" k
  12. }" d* N: X- k; u# c
  13. double minitime= 2147483647;4 R' t# r$ Z! f
  14. int returnvalue=0;: ?7 J* I8 Z* O" P* e' s
  15. for (int i = startop; i < totalop+startop ; i++) $ V1 }. _% z4 g1 \4 H) ]. ]
  16. {
    # N2 B3 |2 ]8 V- v9 j
  17. double protime=getitemvar(rank(outobject(current,i),1),2);
    0 @5 J& V8 r2 Y2 e
  18. double setuptime=getitemvar(rank(outobject(current,i),1),3);5 i3 ]6 [2 K6 m6 w+ H. f& T9 N
  19. double entrytime=getentrytime(rank(outobject(current,i),1));* p8 M1 O+ U! O. B
  20. double remainingtime=protime+setuptime+entrytime-time();
    - }1 U  e1 t) T6 N" I1 `
  21. if (remainingtime<minitime)
    # z6 T1 S- @; w" D0 K
  22. {
    & h% }3 g6 Z5 P
  23.   minitime=remainingtime;
    ( ^" Y- i2 s8 E0 T6 H. C: k3 A
  24.   returnvalue=i;9 v. A) l3 \  ?% E: h/ W1 O+ {; s* n
  25. }
    ( p0 N% ~  L& d$ ^, I7 ]( a- r4 ]: T8 S
  26. }) K% R' M1 x4 P/ Y5 k
  27. return returnvalue;
    % a2 r2 o( ~: V! |) \! @; T- E
复制代码
终于把问题解决了,缺点是这段代码不具备随机性。把这段代码加入到上一次代码的else区域试一下?此时可以把发生时间的均值改回10,然后步进模型查看效果。
0 L' d8 P' o; S9 V5 s# d8 F8 n# K, Q( \: q" \6 y& W/ j, h) D" {
该出手时就出手,该用拉式就用拉式吧,原谅我写代码不加注释吧!% w+ |- l6 i3 b% R0 f9 X5 L4 w

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
2#
Kimver 发表于 2016-5-8 22:30:41 | 只看该作者
我也想过这个问题,学习了,点个赞
3#
慧娴亚伦 发表于 2016-5-9 09:22:02 | 只看该作者
用 FlexSim建模要重点领会flex这个词。( p# ?! |& t: v/ ]2 O* z1 |
在FlexSim仿真世界中,抵达一个目的地有无数条路,对于实际建模需求而言,只要能够抵达,那么这条“路”就不孬。但是选择一条更好的更快捷的“路”是一个仿真建模师从入门到精通必须要掌握的一个过程,也是真正区分高手的方法。( H, ?% S& z! g9 Z
加老师给出的思考过程,对于深入学习FlexSim是非常重要的,学习仿真过程中提出“能不能用其他方式来完成这个建模要求”只是第一步,更为关键的是能不能通过进一步的思考和测试,通过自己的力量去实现新的解决方式。
3 a1 U$ k& D7 @; e: D2 ]但是在这个过程中,千万不要“钻牛角尖”,作为学习是可以尝试各种不同的方法,但是在实际应用中请务必使用最简单最直观的方法。此外,也不要想着一口气就将所有的原理弄透,把一些暂时无法理解的东西记录下来,只要坚持学习使用,就会在逐步深入的过程中“顿悟”原先那些看上去非常不合理的存在。
. x1 |) p1 L* L0 {% ?4 f$ @* V$ Z9 E: c
感谢加老师分享。
4#
ldl89772962 发表于 2016-9-30 10:52:40 | 只看该作者
感谢老师分享
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|全球FlexSim系统仿真中文论坛 ( 京ICP备14043114号-2 )

GMT+8, 2025-6-30 19:58 , Processed in 0.081220 second(s), 14 queries .

Powered by Discuz! X3.3© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表