当前位置: 首页 > 工具软件 > Barbecue > 使用案例 >

barbecue

袁飞鹏
2023-12-01

#include "barbecue.h"
#include <iostream>

void barbecue::add_guest(int arrival)
{
	guest* gst = new guest(this, arrival);
	_schedule_table.push(gst);
}

void barbecue::serve_guest(guest* gst)
{
	_schedule_table.push(gst);
}

void barbecue::schedule()
{
	while (!_schedule_table.empty())
	{
		guest* gst = _schedule_table.top();
		_schedule_table.pop();
		//根据客人的当前状态,进行服务
		//1.客人在烧烤完毕后,进入FINISHED状态
		//释放一个烤架,将客人请至用餐区
		if (gst->_current_state == FINISHED)
		{
			_grill->release(gst->_res_idx);
			_dining_area.push_back(gst);
			std::cout << gst->_timestamp << " finished" << std::endl;
		}
		//2.客人在用完一次吧台后,进入下一状态;烧烤店释放一个吧台
		else if (gst->_current_state == FREEBAR)
		{
			_bar->release(gst->_res_idx);
			gst->moveto(-1, nextschedule());
		}
		//3.客人在等待吧台,如果有可用的吧台,则客人获取资源,并转换状态
		//否则,客人的时间戳修改为下一个调度时间,以期待最近一次调度时间有机会获取资源
		else if (gst->_current_state == WAITING4BAR)
		{
			int bar_idx = _bar->apply(gst->_timestamp + 10);
			gst->moveto(bar_idx, _bar->min());
		}
		else if (gst->_current_state == WAITING4GRILL)
		{
			int grill_idx = _grill->apply(gst->_timestamp + 180);
			gst->moveto(grill_idx, _grill->min());
		}
	}
}

void barbecue::statistics()
{
	int totaltime4bar = 0;
	int totaltime4grill = 0;
	int count = 0;
	for (std::list<guest*>::iterator iter = _dining_area.begin(); iter != _dining_area.end(); iter++)
	{
		count++;
		totaltime4bar += (*iter)->_time4bar;
		totaltime4grill += (*iter)->_time4grill;
	}
	double average4bar = totaltime4bar / 1.0 / count;
	double average4grill = totaltime4grill / 1.0 / count;
	std::cout << "平均等待吧台的时间: " << average4bar << std::endl;
	std::cout << "平均等待烤架的时间: " << average4grill << std::endl;
}

//下一个最近的调度时间
int barbecue::nextschedule()
{
	if (!_schedule_table.empty())
	{
		return _schedule_table.top()->_timestamp;
	}
	return LONG_MAX;
}

bool barbecue::use_one_bar()
{
	if (_bar_num > 0)
	{
		_bar_num--;
		return true;
	}
	return false;
}

bool barbecue::use_one_grill()
{
	if (_grill_num > 0)
	{
		_grill_num--;
		return true;
	}
	return false;
}

void barbecue::free_one_bar()
{
	_bar_num++;
}

void barbecue::free_one_grill()
{
	_grill_num++;
}

void guest::moveto(int res_idx, int newtime)
{
	switch (_current_state)
	{
	case FREEBAR:
		//获取食物未到5份,则继续申请吧台,添加到烧烤店的服务队列中
		if (_food_num < 5)
		{
			_time_in_current_state = 0;
			_current_state = WAITING4BAR;
			_barbecue->serve_guest(this);
		}
		//获取完食物,申请烤架进行烧烤
		else
		{
			_current_state = WAITING4GRILL;
			_time_in_current_state = 0;
			_barbecue->serve_guest(this);
		}
		break;
	case WAITING4BAR:
		//获取到资源,WAITING4BAR=>USINGBAR=>FREEBAR
		if (res_idx != -1)
		{
			_time4bar += _time_in_current_state;
			_timestamp += 10;
			_current_state = FREEBAR;
			_time_in_current_state = 0;
			_res_idx = res_idx;
			_food_num++;
			_barbecue->serve_guest(this);
		}
		else
		{
			_time_in_current_state += newtime - _timestamp;
			_timestamp = newtime;
			_barbecue->serve_guest(this);
		}
		break;
	case WAITING4GRILL:
		//获取到资源,WAITING4GRILL=>USINGGRILL=>FINISHED
		if (res_idx != -1)
		{
			_time4grill += _time_in_current_state;
			_timestamp += 180;
			_current_state = FINISHED;
			_time_in_current_state = 0;
			_res_idx = res_idx;
			_barbecue->serve_guest(this);
		}
		else
		{
			_time_in_current_state += newtime - _timestamp;
			_timestamp = newtime;
			_barbecue->serve_guest(this);
		}
		break;
	}
}

