数据结构队列C++应用:模拟银行排队系统(下)

2010年3月25日 Yarkee 没有评论

接上文……

main.cpp的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <iostream>
#include<vector>
#include <queue>
#include <time.h>
#include<iomanip>
#include "customer.h"
using namespace std;
const int CASHIERS = 5; //设置5个窗口
 
void simulate(int cashiers, double prob_of_arrival, int service_time, int last_time);
 
int main()
{
    int cashiers=CASHIERS;
 
    // 顾客的到达概率
    double prob_of_arrival;
 
    // 每名顾客接受服务所需的时间
    int service_time;
 
    // 程序模拟持续的总时间
    int last_time;
 
    cout << "***********************模拟银行排队系统***********************\n" << endl;
    cout << "请输入每分钟内顾客的到达概率(概率应介于0和1之间): ";
    cin >> prob_of_arrival ;
    cout << "请输入每个顾客接受服务所需要的时间(时间单位:分): ";
    cin >> service_time;
    cout << "请输入银行的工作总时间(时间单位:分): ";
    cin >> last_time;
    cout << endl;
 
    // 调用函数,仿真银行运行情况
    simulate(cashiers, prob_of_arrival, service_time, last_time);
 
    system("pause");
    return 0;
}
 
void simulate(int cashiers, double prob_of_arrival, int service_time, int last_time)
{
// 用于存储顾客信息
Customer customer;
 
//5个Window的对象,分别对应5个窗口
Window Wnd[5];
 
// 顾客排队队列
queue<Customer> wait_queue;
 
// 接受了服务的顾客总数
int served_customers; 
 
// 存储每个顾客的等待时间
vector<int> wait_time; 
 
// 总共的服务时间
int total_wait_time = 0; 
 
// 随机数种子
srand(time(NULL));
 
// 随机数
double rand_num;
int count;
 
//用于给顾客编号,每来一位顾客就顺序加1
int ticket=0;
 
// 对每个窗口的时间和处理顾客数进行初始化
for (count = 0; count < cashiers; ++count){
    //cashier_vacant[count] = 0;
    //cashier_customer[count]=0;
    Wnd[count].set_cashier_vacant(0);
    Wnd[count].set_cashier_customer(0);
}
 
//开始仿真,一个单位时间扫描一次
for ( int t = 0; t < last_time; ++t){
 
    // 小于到达概率,表示说明顾客到达,顾客入队
    if ((rand_num = (rand()%100)/100.0 )<= prob_of_arrival){
        customer.set_arrival_time(ticket++,t);
        wait_queue.push(customer);
    }
 
    cout<<"****************第"<<t+1<<"个时间单元******************"<<endl;
 
    // 对窗口进行逐一扫描,判断其是否有空闲, 并且判断队列是否非空
    for(count=0;count<cashiers;++count){
        //if ((cashier_vacant[count]>t)){
        if(Wnd[count].get_cashier_vacant()>t){
            cout<<"第"<<count+1<<"号窗口正在为第"<< Wnd[count].get_cashier_ticket()+1<<"号顾客服务…"<<endl;
        }
    }
    for (count=0;count<cashiers;++count){
 
        if( (Wnd[count].get_cashier_vacant()<=t) && !wait_queue.empty() && (Wnd[count].get_cashier_vacant()<last_time)){
        // 顾客得到服务
            customer = wait_queue.front();
            wait_queue.pop();
 
            Wnd[count].set_cashier_customer( Wnd[count].get_cashier_customer()+1 );
            Wnd[count].set_cashier_ticket(customer.get_ticket_num());
 
            // 设置顾客离去时间
            customer.set_departure_time(t);
 
            // 顾客等待时间
            wait_time.push_back( t - customer.get_arrival_time());
 
            //所有已服务顾客等待所花费的总时间
            total_wait_time += customer.total_time();
 
            // 设置该窗口的下一个空闲时刻
            Wnd[count].set_cashier_vacant( t+service_time );
            cout<<"第"<<customer.get_ticket_num()+1<<"号顾客请到第"<<count+1<<"号窗口办理业务,您所花费的等待时间为"
                << t - customer.get_arrival_time()<<"分钟!"<<endl;
 
        }//end if
    }// end for
    cout<<"目前共有"<<wait_queue.size()<<"位顾客正在排队等待…"<<endl<<endl;
}// end for
 
cout<<"*******已下班,剩余顾客明天请早,不便之处,敬请原谅*******"<<endl<<endl;
 
// 接受了服务的顾客总数
served_customers = wait_time.size();
 
double average_wait_time =(double)total_wait_time/served_customers ;
 
// 输出统计结果
cout<<"*****************今日银行工作情况总结*********************"<<endl;
for(count=0;count<cashiers;count++){
    cout<<"第"<<count+1<<"号窗口接待的顾客数为"<<Wnd[count].get_cashier_customer()<<"名"<<endl;
}
cout<<endl;
cout << "得到服务的顾客数为"<< served_customers << "名"<<endl;
cout << "得到服务的顾客所需要的平均等待时间为" << setprecision(2)<<average_wait_time<<"分钟"<< endl;
cout << endl;
return 0;
}
分类: 编程 标签: ,

