Skip to content

Instantly share code, notes, and snippets.

@attakei
Forked from remore/kachidoki_elevator.cc
Created January 25, 2017 09:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save attakei/698344dd70ce0e5303231f7ce9fb1b82 to your computer and use it in GitHub Desktop.
Save attakei/698344dd70ce0e5303231f7ce9fb1b82 to your computer and use it in GitHub Desktop.
(1: 最適化問題) 下記パラメータのままでElevator::tick()のみを最適化して平均待ち人数を最小化する / (2: 並列化問題) 以下のプログラムをマルチスレッドで動作させると何倍早くなるか実装して検証する / (3: チューニング問題)並列化以外の方法で本プログラムの実行時間を短縮するためにどのような改修を加えるとよいか考察する
#include <iostream>
#include <iomanip>
#include <random>
#include <unistd.h>
using namespace std;
const int MAX_FLOOR = 14;
const int ELEVATOR_COUNT = 4;
const int RAISING_PROBABILITY = 10;
class Elevator{
private:
int pos=0;
public:
bool dest[MAX_FLOOR]={};
enum RunningStatus {MOVING, STOPPED, ARRIVED};
RunningStatus state=STOPPED;
int get_position();
RunningStatus tick(Elevator *e);
const char* get_state_char();
};
int Elevator::get_position(){
return pos;
}
Elevator::RunningStatus Elevator::tick(Elevator *e){
state = STOPPED;
for (int i=0; i<MAX_FLOOR; i++){
if (dest[i] && i!=pos) {
if (i<pos) {pos-=1;} else {pos+=1;}
if (i==pos) {
state = ARRIVED;
dest[i] = false;
break;
} else {
state = MOVING;
break;
}
}
}
return state;
}
const char* Elevator::get_state_char(){
switch(state){
case Elevator::STOPPED: return "S";
case Elevator::ARRIVED: return "A";
case Elevator::MOVING: return "M";
}
}
int main(int argc, char** argv) {
if (argc<2) {
cout << "入力パラメータを指定してください:" << endl;
cout << "例) ./a.out 1000 -d" << endl;
return -1;
}
int frame_count, sum=0;
Elevator e[ELEVATOR_COUNT];
int waiting_people[MAX_FLOOR]={};
random_device rnd;
for (frame_count=0; frame_count<atol(argv[1]); frame_count++){
// 人が集まる
for (int j=0; j<MAX_FLOOR; j++){
for (int k=0; k<ELEVATOR_COUNT; k++){
if (rnd()%RAISING_PROBABILITY==0){
int peep = 1+rnd()%5;
waiting_people[j] += peep;
e[k].dest[j]=true; // エレベータを呼ぶ
}
}
sum += waiting_people[j];
}
// エレベータ動く
for (int j=0; j<ELEVATOR_COUNT; j++){
switch(e[j].tick(e)){
case Elevator::STOPPED:
case Elevator::ARRIVED:
waiting_people[e[j].get_position()] = 0;
break;
case Elevator::MOVING:
break;
}
}
// コンソール出力
if (argc >=3 && (string)"-d"==argv[2] || (frame_count+1)==atol(argv[1])) {
usleep(50000);
cout << "\033[2J";
cout << " time=" << frame_count << "sec" << endl;
cout << " ----------------------" << endl;
cout << " elevators waiting" << endl;
for (int i=MAX_FLOOR; --i>=0;){
cout << setw(3) << i << "F";
for (auto elevator:e){
cout << "|" << ((elevator.get_position()==i) ? elevator.get_state_char() : (elevator.dest[i] ? "`" : " ") );
}
cout << "|" << " " << waiting_people[i] << endl;
}
}
}
cout << "平均待ち人数=" << (float)sum / (frame_count*MAX_FLOOR) << "人" << endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment