|
本帖最后由 zorsite 于 2016-5-8 16:19 编辑 ) Z9 Q+ R5 B& G* x# c$ k, `5 e; Z: G
5 S1 N7 [% C8 L估计这将是一篇冷贴,高手不屑看,新手看了脑袋大。, @" Q0 z/ v7 U: E D* o# h7 ?
QQ群里有人在问某案例如果不用拉式策略该怎么办?
0 [: x* `# q8 g; |9 k, \* S( o这是一个很简单但又很经典的一个案例,布局如下:
# T" h6 y S% I& @& }- ?6 I" [9 \/ v9 t' j3 U
这个案例的核心要求是:上面两台处理器只处理临时实体类型1,下面三台处理器只处理临时实体类型2.
2 k8 @; u* ]' L0 I9 t9 @7 y解决方法1:
1 P* q7 ~ W0 x( z. C& }; w5 \1 v0 P如果使用拉式策略,在处理器中设置拉入条件即可:0 P, o5 F& o' l8 R+ @( X3 G
9 H+ L* M& j/ g, q1 o. j/ f9 |( C/ B$ d# g% m
解决方法2:
$ @ D. i; U+ E( @( H) H有人坚持要用推式策略 8 y- m# \- m4 J- l
在暂存区的发送至端口中编写以下代码:- if (getitemtype(item)==1) return duniform(1,2);
+ @% @8 _, ]. n0 T0 M - else return duniform(3,5);
复制代码简单粗暴,问题解决。注意,记得把处理器中的拉式策略取消。 2 }" H7 C4 y# Z/ n. Q/ U1 X
但是有一个问题,有可能随机产生的端口所连接的处理器正在使用中,而另外有处理器处于空闲状态。如何把临时实体发往处于空闲状态的那个处理器呢? V' V! Q- u& f \
解决方法3:
# L$ V! Q5 R2 T% n5 D+ ]删掉上面那两行代码,输入以下代码:- int totalop;4 [1 N: E# ?3 N& C+ ?& |: L
- int startop;
/ i9 z) N( b; w* u: l - if (getitemtype(item)==1) 6 e1 J7 }: F+ v5 Y" d; {* \% ]
- { startop=1;
9 U' R, n8 o0 v1 J8 r q2 R u4 o; x - totalop=2;
: b- s! {, b" W. [% D0 k% G - } [/ L9 x" o8 w8 N
- else
5 {2 }+ R: C6 [) Z- @7 i A - {3 h0 l8 y& Y; ~+ y" [# e, r9 @' E' p
- startop=3;
; K2 |* k2 b! @% W8 m* k! S - totalop=3;
. y, ~! u1 ^, Z* j* m* `1 h6 y - }, j6 Y; i* t3 Z" @1 f c+ w
- doublearray openports = makearray(totalop);! S8 R, p4 Q: _* p6 \
- int nrofportsopen = 0;1 C8 L8 K; y. O0 _+ }% g
- for ( int index = startop; index < startop+totalop; index++) ' j8 ~* a' U8 j# b
- {; J: }& @+ A6 _5 v+ N6 r0 f& W
- if (opavailable(current,index)) ( u3 E3 \ y6 n% P9 N i
- {
- k6 V, Q0 B5 X% q! t - nrofportsopen++;
1 H, @1 ]" Y( X1 M& x, a - openports[ nrofportsopen ] = index;
% x2 d, p4 r9 x1 n" F - }" f0 O) ^1 k$ N9 T3 x
- }
$ b* |4 n4 ?, P5 `2 E# T: h - double returnvalue;7 J9 @$ [9 A" \! }8 J5 Q7 f$ ]2 N
- if (nrofportsopen > 0) . q! z/ X9 ?2 ~! n9 e* f) e
- {
, j8 p& M' I. W8 ^/ J) E+ V - int returnindex = duniform(1, nrofportsopen);
/ M7 B2 }: t( x - returnvalue = openports[returnindex];+ l3 g7 p4 m$ G$ X. H) V7 M3 g" s% r
- } else* f( a9 r) O3 _, P5 S
- returnvalue = duniform(startop,startop+totalop-1);
; t7 F5 v4 b' b% _9 B - return returnvalue;
复制代码 这段代码是由系统自带的“随机可用端口”稍作修改得到的,在这个案例中其实也不完美,比如说,3台暂存区都处于加工状态,这个时候来了新的临时实体,发往哪个端口?代码中设置的是随机端口。可是这3台处理器加工完毕的时间有先有后,能不能发送至最先加工完的那个处理器上?对不起,这段代码做不到。4 g8 q( {5 {+ l. p$ W$ P7 L; [
为了能够直观的观察这段代码的缺陷,可以把发生器的发生时间间隔设置小一些,比如均值设置为6或者3,重置模型后点击步进按钮来观察模型。
4 C4 m6 s( {; ^, q" _& B$ U' H c解决方法4:
) E s- _1 ^+ m转换一下思路,如果要解决上面的问题,就必须要知道每一台处理器还剩多少时间能加工完毕,然后找到最先加工完的那一台。这样一来,目标就转换成了找到剩余加工时间最短的那一台处理器。
" u% @3 ^' U) N( t3 s7 \剩余加工时间=安装时间+加工时间+进入时间-当前时间( W8 o1 ]5 Q8 \. g" K
删掉以上代码,输入以下代码:- int totalop;3 A& ]6 O5 m; w( @7 c" n! A
- int startop;7 t! v% o( M3 m6 h4 t9 G
- if (getitemtype(item)==1) # b2 c5 N& _* ~
- { 3 n" H% w; ^! ^" x2 c. Q5 P
- startop=1;
! b9 N+ R6 X- ^! {% [, m' W ?7 t - totalop=2;3 J( @$ j" r) ^3 i" s; ~; C
- }
7 h: q5 _- L' f - else
& V5 |' ?- z( ]5 o - {
/ s. V g% k3 O' R. y - startop=3;
* _ `& t. O% {6 z' T0 u - totalop=3;
2 x0 [4 u2 Y! t$ W - }
! p' W. r0 | ?; S1 y2 @5 g6 l - double minitime= 2147483647;8 p( U% z W0 ~6 ] U, O0 D
- int returnvalue=0;
/ I1 I6 A2 G; I - for (int i = startop; i < totalop+startop ; i++)
" }+ }9 C' @- B+ p! U - {
/ ^/ U1 ^! M; A - double protime=getitemvar(rank(outobject(current,i),1),2);2 c0 R; N0 y- m: Z8 A0 w
- double setuptime=getitemvar(rank(outobject(current,i),1),3);8 [9 ?5 y a* Y( j6 P3 Z
- double entrytime=getentrytime(rank(outobject(current,i),1));
1 u4 K Y6 k: n! d4 p. S - double remainingtime=protime+setuptime+entrytime-time();
4 t- V1 H. j5 x8 y8 C. f - if (remainingtime<minitime)+ I6 v4 u" P% c
- {0 z2 |: n9 H g4 w$ V
- minitime=remainingtime;: i2 x( p4 p0 N/ G1 t) S1 O
- returnvalue=i;/ @1 d, }) J7 @9 ^
- }
) O7 O6 G; I7 J0 Y2 d1 n( R% z - }
: m' ]& V) H$ J - return returnvalue;- S, E4 L/ W! W# C1 a
复制代码 终于把问题解决了,缺点是这段代码不具备随机性。把这段代码加入到上一次代码的else区域试一下?此时可以把发生时间的均值改回10,然后步进模型查看效果。6 E& ?, N! j7 }" d- d6 X
# x9 t5 |- d3 B5 W' J" p6 O3 I- u$ ^该出手时就出手,该用拉式就用拉式吧,原谅我写代码不加注释吧!, ]% B; c8 @7 z* a
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
|