数据结构队列C++应用:模拟银行排队系统(上)

2010年3月25日 Yarkee 没有评论

前几天做的一个数据结构课程的作业,题目要求如下图:

在做之前,有参考网上的一份有点相似的代码,所以有些变量的命名就没有自己想了。程序分为两个文件,一个是头文件customer.h,该头文件中包含和所需要的类的声明和定义,另外一个是main.cpp文件,即主程序文件。写了比较详细的注释,应该能让读者比较好理解。

customer.h文件中的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#ifndef CUSTOMER_H_
#define CUSTOMER_H_
 
class Customer{
public:
    // 设置到达时刻
    void set_arrival_time(int ticket,int arrives)
    {
        ticket_num=ticket;
        arrival_time = arrives;
    }
 
    //读出到达队列的时刻
    int get_arrival_time() const
    {
        return arrival_time;
    }
 
    // 设置离开队列的时刻
    void set_departure_time(int departs)
    {
        departure_time = departs;
    }
 
    // 求出等待的时间
    int total_time()
    {
        return departure_time - arrival_time;
    }
 
    //返回顾客编号
    int get_ticket_num()
    {
        return ticket_num;
    }
 
private:
    int ticket_num,arrival_time, departure_time;
};
 
class Window{
public:
    //存储该窗口处理的顾客数
    void set_cashier_customer(int num)
    {
        cashier_customer=num;
    }
 
    //读取该窗口处理的顾客数
    int get_cashier_customer()
    {
        return cashier_customer;
    }
 
    //存储该窗口正在服务的顾客编号
    void set_cashier_ticket(int num)
    {
        cashier_ticket=num;
    }
 
    //读取该窗口正在服务的顾客编号
    int get_cashier_ticket()
    {
        return cashier_ticket;
    }
 
    //设置该窗口的下一个空闲时刻
    void set_cashier_vacant(int num)
    {
        cashier_vacant=num;
    }
    //读取该窗口的下一个空闲时刻
    int get_cashier_vacant()
    {
        return cashier_vacant;
    }
 
private:
    //该窗口一共服务的顾客数
    int cashier_customer;
 
    //该窗口当前服务的顾客的编号
    int cashier_ticket;
 
    //该窗口的空闲时刻
    int cashier_vacant;
};
#endif



未完待续……

分类: 编程 标签: ,

世界上最美丽的十个公式

2010年3月25日 Yarkee 没有评论

世界上最美丽的十个公式

英国科学期刊《物理世界》曾让读者投票评选了“最伟大的公式”,最终榜上有名的十个公式既有无人不知的1+1=2,又有著名的E=mc2;既有简单的圆周公式,又有复杂的欧拉公式……
从什么时候起我们开始厌恶数学?这些东西原本如此美丽,如此精妙。这个地球上有多少伟大的智慧曾耗尽一生,才最终写下一个等号。每当你解不开方程的时候,不妨换一个角度想,暂且放下对理科的厌恶和对考试的痛恨。因为你正在见证的,是科学的美丽与人类的尊严。

No.10 圆的周长公式(The Length of the Circumference of a Circle)


这公式贼牛逼了,初中学到现在。目前,人类已经能得到圆周率的2061亿位精度。还是挺无聊的。现代科技领域使用的圆周率值,有十几位已经足够了。如果用35位精度的圆周率值,来计算一个能把太阳系包起来的一个圆的周长,误差还不到质子直径的百万分之一。现在的人计算圆周率,多数是为了验证计算机的计算能力,还有就是为了兴趣。

 
No.9 傅立叶变换(The Fourier Transform)

这个挺专业的,一般人完全不明白。不多作解释。简要地说没有这个式子没有今天的电子计算机,所以你能在这里上网除了感谢党感谢政府还要感谢这个完全看不懂的式子。另外傅立叶虽然姓傅,但是法国人。

 
No.8 德布罗意方程组(The de Broglie Relations)


