|
本帖最后由 zorsite 于 2016-5-8 16:19 编辑 1 `& v- Q! W% @' V: v: {. @) B' u
6 ]8 s; t8 x: ]" L l
估计这将是一篇冷贴,高手不屑看,新手看了脑袋大。2 b% C) {0 j3 j J
QQ群里有人在问某案例如果不用拉式策略该怎么办?5 K2 F6 `3 w% a+ `" m
这是一个很简单但又很经典的一个案例,布局如下:4 q L4 _1 X* d6 T+ L+ p: l& p
J, {" ?- b9 {& D8 e) g这个案例的核心要求是:上面两台处理器只处理临时实体类型1,下面三台处理器只处理临时实体类型2.
x6 X& `* K) [解决方法1:
( I( z7 V1 T' L/ o( ^: Y1 ^如果使用拉式策略,在处理器中设置拉入条件即可:
+ M+ O! r8 S# s; S% `
4 Z; l+ C0 d0 N" [8 D/ |* `# C: Q$ B; V/ i
解决方法2:
; s1 g/ ?/ `% e有人坚持要用推式策略 / C- x ?% o, a) K$ p' u9 Z
在暂存区的发送至端口中编写以下代码:- if (getitemtype(item)==1) return duniform(1,2);
* w) @7 p. b% t* W* o8 C* M' b - else return duniform(3,5);
复制代码简单粗暴,问题解决。注意,记得把处理器中的拉式策略取消。 / e4 T. X5 x! [% E9 C( w) m
但是有一个问题,有可能随机产生的端口所连接的处理器正在使用中,而另外有处理器处于空闲状态。如何把临时实体发往处于空闲状态的那个处理器呢?
( ~9 [! y0 p7 n' s y解决方法3:
& ], l2 w8 ~+ g* Y" j: G, B3 o删掉上面那两行代码,输入以下代码:- int totalop;
t1 q9 R, P. _) N5 Q* U - int startop;5 r' w; J1 f! {1 ^
- if (getitemtype(item)==1) 0 N- X" g* U! t- b( I1 p" D& e7 L
- { startop=1;
" q! I |2 O+ r6 U) M& ~0 [ - totalop=2;; p$ U6 ^8 Z9 ]' U1 j
- }
+ }4 \* H, e) [/ h0 B7 U - else
% O1 S2 N2 E) }7 L; w: O7 }: S - {
' A. u$ q8 _5 @2 B7 w; T& Z - startop=3;
9 o' K$ o- }6 Z f* k5 ~4 j - totalop=3;
, T4 [; x, }4 u) d+ w! p - }
2 k' x2 U, Q7 @5 s9 ` - doublearray openports = makearray(totalop);
/ H0 p# Z& w1 B- y! r7 u, _ - int nrofportsopen = 0;
+ z5 n: ~- N6 M - for ( int index = startop; index < startop+totalop; index++)
6 Z7 c# o3 B' E - {
7 d7 t5 b- {9 q - if (opavailable(current,index)) ' n* c# Q6 Y/ h3 \5 E# m8 g
- {8 I9 Z4 Z+ s' U6 v: ^, ]9 ^8 r
- nrofportsopen++;, {4 L0 m0 X) `& G; m6 M/ N
- openports[ nrofportsopen ] = index;
+ a# O" a9 W9 g* I - }4 h9 d" Y6 u, q# L- \
- }
& y; ?. `5 s; U2 M+ Z( ]# \ - double returnvalue;( V" [9 t9 Q7 q0 {! \4 _8 |! R
- if (nrofportsopen > 0)
7 Y1 U8 G4 ^ B - {
7 m/ @$ C, t3 `3 L) P& @ - int returnindex = duniform(1, nrofportsopen);
5 J7 j( d3 w7 Q* _! p" j - returnvalue = openports[returnindex];( u& T* A+ K1 H2 f, x/ W/ j" d
- } else# c# p# O; ^( p% J1 r
- returnvalue = duniform(startop,startop+totalop-1);
# x8 e/ M) d. I j' v6 b9 K) f - return returnvalue;
复制代码 这段代码是由系统自带的“随机可用端口”稍作修改得到的,在这个案例中其实也不完美,比如说,3台暂存区都处于加工状态,这个时候来了新的临时实体,发往哪个端口?代码中设置的是随机端口。可是这3台处理器加工完毕的时间有先有后,能不能发送至最先加工完的那个处理器上?对不起,这段代码做不到。
( D$ t5 x5 S; c" ?4 c* Q为了能够直观的观察这段代码的缺陷,可以把发生器的发生时间间隔设置小一些,比如均值设置为6或者3,重置模型后点击步进按钮来观察模型。! V7 B' x, @) M. Q2 p: j
解决方法4:
8 w4 O: ~6 @- ~; X! D8 l转换一下思路,如果要解决上面的问题,就必须要知道每一台处理器还剩多少时间能加工完毕,然后找到最先加工完的那一台。这样一来,目标就转换成了找到剩余加工时间最短的那一台处理器。' g1 H- W L/ K8 F
剩余加工时间=安装时间+加工时间+进入时间-当前时间
0 d$ s4 S+ q/ r删掉以上代码,输入以下代码:- int totalop;8 e3 y1 M/ h% s: i/ ~
- int startop;
% s( q" z8 C3 p: M/ i! j' o - if (getitemtype(item)==1) $ [, M+ i& [7 p# q
- {
, _3 @! ^, n# z) y - startop=1;
( y) r1 k& u# e - totalop=2;
- H/ H# ~' c* [ - }
' M# N) [! G$ K - else
$ w. D: m1 E4 i - {. Q0 P( U# C* ]1 `( @; h* l
- startop=3;% b3 ^3 F% j) t; o! J7 r
- totalop=3;) V( b$ u! [5 p
- }
, Q4 Y0 v+ V7 s - double minitime= 2147483647;3 b) u5 C4 O3 A" {% l
- int returnvalue=0;4 O9 k/ m6 I# k' U3 }' s1 J
- for (int i = startop; i < totalop+startop ; i++) ! Y# b( o' X; C
- {8 z9 `1 s, M7 k1 M$ T% |
- double protime=getitemvar(rank(outobject(current,i),1),2);, G! u0 ^4 x( s9 ]6 A
- double setuptime=getitemvar(rank(outobject(current,i),1),3);
, y* a; q9 e( O) E - double entrytime=getentrytime(rank(outobject(current,i),1));3 U9 T, f# B* s
- double remainingtime=protime+setuptime+entrytime-time();
J/ k3 t5 U/ T9 |+ y" [ - if (remainingtime<minitime)
n8 _7 _, S; X7 R7 p - {
: s9 E0 B7 ]5 R. p - minitime=remainingtime;
( @1 P% F5 {+ B4 M8 F - returnvalue=i;2 K. p& L e8 m+ o3 u* q4 ]" O& _
- }
7 W/ g! F4 R8 i, k) u5 K2 I - }
! [* }: |) s# ~* | - return returnvalue;. M# \+ g4 Y! a2 \1 G' b5 j6 }
复制代码 终于把问题解决了,缺点是这段代码不具备随机性。把这段代码加入到上一次代码的else区域试一下?此时可以把发生时间的均值改回10,然后步进模型查看效果。
( {2 l @# X6 r8 d/ }% W
( b# i5 k% }4 O+ k: ^该出手时就出手,该用拉式就用拉式吧,原谅我写代码不加注释吧!
% o& Z4 R3 h; ^6 C2 b |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|