g2000深圳门店最新地址:电梯模拟
来源:百度文库 编辑:杭州交通信息网 时间:2024/04/27 23:59:00
或知道哪里可以下载的请告诉一下
谢谢了,急用!!!
电梯的主要调度策略就是首先响应沿当前行进方向上最远端的请求,当该请求满足后,就可以改变方向了,当无请求时,电梯停在哪里的策略不尽相同。多电梯的调度也比较复杂,下面程序中的调度算法是我自己想的,不一定很好,但基本可以使用了。
程序源码如下:
(注:使用C++ Builder 6.0编译)
//---------------------------------------------------------------------------
#include <vcl.h>
#include <SyncObjs.hpp>
#include <iostream>
#include <string>
#include <vector>
#pragma hdrstop
using namespace std;
int floor_num, elevator_num, elevator_capacity, floor_time, stop_time;
TCriticalSection *lock = NULL;
struct TRequest
{
string name;
int from;
int to;
int elevator;
TRequest(const string &name1, int from1, int to1):
name(name1),from(from1),to(to1)
{
elevator = -1;
}
};
vector<vector<TRequest> > up,down,out;
class TElevator;
vector<TElevator *> elevators;
int select_elevator(const TRequest &req, int exclude_elevator = -1);
void select_elevator_all()
{
int i,j;
for (i = 0; i < up.size(); i++)
for (j = 0; j < up[i].size(); j++)
{
up[i][j].elevator = select_elevator(up[i][j]);
}
for (i = 0; i < down.size(); i++)
for (j = 0; j < down[i].size(); j++)
{
down[i][j].elevator = select_elevator(down[i][j]);
}
}
//---------------------------------------------------------------------------
class TElevator: public TThread
{
public:
int person_num;
int id;
int cur_floor;
int run_time;
int status; //0 - stop, 1 - up, 2 - up stop, 3 - down, 4 - down stop;
bool full()
{
return person_num == elevator_capacity;
}
bool has(const vector<TRequest> &v)
{
for (int i = 0; i < (int)v.size(); i++)
if (v[i].elevator == id)
return true;
return false;
}
bool has_up_requests(int cur_floor)
{
for (int i = cur_floor; i <= floor_num; i++)
{
if (!full() && has(up[i]))
return true;
if (i != cur_floor && (!full() && has(down[i]) || has(out[i])))
{
return true;
}
}
return false;
}
bool has_down_requests(int cur_floor)
{
for (int i = cur_floor; i >= 1; i--)
{
if (!full() && has(down[i]))
return true;
if (i != cur_floor && (!full() && has(up[i]) || has(out[i])))
{
return true;
}
}
return false;
}
bool has_stop_requests(int cur_floor, int status)
{
if (status == 1 && !full() && has(up[cur_floor])
|| status == 3 && !full() && has(down[cur_floor]))
return true;
if (has(out[cur_floor]))
return true;
return false;
}
void process_list(vector<TRequest> &v, const string &action, bool inc_other = false)
{
vector<TRequest> vtmp;
for (int i = 0; i < (int)v.size(); i++)
{
if (inc_other || v[i].elevator == id)
{
if (action == "in")
{
if (!full())
{
cout << "elevator" << id << ": " << v[i].name << " " << action << endl;
v[i].elevator = id;
out[v[i].to].push_back(v[i]);
person_num++;
}
else
{
vtmp.push_back(v[i]);
}
}
else
{
cout << "elevator" << id << ": " << v[i].name << " " << action << endl;
person_num--;
}
}
else
{
vtmp.push_back(v[i]);
}
}
v = vtmp;
}
void process_requests(int cur_floor, int status)
{
if (status == 2 && up[cur_floor].size())
{
process_list(up[cur_floor], "in", true);
}
if (status == 4 && down[cur_floor].size())
{
process_list(down[cur_floor], "in", true);
}
process_list(out[cur_floor], "out");
select_elevator_all();
}
virtual void __fastcall Execute(void)
{
lock->Acquire();
cout << "elevator" << id << ": start at floor " << cur_floor << endl;
for (;;)
{
lock->Release();
Sleep(10);
lock->Acquire();
run_time++;
switch(status)
{
case 0://stop
{
run_time = 0;
break;
}
case 1://up
{
if (run_time >= floor_time)
{
run_time = 0;
cur_floor++;
cout << "elevator" << id << ": arrive floor " << cur_floor << endl;
}
break;
}
case 2://up stop
{
if (run_time >= stop_time)
{
cout << "elevator" << id << ": close door" << endl;
process_requests(cur_floor, status);
run_time = 0;
status = 1;
}
break;
}
case 3://down
{
if (run_time >= floor_time)
{
run_time = 0;
cur_floor--;
cout << "elevator" << id << ": arrive floor " << cur_floor << endl;
}
break;
}
case 4://down stop
{
if (run_time >= stop_time)
{
cout << "elevator" << id << ": close door" << endl;
process_requests(cur_floor, status);
run_time = 0;
status = 3;
}
break;
}
}
if (run_time != 0)
{
if (status == 2 || status == 4)
process_requests(cur_floor, status);
continue;
}
for (;;)
{
bool has_up = has_up_requests(cur_floor);
bool has_down = has_down_requests(cur_floor);
if (has_up && status == 0)
{
status = 1;
}
else if (has_down && status == 0)
{
status = 3;
}
bool has_stop = has_stop_requests(cur_floor,status);
if (has_stop && (status == 1 || status == 3))
{
status++;
cout << "elevator" << id << ": open door" << endl;
process_requests(cur_floor,status);
}
if (!has_up && !has_down && ((status % 2) != 0))
{
status = 0;
}
else if (!has_down && status == 3)
{
status = 1;
}
else if (!has_up && status == 1)
{
status = 3;
}
if (has_stop_requests(cur_floor,status))
continue;
break;
}
}
//lock->Release();
}
TElevator(int id1):id(id1),TThread(true)
{
FreeOnTerminate = true;
person_num = 0;
cur_floor = 1;
run_time = 0;
status = 0; //0 - stop, 1 - up, 2 - up stop, 3 - down, 4 - down stop;
}
__fastcall ~TElevator()
{
lock->Acquire();
cout << "end of elevator..." << endl;
lock->Release();
}
};
int select_elevator(const TRequest &req, int exclude_elevator)
{
int elevator = -1;
int min_weight = -1;
for (int i = 1; i <= elevator_num; i++)
{
int target_floor = req.from;
bool up_direction = (req.from < req.to);
TElevator *p = elevators[i];
bool elevator_up = (p->status == 1 || p->status == 2 || p->status == 0);
bool elevator_down = (p->status == 3 || p->status == 4 || p->status == 0);
bool elevator_stop = ((p->status % 2) == 0);
int elevator_floor = p->cur_floor;
bool need_up = (elevator_floor < target_floor);
int weight;
if (i == exclude_elevator || p->full())
{
weight = 4*floor_num;
}
else if (elevator_floor == target_floor && elevator_stop)
{
weight = -floor_num;
}
else if (p->status == 0)
{
weight = abs(elevator_floor - target_floor) - floor_num;
}
else if (elevator_floor == target_floor)
{
if (elevator_down)
{
weight = elevator_floor + target_floor - 2;
}
else
{
weight = 2*floor_num - (elevator_floor + target_floor);
}
}
else
{
if (need_up && elevator_up || !need_up && elevator_down)
{
weight = abs(elevator_floor - target_floor);
}
else
{
if (need_up)
{
weight = elevator_floor + target_floor - 2;
}
else
{
weight = 2*floor_num - (elevator_floor + target_floor);
}
}
if (need_up != up_direction)
{
if (up_direction)
{
weight += 2*(target_floor - 1);
}
else
{
weight += 2*(floor_num - target_floor);
}
}
}
if (elevator == -1 || weight < min_weight)
{
elevator = i;
min_weight = weight;
}
}
return elevator;
}
#pragma argsused
int main(int argc, char* argv[])
{
int i;
lock = new TCriticalSection;
cout << "input floor_num elevator_num elevator_capacity floor_time stop_time: ";
cin >> floor_num >> elevator_num >> elevator_capacity >> floor_time >> stop_time;
char buf[80];
cin.getline(buf,sizeof(buf));
up.resize(floor_num + 1);
down.resize(floor_num + 1);
out.resize(floor_num + 1);
elevators.resize(elevator_num + 1);
for (i = 1; i <= elevator_num; i++)
{
elevators[i] = new TElevator(i);
elevators[i]->Resume();
}
Sleep(100);
int x = 0,y = 0;
lock->Acquire();
cout << "input name from to: " << endl;
for (;;)
{
string name;
lock->Release();
Sleep(20);
cin >> name >> x >> y;
lock->Acquire();
//char buf[80];
//cin.getline(buf,sizeof(buf));
if (x == y)
continue;
if (x < 1 || x > floor_num)
continue;
if (y < 1 || y > floor_num)
continue;
//valid request
TRequest req(name,x,y);
req.elevator = select_elevator(req);
if (x < y)
up[x].push_back(req);
else
down[x].push_back(req);
}
//lock->Release();
//return 0;
}
//---------------------------------------------------------------------------
我以前写过一个单线程的电梯,你可以参看http://blog.csdn.net/freshare/
只会单线程