GPSSWorld初级程序编写套路

发布时间 2023-06-13 14:39:50作者: 孤飞

1.仿真用时间控制:

    generate 16,9
    ...
    terminate
    generate	240
    terminate	1
    start	1

2.仿真预热:

	start	5,np
	reset
	start	20

3.理发师选择有偏好:

transfer	both,adda,addb
adda	seize	s_a
	…
addb	seize	s_b
	…

4.理发师选择没有偏好:

(1)方法1:概率+both

transfer	.5,sel_a,sel_b
sel_a	transfer	both,adda,addb
sel_b	transfer	both,addb,adda
adda	seize	s_a
	…
addb	seize	s_b
	…

(2)方法2:pick+both

agn	    transfer	pick,sel_a,sel_b
sel_a	transfer	both,adda,agn;如果进不去a就回到agn重新选择
sel_b	transfer	both,addb,agn
adda	seize	s_a
	…
addb	seize	s_b
	…

Q:为什么用pick模式就要让sel_a回到agn重新选择呢?像方法1一样直接尝试addb不行吗?

A: 一旦尝试进入sel_a,就开始both模式了,both模式是有偏好的,优先进入A,我们希望的事一直随机选择。

Q:可以去掉方法2中的sel_a 、b直接尝试进入adda 、b吗?为什么?【例3.8】

A: pick的随机选择模式是选中一个就会死等这一点,不会像both一样尝试下一个,所以我们不能让其去尝试进入seize模块,否则一直等待A,B好了也不会进去,所以要配合transfer both模块来使用。

5.如果服务设施没有区别的话不如让其变成存储器。

6.多个入口(也就是有多个能够产生实体的通道),一定要避免已经存在的活动实体尝试进入另一个的generate模块,通常用到无条件跳转实现。

	generate	20,10
	transfer	,add1
	generate	30,5
add1	...

7.质量检查(成功概率问题)

	transfer	.1,acc,rej
acc	...
rej	terminate

8.活动实体(顾客)有优先级【急诊】

(1)方法1:产生实体时就赋予优先级

	generate	7,5	;缺省,优先级默认为0
	...
	terminate
	generate	60,40,,,1

(2)方法2:通过PRIORITY模块改变优先级

	generate	7,5
	...
	terminate
	generate	60,40
	priority	1,bu

9.如果设施都忙,则直接离开:建立一个terminate的标签

s_bar	storage		2
		generate	10
		transfer	both,add1,add2;进不去存储器就离开
add1	enter	s_bar
		...
add2	terminate

10.先处理离开再处理进入

(1)方法1:占用设施后给活动实体提高优先级

因为同一个时间发生的事件是随机处理的,有可能原先占用设施的活动实体先离开设施;也有可能先让到达的实体尝试进入,尝试失败就离开了。

add1	enter		s_bar
		priority	1
		advance		20
		leave		s_bar
		terminate	1

(2)方法2*:将新到达的活动实体移动到当前事件链表(CEC)相同优先级活动实体后面

		generate	10
		buffer
		transfer	both,add1,add2
add1	enter		s_bar
		advance		20

11.控制活动实体的产生开始时间和数量

在主体流程之后可以再写generate通过无条件跳转到之前的模块

	generate	3,1,7200,60	;2小时后一共产生60个活动实体
	transfer	,str1

11.借助过程参数SNA码来确定活动实体的运行过程

例如:获取最短队列作为实体的一个参数,到时候在这个实体排队,以及有时候通过参数记录特定的延迟时间advance

    queue	p$q_kb
    advance	p1,p2

12.实现按时关门结束运营(按条件结束系统运行)

通过产生一个更高优先级的活动实体来抢夺设施控制权,抢夺成功后就不在工作了(排队的直接赶出去)

	generate	480,,,,2
	seize		f_bar
	release		f_bar
	terminate	1
	start		1

那么有没有更贴合实际的模型呢,也就是准时关门,不再让新顾客进入排队,已经进门等候的继续完成再歇业,这时候可以用逻辑开关来当作一个门

            initial		ls1
            generate	16,9
            gate ls		1,out
add_jr		queue		q_bar
			seize		f_bar
			depart		f_bar
			advance		15,7
add_done	release		f_bar
			terminate
out			terminate

			generate	480	;用一个实体来直接完成计时和程序终止
			logic R		1
			test e		n$add_jr,n$add_done	;进入人数和完成人数相等
			terminate	1
			start		1

那如果理发师中午也需要吃饭,理完手上的发后就吃完饭(到时间),再处理排队的人,那就需要灵活运用控制实体的功能了

            generate	240,,,1,2	;用一个实体来直接完成计时和程序终止
            seize		f_bar
            advance		(300-c1)	;c1是系统模拟钟相对时间
            release		f_bar
            advance		240
            logic r		1	;关门
            test e		n$add_jr,n$add_done	;进入人数和完成人数相等
            terminate	1	;控制实体完成使命
            start		1

如果要统计理发师的占有率*,那么就不能通过优先级占用来实现吃饭了。可以多加几个开关。

小明11:30去了理发店开始排队,一看离吃饭还有一会儿,应该能轮上。等到最后一个前面的顾客理完发时12:01了,理发师说我先去吃饭,你等到一点吧......

...
add_jr		queue		q_bar
			GATE NU		f_bar	;测试理发师有空位了吗的意义是,检查逻辑开关是排队结束了才测试。
			GATE LS		2	;不是只要进入队列了就开始检查逻辑开关,要在刚要开始理发的时候再看。
			seize		f_bar
			depart		f_bar
			advance		15,7
...
out			terminate

            generate	240,,,1	;用一个实体来直接完成计时和程序终止
            LOGIC S		2	;12点关门了(吃饭的逻辑开关2)
            advance		60	;吃饭1小时
            LOGIC S		2	;开门
            advance		240	;辛苦工作到傍晚
            logic r		1	;是时候关门了(下班的逻辑开关1)
            test e		n$add_jr,n$add_done	;进入人数和完成人数相等
            terminate	1	;控制实体被终结了
            start		1