parent
982d1a682e
commit
28a209cbd1
|
@ -8,36 +8,11 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
|
#include <cmath>
|
||||||
|
#include <map>
|
||||||
|
#include <random>
|
||||||
|
#include "libpoly.h"
|
||||||
|
|
||||||
#ifndef libpoly092986127876181939u43295237
|
|
||||||
#define libpoly092986127876181939u43295237
|
|
||||||
|
|
||||||
extern void test(void); // prints to stdout to test linking
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct LP_Point {
|
|
||||||
double x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LP_Polygon {
|
|
||||||
std::vector< LP_Point > points;
|
|
||||||
LP_Polygon(std::vector< LP_Point >&& p) : points(p) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LP_Task : public std::enable_shared_from_this< LP_Task > {
|
|
||||||
LP_Polygon p;
|
|
||||||
double minimal_triangulation;
|
|
||||||
};
|
|
||||||
|
|
||||||
using LP_Task_p = std::shared_ptr< LP_Task >;
|
|
||||||
|
|
||||||
extern LP_Task_p pickup_task(); //je thread safe, nebo si to musím ošéfit?
|
|
||||||
extern bool submit_task(LP_Task_p&&);
|
|
||||||
extern void print_stats();
|
|
||||||
|
|
||||||
#endif // libpoly092986127876181939u43295237
|
|
||||||
|
|
||||||
//############################################################ GLOBALS
|
//############################################################ GLOBALS
|
||||||
|
|
||||||
|
@ -47,27 +22,47 @@ std::condition_variable can_push;
|
||||||
std::atomic_uint32_t active_producents;
|
std::atomic_uint32_t active_producents;
|
||||||
std::atomic_uint32_t active_consuments;
|
std::atomic_uint32_t active_consuments;
|
||||||
std::atomic_bool tasks_incoming;
|
std::atomic_bool tasks_incoming;
|
||||||
|
std::ostream& os = std::cout;
|
||||||
|
std::mutex os_l;
|
||||||
|
|
||||||
//############################# MODIFY HERE
|
//############################# MODIFY HERE
|
||||||
|
|
||||||
constexpr unsigned NUM_PRODUCENTS = 20;
|
constexpr unsigned NUM_PRODUCENTS = 1;
|
||||||
constexpr unsigned NUM_WORKERS = 20;
|
constexpr unsigned NUM_WORKERS = 3;
|
||||||
|
|
||||||
//############################################################ COMMON STRUCTURES
|
//############################################################ COMMON STRUCTURES
|
||||||
|
|
||||||
|
struct Temp_Task: public std::enable_shared_from_this< Temp_Task > {
|
||||||
|
LP_Polygon p;
|
||||||
|
double minimal_triangulation;
|
||||||
|
|
||||||
|
Temp_Task(LP_Polygon&& _p): p(_p){}
|
||||||
|
};
|
||||||
|
|
||||||
|
using Temp_Task_p = std::shared_ptr< Temp_Task >;
|
||||||
|
|
||||||
class Task {
|
class Task {
|
||||||
private:
|
private:
|
||||||
LP_Task_p task;
|
Temp_Task_p task;
|
||||||
bool ready_for_submit;
|
|
||||||
|
double triangulate(LP_Polygon* p);
|
||||||
|
double triangulate();
|
||||||
|
double triangulate_subpolys(std::vector<bool> poly_key, std::map<int, double>* m);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Task() = delete;
|
Task(): task(nullptr){};
|
||||||
Task(const Task&) = delete;
|
Task(const Task&) = delete;
|
||||||
Task(Task&& t): task(t.task), ready_for_submit(t.ready_for_submit){
|
Task(Task&& t): task(t.task){
|
||||||
t.task.reset();
|
t.task.reset();
|
||||||
}
|
}
|
||||||
Task(LP_Task_p&& tp): task(tp), ready_for_submit(false){}
|
Task(Temp_Task_p&& tp): task(tp){}
|
||||||
void triangulate();
|
void solve_stupid(){
|
||||||
|
task->minimal_triangulation = triangulate(&(task->p));
|
||||||
|
}
|
||||||
|
Temp_Task_p unwrap(){ // TODO: vymyslet jinak, zaručit po tomto kroku selfdestruct
|
||||||
|
return std::move(task);
|
||||||
|
}
|
||||||
|
double const solution(){ return task->minimal_triangulation; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Queue{
|
class Queue{
|
||||||
|
@ -79,8 +74,7 @@ public:
|
||||||
|
|
||||||
void push(Task&& t){
|
void push(Task&& t){
|
||||||
std::unique_lock<std::mutex> pushlock(q_l);
|
std::unique_lock<std::mutex> pushlock(q_l);
|
||||||
can_push.wait(pushlock, [this]{ return (q.size() < MAX_LENGHT); });
|
can_push.wait(pushlock, [this](){ return (q.size() < MAX_LENGHT); });
|
||||||
|
|
||||||
|
|
||||||
q.push(std::move(t));
|
q.push(std::move(t));
|
||||||
pushlock.unlock();
|
pushlock.unlock();
|
||||||
|
@ -89,7 +83,7 @@ public:
|
||||||
|
|
||||||
Task pop(){
|
Task pop(){
|
||||||
std::unique_lock<std::mutex> poplock(q_l);
|
std::unique_lock<std::mutex> poplock(q_l);
|
||||||
can_pop.wait(poplock, [this]{ return !is_empty(); });
|
can_pop.wait(poplock, [this](){ return !is_empty(); });
|
||||||
|
|
||||||
Task t(std::move(q.front()));
|
Task t(std::move(q.front()));
|
||||||
q.pop();
|
q.pop();
|
||||||
|
@ -116,12 +110,29 @@ public:
|
||||||
~Producent(){ active_producents--; }
|
~Producent(){ active_producents--; }
|
||||||
|
|
||||||
Task get_task(){
|
Task get_task(){
|
||||||
LP_Task_p tp = pickup_task(); //might need to be locked - ask Ondra
|
//LP_Task_p tp = pickup_task();
|
||||||
|
|
||||||
|
//#########################3TEMP_PART:
|
||||||
|
std::vector< LP_Point > points;
|
||||||
|
srand(static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()));
|
||||||
|
int num_of_points = (rand()%10) + 1;
|
||||||
|
for(int i = 0; i < num_of_points; i++){
|
||||||
|
LP_Point p;
|
||||||
|
|
||||||
|
p.x = rand()%199 +1;
|
||||||
|
p.y = rand()%199 +1;
|
||||||
|
points.push_back(p);
|
||||||
|
}
|
||||||
|
LP_Polygon p(std::move(points));
|
||||||
|
Temp_Task_p tp = std::make_shared<Temp_Task>(std::move( p ));
|
||||||
|
|
||||||
return Task(std::move(tp));
|
return Task(std::move(tp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_queue(){
|
void fill_queue(){
|
||||||
while(tasks_incoming){
|
while(tasks_incoming){
|
||||||
|
//Task t = get_task();
|
||||||
|
|
||||||
task_queue->push(get_task());
|
task_queue->push(get_task());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,29 +160,123 @@ public:
|
||||||
void work(){
|
void work(){
|
||||||
while(active_producents || ! task_queue->is_empty()){
|
while(active_producents || ! task_queue->is_empty()){
|
||||||
Task t = get_task();
|
Task t = get_task();
|
||||||
t.triangulate();
|
t.solve_stupid();
|
||||||
|
//submit_task(std::move(t.unwrap()));
|
||||||
|
os_l.lock();
|
||||||
|
os << t.solution() << std::endl;
|
||||||
|
os_l.unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void consume_thread(task_queue_ptr task_queue){
|
void consume_thread(task_queue_ptr task_queue){
|
||||||
Consument c(task_queue);
|
Consument c(task_queue);
|
||||||
|
c.work();
|
||||||
|
}
|
||||||
|
|
||||||
|
//############################################################ TRIANGULATION
|
||||||
|
|
||||||
|
struct Line{
|
||||||
|
LP_Point a;
|
||||||
|
LP_Point b;
|
||||||
|
double length;
|
||||||
|
|
||||||
|
Line() = delete;
|
||||||
|
Line(LP_Point _a, LP_Point _b): a(_a), b(_b){
|
||||||
|
LP_Point vec_ba;
|
||||||
|
vec_ba.x = b.x - a.x;
|
||||||
|
vec_ba.y = b.y - a.y;
|
||||||
|
length = sqrt(vec_ba.x*vec_ba.x + vec_ba.y*vec_ba.y);
|
||||||
|
}
|
||||||
|
Line(Line& l): a(l.a), b(l.b), length(l.length){}
|
||||||
|
};
|
||||||
|
|
||||||
|
double Task::triangulate(LP_Polygon* p){
|
||||||
|
size_t poly_size = p->points.size();
|
||||||
|
|
||||||
|
if(poly_size == 3) return 0.;
|
||||||
|
|
||||||
|
double triangulation;
|
||||||
|
double min_triangulation = INFINITY;
|
||||||
|
|
||||||
|
for (size_t point_idx = 0; point_idx < poly_size; point_idx++){
|
||||||
|
Line cut(p->points.at( (point_idx - 1) % poly_size ),
|
||||||
|
p->points.at( (point_idx + 1) % poly_size ));
|
||||||
|
|
||||||
|
std::vector<LP_Point> smaller_poly;
|
||||||
|
for(size_t i = 0; i < poly_size; i++){
|
||||||
|
if(i != point_idx) smaller_poly.push_back(p->points.at(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
LP_Polygon s_p(std::move(smaller_poly));
|
||||||
|
triangulation = triangulate(&s_p) + cut.length;
|
||||||
|
if(triangulation < min_triangulation) min_triangulation = triangulation;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min_triangulation;
|
||||||
|
|
||||||
|
}
|
||||||
|
//############################### dynamic something
|
||||||
|
|
||||||
|
//use std::map to store triangulations of polygons
|
||||||
|
//KEY CREATION:
|
||||||
|
// take relative positions of points in polygon, add them as vectors and do something with the amount of them
|
||||||
|
// maybe num * vx + num^2 * vy
|
||||||
|
|
||||||
|
double Task::triangulate(){
|
||||||
|
std::map<int, double> m;
|
||||||
|
std::vector<bool> poly_key;
|
||||||
|
return triangulate_subpolys(poly_key, &m);
|
||||||
|
}
|
||||||
|
|
||||||
|
int vec_to_int(std::vector<bool>* vec){
|
||||||
|
int res = 0;
|
||||||
|
for (size_t i = 0; i < vec->size(); i++){
|
||||||
|
res += vec->at(i) * 2^i;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
double Task::triangulate_subpolys(std::vector<bool> poly_key, std::map<int, double>* m){
|
||||||
|
// convert p to int
|
||||||
|
// try to find in map
|
||||||
|
// success -> return mapped value
|
||||||
|
// failure -> compute triangulation
|
||||||
|
// save value in map
|
||||||
|
// return found value
|
||||||
|
// COMPUTE TRIANGULATION
|
||||||
|
// create polygon poly from p
|
||||||
|
// use stupid triangulation but create poly_key instead of small_poly
|
||||||
|
|
||||||
|
return 0.;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//############################################################ MAIN
|
//############################################################ MAIN
|
||||||
|
|
||||||
int main(){
|
int main(){
|
||||||
active_producents = 0;
|
active_producents = active_consuments = 0;
|
||||||
Queue q;
|
tasks_incoming = true;
|
||||||
task_queue_ptr queue_ptr(&q);
|
|
||||||
|
task_queue_ptr queue_ptr = std::make_shared<Queue>();
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
|
|
||||||
for(unsigned int i = 0; i < NUM_PRODUCENTS; i++){
|
for(unsigned int i = 0; i < NUM_PRODUCENTS; i++){
|
||||||
threads.emplace_back(produce_thread, queue_ptr);
|
threads.emplace_back(produce_thread, queue_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(5));
|
for(unsigned int i = 0; i < NUM_WORKERS; i++){
|
||||||
|
threads.emplace_back(consume_thread, queue_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(5));
|
||||||
|
tasks_incoming = false;
|
||||||
for(auto& t : threads){
|
for(auto& t : threads){
|
||||||
t.join();
|
t.join();
|
||||||
|
os_l.lock();
|
||||||
|
os << "joined" << std::endl;
|
||||||
|
os_l.unlock();
|
||||||
}
|
}
|
||||||
|
//test();
|
||||||
}
|
}
|
Loading…
Reference in New Issue