这个东西也挺牛逼的,高中物理学到光学的话很多概念跟它是远亲。简要地说德布罗意这人觉得电子不仅是一个粒子,也是一种波,它还有 “波长”。于是搞啊搞就有了这个物质波方程,表达了波长、能量等等之间的关系。同时他获得了1929年诺贝尔物理学奖。

 
No.7 1+1=2
这个公式不需要名称,不需要翻译,不需要解释。

 
No.6 薛定谔方程(The Schrödinger Equation)

也是一般人完全不明白的。因此我摘录官方评价:“薛定谔方程是世界原子物理学文献中应用最广泛、影响最大的公式。”由于对量子力学的杰出贡献,薛定谔获得1933年诺贝尔物理奖。
另外薛定谔虽然姓薛,但是奥地利人。

阅读全文…

猴子实验:关于道德、阶级、信仰与爱情(下)

2010年3月21日 Yarkee 1 条评论


接上文……


五:信仰的起源

5只猴子A B C D E3个阶级快乐的生活了很久。他们精确的给出了3个阶级的定义,即吃香蕉阶级,拿香蕉阶级和干看着阶级。可惜猴子A由于长期水中作业无可避免的引发了它肺部功能的衰竭。
一天,他在例行的拿香蕉作业中跌倒后就再也没有爬起来。于是,实验人员又送进了一只同样孔武有力的猴子F。当然,它还是对屋顶的香蕉很有兴趣。不幸的是,它最终以微弱的劣势被以C为首的猴群再次海K。
第二天,又到了拿香蕉的时候,C很无所谓,反正它还是要吃香蕉,而且不会被水淋到。真正恐慌的是B D E三只猴子。他们心想,F猴是那么的强壮,他们这些媳妇是熬不成婆了。他们将面临一个艰难的抉择——该谁去步A的后尘。
猴子B D E展开了激烈的争论,讨论谁应该做下一个拿香蕉阶级。猴子F很好奇,什么叫“拿香蕉阶级”呢?猴子B D E结实:所谓“拿香蕉阶级”,就是猴子界勇敢者的阶级,需具备一不怕苦二不怕死的大无畏精神方能得此殊荣。F闻听不禁跃跃欲试。当然它最终达到了目的,作了唯一的拿香蕉阶级。
再猴子B D E三猴陆续被换出局,换来的猴子个个强健如C,他们继续大大出手,不过目标不是香蕉,而是那个唯一的拿香蕉阶级。于是信仰也就出现了。


六:迷信的起源
后来,A终于被好心的实验人员拉出了苦海。新来了猴子F。C觉得有必要维护自己的阶级地位,B D E则生怕顶了A的缸。在各种复杂心情的作用下,B D E在C的带领下爆扁了F一顿,然后强另F做拿香蕉阶级。F开始不乐意,后来慢慢在B等的劝说下,等待“多年的媳妇熬成婆”这一宿命。
慢慢的,老资格的B D E猴子渐渐被淘汰,C发现自己在体力上不再占优势,很难通过武力让这一游戏规则继续下去,觉得十分苦恼。这时,一只最有希望升级为吃香蕉阶级(既C的理所当然接班人)的猴子,也是C谋臣的H向C进言,于是君臣之间商量出一个计谋。
按照君臣定计,H开始依靠自己多懂的几种猴语而在其他若干猴子面前树立的权威形象,向其他猴鼓吹:“每一只新来笼子的猴子都是有罪的,这种罪责来自血统……只有摘香蕉的猴子才能被(实验人员)送到天堂。”
事实上,因为被水冲容易的肺炎病倒而被实验人员淘汰,但猴子们不知道,反而以为被淘汰的猴子真的进了天堂。
渐渐地,猴子们都相信了这套理论,并讲给每只新猴子听,就这么流传下去越传越神。以至于后来摘香蕉阶级的猴子为了能摘到香蕉而大打出手……这是C没有想到的,H没有看到的,那时他们都已死了。然而迷信就这么诞生了。


