|
本帖最后由 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
在暂存区的发送至端口中编写以下代码:- if (getitemtype(item)==1) return duniform(1,2);. W' b7 y8 D7 S6 g0 F
- 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 _删掉上面那两行代码,输入以下代码:- int totalop;
9 a+ j G' W* i- q( T2 u - int startop;
! j6 a3 j% s/ ^6 s" n9 @ - if (getitemtype(item)==1)
0 @$ {0 H4 y/ X* Q - { startop=1;
, f" J8 l" B+ B - totalop=2;0 J" N1 D5 `; J- a2 S) m u
- }5 v) X: U: u" a1 j7 N6 B: }
- else / t& [; J1 B, t8 u. o7 a
- {
' q4 [. d* c' T# J- Q5 ? - startop=3;
3 J% ^9 X1 g" l& e - totalop=3;' y% V/ n' Q' ]8 F$ o4 Z
- }! l4 ?; A+ T. m* O
- doublearray openports = makearray(totalop);
1 B+ a6 y# N; l - int nrofportsopen = 0;
3 T+ Y* B+ a) I6 ?) [ - for ( int index = startop; index < startop+totalop; index++) & o; g7 L0 ~: [5 B' S
- {5 {# K$ `# A$ S6 S! n
- if (opavailable(current,index))
/ x6 \- J# j6 k! ^: x; N - {
5 j: t1 f, K: F4 `- p# t - nrofportsopen++;
8 K! L j8 N' V - openports[ nrofportsopen ] = index;
3 F' I% }' K1 D - }5 B" F6 R6 C" ` O6 l
- }9 Y) T d* Q7 H( ^& K: n; j! A. V e
- double returnvalue;5 t7 R" j3 s9 C1 u( u+ S
- if (nrofportsopen > 0)
# H Y# I1 i; E4 R- @, T( m. Q - {$ h! F7 J* y; ~+ p. R8 B7 ~% V1 |
- int returnindex = duniform(1, nrofportsopen);. e s! m7 a/ o& k# b. e
- returnvalue = openports[returnindex];
2 I% P. W$ t2 c8 @5 J1 ? - } else; ~% d& W0 }1 k6 h2 e; ?# ~6 s
- returnvalue = duniform(startop,startop+totalop-1);
- u% f: V# @( f, i/ H - 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删掉以上代码,输入以下代码:- int totalop;
+ A9 C$ ]) c4 v* m% F - int startop;
! K9 ~% i( I( D r - if (getitemtype(item)==1)
# [7 g/ y8 T- R& f1 V4 f& Z - {
- \( ^ a( {( @7 x2 H( i0 { - startop=1;
3 v5 d" C. ^% p6 [; }; r0 {9 s - totalop=2;) N- w8 [8 F8 ]$ e% ]/ C
- }. `$ \# o/ L% @ F% [7 ?
- else / k$ M& |; ^# r
- {8 Q, `! ~' Q/ c# W' y {
- startop=3;
' p4 }: @& B% O1 Q - totalop=3;. N4 Z" D) h8 T" x; C; k" k
- }" d* N: X- k; u# c
- double minitime= 2147483647;4 R' t# r$ Z! f
- int returnvalue=0;: ?7 J* I8 Z* O" P* e' s
- for (int i = startop; i < totalop+startop ; i++) $ V1 }. _% z4 g1 \4 H) ]. ]
- {
# N2 B3 |2 ]8 V- v9 j - double protime=getitemvar(rank(outobject(current,i),1),2);
0 @5 J& V8 r2 Y2 e - double setuptime=getitemvar(rank(outobject(current,i),1),3);5 i3 ]6 [2 K6 m6 w+ H. f& T9 N
- double entrytime=getentrytime(rank(outobject(current,i),1));* p8 M1 O+ U! O. B
- double remainingtime=protime+setuptime+entrytime-time();
- }1 U e1 t) T6 N" I1 ` - if (remainingtime<minitime)
# z6 T1 S- @; w" D0 K - {
& h% }3 g6 Z5 P - minitime=remainingtime;
( ^" Y- i2 s8 E0 T6 H. C: k3 A - returnvalue=i;9 v. A) l3 \ ?% E: h/ W1 O+ {; s* n
- }
( p0 N% ~ L& d$ ^, I7 ]( a- r4 ]: T8 S - }) K% R' M1 x4 P/ Y5 k
- 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
|