#ifndef __BARBECUE_H__
#define __BARBECUE_H__
#include <queue>
#include <list>
//客人状态
enum guest_state
{
	FINISHED,
	FREEBAR,
	USINGBAR,
	USINGGRILL,
	WAITING4BAR,
	WAITING4GRILL
};

class barbecue;

//资源类
//向用户提供获取资源,释放资源接口
class resource
{
public:
	resource(int size)
	{
		_resources = new int[size];
		for (int i = 0; i < size; i++)
			_resources[i] = LONG_MAX;
		_size = size;
		_minValue = LONG_MAX;
	}
	~resource()
	{
		delete [] _resources;
	}
public:
	//申请资源,并提供释放资源的时间,成功申请返回bar的编号,否则返回-1
	int apply(int time)
	{
		for (int i = 0; i < _size; i++)
			if (_resources[i] == LONG_MAX)
			{
				_resources[i] = time;
				_minValue = _minValue > time ? time : _minValue;
				return i;
			}
		return -1;
	}
	void release(int idx)
	{
		_resources[idx] = LONG_MAX;
		_minValue = LONG_MAX;
		for (int i = 0; i < _size; i++)
		{
			_minValue = _minValue > _resources[i] ? _resources[i] : _minValue;
		}
	}
	//在_bars数组中储存bar的释放时间,getMin返回最近一次吧台释放时间
	int min()
	{
		return _minValue;
	}
private:
	int* _resources;
	int _size;
	int _minValue;
};

//每一个客人有以下信息:
//1.当前状态
//2.当前状态的维持时间
//3.累计等待吧台时间
//4.累计等待烤架时间
//5.进入烧烤店的时间
//6.时间戳,记录被招待时的时间
class guest
{
public:
	guest(barbecue* bbq, int arrival)
	{
		_current_state = WAITING4BAR;
		_time_in_current_state = 0;
		_time4bar = _time4grill = 0;
		_timestamp = _arrival = arrival;
		_barbecue = bbq;
		_food_num = 0;
		_res_idx = -1;
	}
public:
	friend class barbecue;
	bool finished() { return _current_state == FINISHED; }
	void moveto(int res_idx, int newtime);
private:
	barbecue* _barbecue;
	guest_state _current_state;
	int _time_in_current_state;
	int _food_num;   //当前获取了几份食物
	int _time4bar;
	int _time4grill;
	int _arrival;
	int _timestamp;
	int _res_idx; //当前获取的资源编号
};

class barbecue
{
public:
	//初始化20个吧台,8个烤架,时间戳为0
	barbecue()
	{
		_bar_num = 20;
		_bar = new resource(20);
		_grill = new resource(8);
		_grill_num = 8;
	}
	~barbecue()
	{
		for (std::list<guest*>::iterator iter = _dining_area.begin(); iter != _dining_area.end(); iter++)
		{
			delete (*iter);
		}
		while (!_schedule_table.empty())
		{
			guest* gst = _schedule_table.top();
			_schedule_table.pop();
			delete gst;
		}
		delete _bar;
		delete _grill;
	}
public:
	//添加客人
	void add_guest(int arrival);
	//服务客人
	void serve_guest(guest* gst);
	//对先前添加的客人,进行服务,直到客人都烧烤完
	void schedule();
	void statistics();
private:
	//释放烤架
	void free_one_grill();
	//释放吧台
	void free_one_bar();
	//申请使用烤架
	bool use_one_grill();
	//申请使用吧台
	bool use_one_bar();
	//下一个最近的调度时间
	int nextschedule();

private:
	struct cmp
	{
		bool operator()(const guest* a, const guest* b)
		{
			if (a->_timestamp == b->_timestamp) return a->_current_state > b->_current_state;
			return a->_timestamp > b->_timestamp;
		}
	};
	std::priority_queue<guest*, std::vector<guest*>, cmp> _schedule_table;
	std::list<guest*> _dining_area;
	int _grill_num;
	resource* _grill;
	resource* _bar;
	int _bar_num;
};

#endif


 类似资料:

相关阅读

相关文章

相关问答