七:爱情的起源
后来,实验人员放进去了一只雌性的猴子I。第一天晚上C就以头领的身风占有了I。处于第二阶级的B D E敢怒不敢言。而I也因而接受了她的新身份,分享着自己用身体换来的香蕉和冲凉的权利。
直到有一天,她对唯一的拿香蕉阶级F产生了兴趣,所有关于HERO的传奇和天堂的传说都满足不了I强烈的好奇心。于是在C B D E四只猴子都在水足香蕉饱之后沉沉睡去的夜里,I开始了和F的接触。在雌性动物特有的温柔天赋的作用下,寒夜中冻的瑟瑟发抖的F不禁牵起了一中I从未有过的感受。极尽温柔的用雌性的天赋抚慰F身心的创伤。
从那以后的每一次冲凉和吃香蕉的时候,I总是悄悄的注视着受难的F,悄悄的心疼着,然后每一个深夜,I继续用自己的方式治愈着F。终于有一天,I和F把熟睡中的C杀死,而早已被平静的生活惰化的B D E则根本没有反抗的意思。F顺理成章的成为了新的王者。
这就是爱情的起源,一种产生于重重压迫之下,发自异性之间的好奇心的具有巨大得足以改朝换代的力量的化学反应。


八:脆弱的爱情
由于C的以外死亡和鉴于I的进入而产生的新变化,实验人员决定再放入三只雌性猴子以平衡需求,同时也把笼子扩建成为拥有好几个不同隔离间的复合试结构。
三只新加入的猴MM自然大受欢迎,在没有发生任何争执的情况下被B D E和平瓜分了,之后的日子安静祥和。直到B D E渐渐年老体衰,以及实验人员放入除香蕉之外的不同种类的水果之后,事态发生了变化。
导火索是E试图用属于自己的那只猴MM去讨好F,以换取一颗杨桃,这项交易在还没有开始的时候,就被I撞破终止了。但是I和F的夫妻矛盾却因此而展开,雪上加霜的是,E的尝试同时也提醒了B和D,于是一次又一次的秘密交易在暗中酝酿。而无辜的F却不得不I三天一小吵五天一大闹的思想教育。
终于在正反两股力量的作用下,F有了第一次的越轨行为。接下去的状况一发不可收拾,B D E用他们各自的猴MM换取他们想要的各种水果。而F则在I的疲劳攻势之外得到自己的安慰,代价仅仅是他早就不感兴趣的东西。
这种日子并没持续多久,终于I在郁郁寡欢中一睡不醒,而F也因过度操劳而去了天堂。剩下三只已没有研究价值的老公猴和三只欲望过剩而无处发泄的猴MM……


最后这项以猴子作为对象的实验被彻底终止了,这项实验做出的最后一个贡献是,它证明了爱情的不可考验性——爱情只能存在于需要面对巨大压力的艰苦岁月。
爱情,是经不起现实考验的,很脆弱,很虚弱。爱是性欲催促出来的急迫感情和活动,为了稳定和固定这种感情活动而上升到社会法律高度。


猴子实验:关于道德、阶级、信仰与爱情(上)

2010年3月21日 Yarkee 没有评论


这是一个有趣的实验,对象是猴子。


一:道德的起源
科学家将5只猴子关在密闭的房间里,每天喂很少的事物,让猴子饿的吱吱叫。几天后,实验者在房间上面的小洞放下一串香蕉,并装了个自动装置,一旦侦测到有猴子要拿香蕉,马上就会有水喷下,这5只猴子都会一身湿。
一只饿得头昏眼花的大猴子一个箭步冲向香蕉,可是没等它拿到香蕉,这5只猴子就被欲设机关所喷出的水淋湿了。当后面4只猴子依次爬上去拿香蕉时,发现莫不如此。于是,众猴子只好望蕉兴叹,它们达成一个共识:不要去拿香蕉,以避免被水喷到。
几天后实验人员把其中一只猴子释放,换进去一只新猴子A。当新猴子A肚子饿得也想去吃香蕉时立刻被其他4只老猴子海K了一顿。因为其他4只猴子认为A会害他们被水淋到,所以制止它去拿香蕉。A尝试了几次,虽被打的满头包,依然没有拿到香蕉。当然这5只猴子没有被水喷到。
后来实验人员再把一只旧猴子释放,换上另一只新猴子B。这猴子B看到香蕉,也是迫不及待要去拿。淡然,一如刚才所发生的情形,其他4只猴子海K了B一顿。特别的是,那只A猴子打的特别用力。B猴子试了几次总是被揍的很惨,只好作罢。
最后,所有的旧猴子逐渐换成了新猴子,但大家都不敢去动香蕉,虽然他们不知道为什么,只知道去动香蕉会被别的猴子痛扁。
在这个实验中,猴子们产生了“道德”。如果这群猴子构成一个社,它们也繁衍下一代,它们也会将它们的经历告诉下一代,渐渐的,猴子们便认为取香蕉的后果会对其他猴子利,从而认为取香蕉是“不道德的”,它们也会自动惩罚“不道德的”猴子。当然,这个实验也反映了人类道德的产生过程。


