这是华师大算法课上的最后一个练习题目。C++版本。可运行。
一. 代码
#include <iostream>
#include <cstdlib>
#include <queue>
#include<time.h>
#include<cmath>
#define RUN_WAY_H
#define RUN_WAY_H
#define PLANE_H
#define PLANE_H
using namespace std;
// 枚举飞机状态
enum Plane_status { null, arriving, departing };
class Random {
public:
Random(bool pseudo = true);
double random_real();
int random_integer(int low, int high);
int poisson(double mean);
// void randomByAvg(double avg,int num);
private:
int reseed(); // Re-randomize the seed.
int seed,multiplier,add_on;
// constants for use in arithmetic operations
};
Random::Random(bool pseudo)
/*
Post: The values of seed, add_on, and multiplier are
initialized. The seed is initialized randomly only if pseudo == false.
*/
{
if (pseudo) seed = 1;
else seed = time(NULL) % INT_MAX;
multiplier = 2743;
add_on = 5923;
}
int Random::reseed()
/*
Post: The seed is replaced by a pseudorandom successor.
*/
{
seed = seed * multiplier + add_on;
return seed;
}
double Random::random_real()
/*
Post: A random real number between 0 and 1 is returned.
*/
{
double max = INT_MAX + 1.0; //INT_MAX = (2)31 -1
double temp = reseed();
if (temp < 0) temp = temp + max;
return temp / max;
}
int Random::random_integer(int low, int high)
/*
Post: A random integer between low and high is returned.
*/
{
if (low > high) return random_integer(high, low);
else return ((int) ((high - low) * random_real())) + low;
}
int Random::poisson(double mean)
/*
Post: A random integer, reflecting a Poisson distribution
with parameter mean, is returned.
*/
{
double limit = exp(-mean);
double product = random_real();
int count = 0;
while (product > limit) {
count++;
product *= random_real();
}
return count;
}
// 飞机类定义
class Plane
{
public:
Plane();
Plane(int flt, int time, Plane_status status);
void refuse() const;
void land(int time) const;
void fly(int time) const;
int started() const;
protected:
int flt_num;
int clock_start;
Plane_status state;
};
Plane::Plane(int flt, int time, Plane_status status)
// 飞机的数据
{
flt_num = flt;
clock_start = time;
state = status;
cout << "Plane number " << flt << "ready to: ";
if (status == arriving)
cout << "land." << endl;
else
cout << "take off" << endl;
}
Plane::Plane()
// 飞机默认构造函数
{
flt_num = -1;
clock_start = -1;
state = null;
}
void Plane::refuse() const
// 当队列满时,处理一架等待使用跑道的飞机
{
cout<<time << ":Plane number " << flt_num;
if (state == arriving)
cout << "directed to another airport.\n";
else
cout << "told to try to takeoff again later.\n";
}
void Plane::land(int time) const
// 处理一架着陆的飞机
{
int wait = time - clock_start;
cout << time << ": Plane number " << flt_num << " landed after "
<< wait << " time unit" << ((wait == 1)? "": "s")
<< " in the takeoff queue." << endl;
}
void Plane::fly(int time) const
// 处理一架将要在某一时间起飞的飞机
{
int wait = time - clock_start;
cout << time << ": Plane number " << flt_num << " takeoff after "
<< wait << " time unit" << ((wait == 1)? "" : "s")
<< " in the takeoff queue." << endl;
}
int Plane::started() const
// 返回飞机到达机场的时间
{
return clock_start;
}
// 枚举跑到状态
enum Runway_activity { idle, land, take_off };
enum Error_code { success, fail };
// 跑道类
class Runway
{
public:
Runway(int limit);
Error_code can_land(const Plane ¤t);
Error_code can_depart(const Plane ¤t);
Runway_activity activity(int time, Plane &moving);
void shut_down(int time) const;
protected:
queue<Plane> landing;
queue<Plane> takeoff;
int queue_limit;
// 亲求着陆的飞机数量
int num_land_requests;
// 请求起飞的飞机数量
int num_takeoff_requests;
// 已经着陆的飞机数量
int num_landings;
// 已经起飞的飞机数量
int num_takeoffs;
// 在着陆队列里的数量
int num_land_accepted;
// 在起飞队列里的数量
int num_takeoff_accepted;
// 被拒绝着陆的飞机数量
int num_land_refused;
// 被拒绝起飞的飞机数量
int num_takeoff_refused;
// 飞机等待着陆的时间
int land_wait;
// 飞机等待起飞的时间
int takeoff_wait;
// 跑道空闲总时间
int idle_time;
};
void run_idle(int time);
void initialize(int &end_time, int &queue_limit,
double &arrival_rate, double &departure_rate);
Runway::Runway(int limit)
// 初始化Runway的数据成员
{
queue_limit = limit;
num_land_requests = num_takeoff_requests = 0;
num_landings = num_takeoffs = 0;
num_land_refused = num_takeoff_refused = 0;
num_land_accepted = num_takeoff_accepted = 0;
land_wait = takeoff_wait = idle_time = 0;
}
Error_code Runway::can_land(const Plane ¤t)
// 当前的这架飞机被添加到着陆队列,否则,返回异常.
// Runway类的数据被更新
{
Error_code result;
if (landing.size() < queue_limit)
{
result = success;
landing.push(current);
}
else
result = fail;
num_land_requests++;
if (result != success)
num_land_refused++;
else
num_land_accepted++;
return result;
}
Error_code Runway::can_depart(const Plane ¤t)
// 当前飞机被添加到起飞队列.否则,返回异常.
// Runway类的数据被更新
{
Error_code result;
if (takeoff.size() < queue_limit)
{
result = success;
takeoff.push(current);
}
else
result = fail;
num_takeoff_requests++;
if (result != success)
num_takeoff_refused++;
else
num_takeoff_accepted++;
return result;
}
Runway_activity Runway::activity(int time, Plane &moving)
/*
* 如果着陆队列有进入权,它的头部的飞机被赋值到moving参数
* land的消息将被返回.
* 否则, 如果起飞队列有进入权,它的头部飞机被赋值到moving参数
* takeoff消息将被返回
* 否则, idle消息被返回
* Runway类数据被更新
*/
{
Runway_activity in_progress;
if (!landing.empty())
{
moving = landing.front();
land_wait += time - moving.started();
num_landings ++;
in_progress = land;
landing.pop();
}
else if (!takeoff.empty())
{
moving = takeoff.front();
takeoff_wait += time - moving.started();
num_takeoffs++;
in_progress = take_off;
takeoff.pop();
}
else
{
idle_time++;
in_progress = idle;
}
return in_progress;
}
void Runway::shut_down(int time) const
// 跑道的使用概况
{
cout << "Simulation has conluded after " << time << " time units."
<< endl;
cout << "Total number of planes processed "
<< (num_land_requests + num_takeoff_requests) << endl;
}
void run_idle(int time)
// 当机场空闲时打印出时间信息
{
cout << time << ": Runway is idle." << endl;
}
void initialize(int &end_time, int &queue_limit,
double &arrival_rate, double &departure_rate)
// 初始化数据
{
cout << "This program simulates an airport with only a runway." << endl
<< "One plane can land to depart in each unit of time." << endl
<< "Up to what number of planes can be waiting to land "
<< "or take off at any time? " << flush;
cin >> queue_limit;
cout << "How many units of time will the simulation run? " << flush;
cin >> end_time;
bool acceptable;
do
{
cout << "Expected number of arrivals per unit time? " << flush;
cin >> arrival_rate;
cout << "Expected number of departures er unit time?" << flush;
cin >> departure_rate;
if (arrival_rate < 0.0 || departure_rate < 0.0)
cerr << "These rates must be nonnegative." << endl;
else
acceptable = true;
if (acceptable && arrival_rate + departure_rate > 1.0)
cerr << "Safety Warning: This airport will become saturated." << endl;
}while(!acceptable);
}
int main()
// 测试机场
{
Random random;
// 模拟程序开始运行时间
int end_time;
// 跑到队列的规模
int queue_limit;
int flight_number = 0;
double arrival_rate, departure_rate;
// 初始化
initialize(end_time, queue_limit, arrival_rate, departure_rate);
// 随机数
Runway small_airport(queue_limit);
for(int current_time = 0; current_time < end_time; current_time++)
{
// 这里要产生一个随机数
int number_arrivals = random.poisson(arrival_rate);
for (int i=0; i<number_arrivals; ++i)
{
// 定义飞机对象
Plane current_plane(flight_number++, current_time, arriving);
if (small_airport.can_land(current_plane) != success)
current_plane.refuse();
}
int num_departures =random.poisson(departure_rate);
for(int j=0; j < num_departures; j++)
{
Plane current_plane(flight_number++, current_time, departing);
if (small_airport.can_depart(current_plane) != success)
current_plane.refuse();
}
Plane moving_plane;
switch(small_airport.activity(current_time, moving_plane))
{
case land:
// 着陆
moving_plane.land(current_time);
break;
case take_off:
// 起飞
moving_plane.fly(current_time);
break;
case idle:
// 空闲
run_idle(current_time);
}
}
// 关闭飞机场
small_airport.shut_down(end_time);
return 0;
}
运行结果: