-
-
Save mk2/590b5fcae9605c897eff7b42b58688e5 to your computer and use it in GitHub Desktop.
(1: 最適化問題) 下記パラメータのままでElevator::tick()のみを最適化して平均待ち人数を最小化する / (2: 並列化問題) 以下のプログラムをマルチスレッドで動作させると何倍早くなるか実装して検証する / (3: チューニング問題)並列化以外の方法で本プログラムの実行時間を短縮するためにどのような改修を加えるとよいか考察する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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