二:阶级的起源
实验人员继续他们的实验,不过这次他们改变了喷水装置。一旦侦测到有猴子拿香蕉,马上有水喷向拿香蕉的猴子,而非全体。
然后,实验人员又把其中的一只猴子释放,换进一只新的猴子C。不同以往的是,猴子C特别的孔武有力。当然,猴子C看到香蕉,也马上想要去拿。一如以前所发生的起行,其他四只猴子想海K猴子C一顿,不过,他们错误估计了C的实力,所以结果是反被C海K了一顿。于是,猴子C拿到了香蕉,当然也被淋了个湿透。C一边打着喷嚏,一边吃着香蕉,美味但是也美中不足。
A B D E没有香蕉吃,但也比较快乐,毕竟没被水淋到嘛。后来,C发现只有拿香蕉的猴子才会被淋到,就要求最弱小的A替它拿香蕉。A不想被K,只好每天拿香蕉 被水淋。
B D E越发快乐起来,这就叫比上不足 比下有余嘛!于是,5只猴子有了三个阶级。这样一来,阶级就产生了。
而人类社会的阶级无疑是从动物社会这种等级差别中发展而来的,所以,原始社会不可能是没有阶级的社会。当然,原始社会的阶级及社会丑恶现象对现代来说是一种低级的,原始的。人类从灵长动物中进化而来,可以肯定的说,人类社会的阶级就是从动物社会的等级中发展而来的。


三:道德的沦丧
实验人员进行的有关猴子的研究仍在继续。天变热了,笼子里的猴子们想冲凉却找不到地方,终于出现了一位反潮流英雄——猴子HERO。
HERO无意中碰到香蕉,理所当然引来一顿暴打。但在挨打过程中,猴子门享受到了冲凉的乐趣。等圣上的水干了,猴子A无意中碰撞了HERO,使HERO再次接触到了香蕉,于是,猴子们享受了第二次冲凉,HERO遭到了第二次痛殴。
此后,只要大家有冲凉的需要,就会有一只猴子挺身而出,对HERO进行合理冲撞。大家对HERO的态度也有了明显的不同,平时大家会对HERO异常温和,以弥补在冲凉时为维护规则而不得不对它进行的暴力举动。
一天,在大家冲凉时,饱受折磨的HERO闻到了香蕉的清香,生物本能使它在别的猴子心有旁骛时将香蕉吃了。而且此后没有了新的香蕉来填补空缺。猴子们陷入了另一个尴尬境地:没有冲凉的水,也没有香蕉,只有HERO。
于是另一个规则形成了。猴子们在烦躁的时候会痛打HERO出气,HERO不得反抗。当笼子里的旧猴子被新猴子换掉时,新猴子会在最快的时间内学会殴打HERO。
终于有一天,老天开眼,历尽沧桑的HERO被另一只猴子代替了。猴子们失去了发泄对象,只能任意选取一个目标攻击。此后,笼子里的猴子们不吃不喝不冲凉,唯一的举动就是打架。这就是道德的沦丧。


四:道德的重建
实验人员对猴子们的斗争不休感到不安。为了重建道德秩序,他们决定继续供应香蕉。一天,正在混战的猴子们发现头顶多了一串香蕉,A不顾身上的剧痛,把香蕉摘了下来。于是久违的甘露出现了,未曾尝过甜头的猴子们先是茫然失措,继而争先恐后的加入冲凉的行列,香蕉反而被遗忘了。
当猴子B C D E发现A在享受沐浴的同时还吃着美味的香蕉。嫉妒心使他们暂时团结起来,共同K了A一顿,将A吃剩的香蕉夺过来。但此刻的香蕉成了匹夫怀里的宝玉,得到它的猴子虽能享受美味,但付出的代价也是巨大的。
实验人员不断放入香蕉,却发现战斗比以前更激烈了。分析清楚原因后,他们用木头做了一个假香蕉放进了笼子。此时猴子们已经学聪明了,它们知道触摸香蕉可以享受淋浴,而试图独占香蕉则会遭到痛扁。
于是,一个新的现象出现了,当猴子有冲凉需要时,会有一只猴子将香蕉拿起来。当它发现有遭到攻击的可能时,会马上放下香蕉逃到一边去。这样,猴子都能冲凉,但又不至于像以前那样N败俱伤。没有猴子发现哪个香蕉是假的。
(未完待续…)



WP SlimStat