g2000深圳门店最新地址:电梯模拟

来源:百度文库 编辑:杭州交通信息网 时间:2024/04/27 23:59:00
谁会用C++编写多线程的电梯仿真程序啊,要求一座大楼里有10部电梯.
或知道哪里可以下载的请告诉一下
谢谢了,急用!!!

电梯的主要调度策略就是首先响应沿当前行进方向上最远端的请求,当该请求满足后,就可以改变方向了,当无请求时,电梯停在哪里的策略不尽相同。多电梯的调度也比较复杂,下面程序中的调度算法是我自己想的,不一定很好,但基本可以使用了。
  程序源码如下:
  (注:使用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/

只会单线程