Last active
August 2, 2018 10:13
-
-
Save blooser/60d544d1403119cf7e126d8b6e113450 to your computer and use it in GitHub Desktop.
Queue simulator
This file contains hidden or 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 "queue.h" | |
#include <fstream> | |
#include <iterator> | |
#include <algorithm> | |
#include <random> | |
std::mutex guard; | |
static std::mt19937 gen{std::random_device{}()}; | |
template <class T> | |
T random(T min, T max){ | |
return std::uniform_int_distribution<T>{min, max}(gen); | |
} | |
string setname(); | |
void simulate(Queue&); | |
typedef std::vector<Queue> vq; | |
vq queues_to_simulate(int,int); | |
vq queues_to_simulate(int); | |
vq queues_to_simulate(); | |
void queue_threads(vq & queue); | |
int countFileLines(std::ifstream & file); | |
int main(void){ | |
vq test = queues_to_simulate(5, 8); | |
queue_threads(test); | |
summary(test.back()); | |
cout<<"\n\n"; | |
test.back().clearResults(); | |
test = queues_to_simulate(10); | |
queue_threads(test); | |
summary(test.back()); | |
cout<<"\n\n"; | |
test.back().clearResults(); | |
test = queues_to_simulate(); | |
queue_threads(test); | |
summary(test.back()); | |
} | |
void queue_threads(vq & queue){ | |
std::vector<std::future<void>> threads; | |
FOREACH(it, queue) | |
threads.push_back(std::async(std::launch::async, simulate, std::ref(*it))); | |
FOREACH(it, threads) | |
it->get(); | |
} | |
void simulate(Queue & queue){ | |
Customer * temp; | |
queue.shortest_time = queue.head->person; | |
queue.longest_time = queue.head->person; | |
while(!queue.isempty()){ | |
double time = 0; | |
if(time <= 0){ | |
temp = new Customer; | |
queue.dequeue(*temp); | |
if(*temp < queue.longest_time) | |
queue.longest_time = *temp; | |
if(*temp > queue.shortest_time) | |
queue.shortest_time = *temp; | |
time = temp->first(); | |
queue.allwaittime+= time; | |
delete temp; | |
} | |
if(time > 0) | |
time--; | |
} | |
queue.average = queue.allwaittime/queue.number_of_customers; | |
guard.lock(); | |
queue.save(); | |
guard.unlock(); | |
} | |
int countFileLines(std::ifstream & file){ | |
int lines = std::count(std::istreambuf_iterator<char>(file), | |
std::istreambuf_iterator<char>(), '\n'); | |
return lines; | |
} | |
string setname(){ | |
std::ifstream file; | |
file.open("names.txt", std::ios::out); | |
if(!file.is_open()) | |
return "None"; | |
int n = countFileLines(file); | |
file.seekg(std::ios::beg); | |
REP(i, random(0, n)) | |
file.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); | |
std::string name; | |
file >> name; | |
file.close(); | |
return name; | |
} | |
vq queues_to_simulate(int n, int n_customers){ | |
vq queues; | |
queues.reserve(n); | |
REP(i, n){ | |
queues.push_back(Queue()); | |
REP(j, n_customers) | |
queues[i].enqueue(Customer(setname(), random(1, 300))); | |
} | |
return queues; | |
} | |
vq queues_to_simulate(int n){ | |
vq queues; | |
queues.reserve(n); | |
int n_customers; | |
REP(i, n){ | |
queues.push_back(Queue()); | |
n_customers = random(1, 100); | |
REP(j, n_customers) | |
queues[i].enqueue(Customer(setname(), random(1, 300))); | |
} | |
return queues; | |
} | |
vq queues_to_simulate(){ | |
vq queues; | |
int n = random(1, 20); | |
int n_customers; | |
queues.reserve(n); | |
REP(i, n){ | |
queues.push_back(Queue()); | |
n_customers = random(1, 100); | |
REP(j, n_customers) | |
queues[i].enqueue(Customer(setname(), random(1, 300))); | |
} | |
return queues; | |
} |
This file contains hidden or 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
Helga | |
Kris | |
Almeda | |
Lu | |
Synthia | |
Ferdinand | |
Dayle | |
Augustina | |
Zena | |
Royal | |
Edie | |
Luigi | |
Arlena | |
Harrison | |
Rossana | |
Yvone | |
Everette | |
Una | |
Juan | |
Jayna | |
Glady | |
Janeen | |
Viola | |
Ginger | |
Kenyetta | |
Brandon | |
Laurinda | |
Tammera | |
Darcey | |
Ronny | |
Teodoro | |
Glen | |
Shalonda | |
Rita | |
Lorrine | |
Margaretta | |
Rema | |
Emery | |
Jenny | |
Ulysses | |
Kristine | |
Garfield | |
Anneliese | |
Bettina | |
Nelida | |
Melinda | |
Enoch | |
Brenda | |
Eufemia | |
Tarah | |
Gale | |
Librada | |
Shantay | |
Nada | |
Rosena | |
Erwin | |
Humberto | |
Elenor | |
Latasha | |
Charlie | |
Danyelle | |
Freddie | |
Kelsi | |
Martin | |
Carly | |
Valeria | |
Stasia | |
Sha | |
Georgina | |
Quintin | |
Sam | |
Eleanore | |
Carletta | |
Antonetta | |
Lannie | |
Jeanie | |
Desirae | |
Adena | |
Loyd | |
Lasonya | |
Rocco | |
Ilona | |
Leatha | |
Ashleigh | |
Temple | |
Kirstie | |
Wen | |
Raylene | |
Peter | |
Emmaline | |
Ileana | |
Shakira | |
Lynsey | |
Etta | |
Ashely | |
Myrl | |
Katelin | |
Ebony | |
Karisa | |
John | |
Berthold | |
Reiner |
This file contains hidden or 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 "queue.h" | |
#include <iomanip> | |
Customer::Customer(){ | |
name = '\0'; | |
wait_time = 0; | |
} | |
Customer::Customer(const string & name, const int time){ | |
this->name = name; | |
this->wait_time = time; | |
} | |
Customer & Customer::operator=(const Customer & other){ | |
this->wait_time = other.first(); | |
this->name = other.second(); | |
} | |
bool Customer::operator<(const Customer & customer){ | |
return customer.first() < this->wait_time; | |
} | |
bool Customer::operator>(const Customer & customer){ | |
return customer.first() > this->wait_time; | |
} | |
std::ostream & operator<<(std::ostream & os, const Customer & customer){ | |
os<<customer.name<<" "<< std::setw(8)<<time_format(customer.wait_time); | |
return os; | |
} | |
vs Queue::results = vs(0); | |
Queue::Queue() : maximum(n), longest_time(), shortest_time() { | |
current = 0; | |
head = rear = nullptr; | |
average = 0.0; | |
allwaittime = 0; | |
} | |
Queue::~Queue(){ | |
Node * temp; | |
while(head != nullptr){ | |
temp = head; | |
head = head->next; | |
delete temp; | |
} | |
} | |
void Queue::enqueue(const Customer & newcustomer){ | |
if(isfull()) | |
return; | |
Node * addcustomer = new Node; | |
addcustomer->person = newcustomer; | |
addcustomer->next = nullptr; | |
current++; | |
number_of_customers = current; | |
if(head == nullptr) | |
head = addcustomer; | |
else | |
rear->next = addcustomer; | |
rear = addcustomer; | |
} | |
void Queue::dequeue(Customer & leaver){ | |
if(head == nullptr) | |
return; | |
leaver = head->person; | |
Node * remove = head; | |
head = head->next; | |
delete remove; | |
current--; | |
if(isempty()) | |
head = nullptr; | |
} | |
void Queue::save(){ | |
std::stringstream sstream; | |
sstream<<std::left<<std::setw(3)<<" customers: "<<number_of_customers<<'\t' | |
<<std::setw(3)<<"sum: "<<time_format(allwaittime)<<" " | |
<<std::setw(3)<<"average: "<<time_format(average)<<" " | |
<<std::setw(9)<<"slowest: "<<std::setw(9)<<longest_time<<" " | |
<<std::setw(9)<<"quickest: "<<std::setw(9)<<shortest_time; | |
results.push_back(sstream.str()); | |
} | |
void Queue::clearResults(){ | |
results.clear(); | |
} | |
void summary(const Queue & queue){ | |
auto wait = std::chrono::milliseconds(3); | |
for(auto it = queue.results.begin(); it != queue.results.end(); it++){ | |
cout<<*it<<"\n"; | |
std::this_thread::sleep_for(wait); | |
} | |
} | |
string time_format(ll time){ | |
int seconds = time%3600; | |
int minutes = seconds/60; | |
int hours = time/3600; | |
seconds %= 60; | |
std::string hourFormat, minuteFormat, secondFormat; | |
hourFormat = hours >= 10 ? std::to_string(hours) : "0" + std::to_string(hours); | |
minuteFormat = minutes >= 10 ? std::to_string(minutes) : "0" + std::to_string(minutes); | |
secondFormat = seconds >= 10 ? std::to_string(seconds) : "0" + std::to_string(seconds); | |
return hourFormat + ":" + minuteFormat + ":" + secondFormat; | |
} |
This file contains hidden or 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 <ctime> | |
#include <string> | |
#include <vector> | |
#include <sstream> | |
#include <chrono> | |
#include <thread> | |
#include <future> | |
#include <mutex> | |
using std::cout; | |
using std::string; | |
typedef long long ll; | |
typedef std::vector<string> vs; | |
#define REP(i, n) for(int i=0; i<n; i++) | |
#define VAR(i, x) __typeof(x) i = x | |
#define FOREACH(i, x) for(VAR(i, x.begin()); i != x.end(); i++) | |
string time_format(ll); | |
class Customer{ | |
private: | |
int wait_time; | |
string name; | |
public: | |
Customer(); | |
Customer(const string &, const int); | |
const int & first() const { return wait_time; } | |
const string & second() const { return name; } | |
Customer & operator=(const Customer &); | |
bool operator>(const Customer &); | |
bool operator<(const Customer &); | |
friend std::ostream & operator<<(std::ostream & os, const Customer & customer); | |
}; | |
class Queue{ | |
private: | |
static vs results; | |
enum { n = 100 }; | |
struct Node{ | |
Customer person; | |
struct Node * next; | |
}; | |
struct Node * head; | |
struct Node * rear; | |
int current, number_of_customers; | |
const int maximum; | |
ll allwaittime; | |
double average; | |
Customer longest_time; | |
Customer shortest_time; | |
public: | |
Queue(); | |
~Queue(); | |
bool isfull() { return current == maximum; } | |
bool isempty() { return current == 0; } | |
void enqueue(const Customer&); | |
void dequeue(Customer &); | |
void clearResults(); | |
friend void simulate(Queue & queue); | |
friend void summary(const Queue & queue); | |
protected: | |
void save(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment