From 341b496b40c536763e6c9625110a53f2eebc4ac4 Mon Sep 17 00:00:00 2001 From: TUNQRT Date: Tue, 25 Mar 2025 09:58:44 +0100 Subject: [PATCH] triangulation fix + infrastructure improvements --- Dockerfile | 6 +- build.sh | 5 +- kill.sh | 2 +- triangulation.cpp | 222 +++++++++++++++++++++++++++++----------------- 4 files changed, 147 insertions(+), 88 deletions(-) diff --git a/Dockerfile b/Dockerfile index a91a01e..ab08ccc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,12 +1,12 @@ FROM gcc:latest +RUN apt update && apt install -y gdb gdbserver openssh-server && \ + apt clean + COPY ./ /app WORKDIR /app -RUN apt update && apt install -y gdb gdbserver openssh-server && \ - apt clean - RUN make a.out && echo 'yeey' RUN mv key.pub /root/.ssh/authorized_keys && \ diff --git a/build.sh b/build.sh index 4625a5d..efe8e66 100755 --- a/build.sh +++ b/build.sh @@ -3,4 +3,7 @@ if [ ! -f key ] || [ ! -f key.pub ]; then rm -f key key.pub && \ ssh-keygen -t ed25519 -N "" -f key fi -docker build -t cpp20 . \ No newline at end of file + +docker build -t cpp20 . + +./kill.sh \ No newline at end of file diff --git a/kill.sh b/kill.sh index 8300ff8..b14a412 100755 --- a/kill.sh +++ b/kill.sh @@ -1,3 +1,3 @@ #!/bin/bash -docker ps --filter name=triangulation --format "{{.ID}}"| xargs -L1 docker kill \ No newline at end of file +docker ps --filter name=triangulation --format "{{.ID}}"| ifne xargs -L1 docker kill \ No newline at end of file diff --git a/triangulation.cpp b/triangulation.cpp index 0513059..40ad9ab 100644 --- a/triangulation.cpp +++ b/triangulation.cpp @@ -45,7 +45,8 @@ private: double triangulate_basic(LP_Polygon* p); double triangulate(); - double triangulate_subpolys(std::vector poly_key, std::map* m); + double triangulate_subpolys(std::vector poly_key, + std::map< std::vector, double>* m); std::vector create_key(std::vector* indices); public: @@ -105,6 +106,84 @@ public: using task_queue_ptr = std::shared_ptr; +//############################################################ DEBUG HELPERS + +void print_point(LP_Point* p){ + std::cout << "{ " << p->x << ", " << p->y << " }"; +} + +void print_polygon(LP_Polygon* p){ + std::cout << "{\n"; + for(size_t i = 0; i < p->points.size(); i++){ + std::cout << " "; + print_point(&(p->points[i])); + if(i < p->points.size() - 1) std::cout << ",\n"; + else std::cout << "\n"; + } + std::cout << "}\n"; +} + +void task_test(){ + std::vector< LP_Point > v1 = {{0,0}, {1,1}, {3,1}, {2,0}}; + std::vector< LP_Point > v2 = {{0,0}, {0,1}, {1,2}, {2,1}, {2,0}}; + std::vector< LP_Point > v3 = {{0,0}, {1,1}, {2,2}, {3,1}, {2,0}, {1,-1}}; + + LP_Polygon p1(std::move(v1)); + LP_Polygon p2(std::move(v2)); + LP_Polygon p3(std::move(v3)); + + Temp_Task_p tp1 = std::make_shared(std::move(p1)); + Temp_Task_p tp2 = std::make_shared(std::move(p2)); + Temp_Task_p tp3 = std::make_shared(std::move(p3)); + + Task t1(std::move(tp1)); + Task t2(std::move(tp2)); + Task t3(std::move(tp3)); + + auto start1 = std::chrono::high_resolution_clock::now(); + t1.solve_stupid(); + auto end1 = std::chrono::high_resolution_clock::now(); + + auto start2 = std::chrono::high_resolution_clock::now(); + t2.solve_stupid(); + auto end2 = std::chrono::high_resolution_clock::now(); + + auto start3 = std::chrono::high_resolution_clock::now(); + t3.solve_stupid(); + auto end3 = std::chrono::high_resolution_clock::now(); + + auto duration1 = std::chrono::duration_cast(end1 - start1); + auto duration2 = std::chrono::duration_cast(end2 - start2); + auto duration3 = std::chrono::duration_cast(end3 - start3); + + std::cout << "4 vertices:\ncorrect: calculated:\n" << "1.414 " << t1.solution() << " taking " << duration1.count() << "ms" << std::endl; + std::cout << "5 vertices:\ncorrect: calculated:\n" << "4.236 " << t2.solution() << " taking " << duration2.count() << "ms" << std::endl; + std::cout << "6 vertices:\ncorrect: calculated:\n" << "5.414 " << t3.solution() << " taking " << duration3.count() << "ms" << std::endl << std::endl; + + start1 = std::chrono::high_resolution_clock::now(); + t1.solve_less_stupid(); + end1 = std::chrono::high_resolution_clock::now(); + + start2 = std::chrono::high_resolution_clock::now(); + t2.solve_less_stupid(); + end2 = std::chrono::high_resolution_clock::now(); + + start3 = std::chrono::high_resolution_clock::now(); + t3.solve_less_stupid(); + end3 = std::chrono::high_resolution_clock::now(); + + duration1 = std::chrono::duration_cast(end1 - start1); + duration2 = std::chrono::duration_cast(end2 - start2); + duration3 = std::chrono::duration_cast(end3 - start3); + + std::cout << "SECOND VERSION:\n\n"; + + std::cout << "4 vertices:\ncorrect: calculated:\n" << "1.414 " << t1.solution() << " taking " << duration1.count() << "ms" << std::endl; + std::cout << "5 vertices:\ncorrect: calculated:\n" << "4.236 " << t2.solution() << " taking " << duration2.count() << "ms" << std::endl; + std::cout << "6 vertices:\ncorrect: calculated:\n" << "5.414 " << t3.solution() << " taking " << duration3.count() << "ms" << std::endl << std::endl; +} + + //############################################################ PRODUCE THREAD /* class Producent{ @@ -219,10 +298,10 @@ double Task::triangulate_basic(LP_Polygon* p){ if(poly_size == 3) return 0.; if(poly_size == 4){ - Line cut1(p->points.at( 0 ), - p->points.at( 2 )); - Line cut2(p->points.at( 1 ), - p->points.at( 3 )); + Line cut1(p->points[0], + p->points[2]); + Line cut2(p->points[1], + p->points[3]); return std::min(cut1.length, cut2.length); } @@ -230,17 +309,38 @@ double Task::triangulate_basic(LP_Polygon* p){ 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 )); + Line cut(p->points.at( (point_idx + poly_size - 1) % poly_size ), + p->points.at( (point_idx + poly_size + 1) % poly_size )); std::vector 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_basic(&s_p) + cut.length; - if(triangulation < min_triangulation) min_triangulation = triangulation; + + // if(poly_size == 6){ + // std::cout << "From poly:\n"; + // print_polygon(p); + // std::cout << "created:\n"; + // print_polygon(&s_p); + // std::cout << "by cut " << (point_idx + poly_size - 1) % poly_size << "->" << (point_idx + poly_size + 1) % poly_size << "\n\n"; + // } + + double s_triang = triangulate_basic(&s_p); + triangulation = s_triang + cut.length; + min_triangulation = std::min(triangulation, min_triangulation); + // if(triangulation < min_triangulation) min_triangulation = triangulation; + + // std::cout << "Poly size = " << poly_size << + // "\nCutted point = "; + // print_point(&(p->points[point_idx])); + // std::cout << " by "; + // print_point(&(cut.a)); + // std::cout << " -> "; + // print_point(&(cut.b)); + // std::cout << "\nTriang = " << triangulation << + // "\nPrev min triang = " << prev_min_t << + // "\nMin triang = " << min_triangulation << "\n\n"; } return min_triangulation; @@ -257,23 +357,16 @@ double Task::triangulate_basic(LP_Polygon* p){ //########################### dynamic something //use std::map to store triangulations of polygons +// ! only for small polygons: int is too small double Task::triangulate(){ - std::map m; + std::map, double> m; std::vector poly_key(task->p.points.size(), true); return triangulate_subpolys(poly_key, &m); // // return triangulate_subpolys_but_better(); } -int vec_to_int(std::vector* vec){ - int res = 0; - for (size_t i = 0; i < vec->size(); i++){ - res += vec->at(i) * 2^i; - } - return res; -} - std::vector Task::create_key(std::vector* indices){ size_t key_length = task->p.points.size(); @@ -285,15 +378,10 @@ std::vector Task::create_key(std::vector* indices){ return key; } -double Task::triangulate_subpolys(std::vector poly_key, std::map* m){ - // convert p to int - int key = vec_to_int(&poly_key); +double Task::triangulate_subpolys(std::vector poly_key, std::map< std::vector, double>* m){ + if (m->contains(poly_key)) return m->at(poly_key); // ! contains() is c++20 - // try to find in map - // success -> return mapped value - if (m->count(key)) return m->at(key); // ! contains() is c++20 - - // failure -> create poly from key + // SET VARIABLES std::vector curr_points; std::vector curr_indices; for(size_t i = 0; i < task->p.points.size(); i++){ @@ -302,23 +390,32 @@ double Task::triangulate_subpolys(std::vector poly_key, std::map sub_indices = curr_indices; sub_indices.erase(sub_indices.begin() + point_idx); @@ -326,58 +423,17 @@ double Task::triangulate_subpolys(std::vector poly_key, std::map v1 = {{0,0}, {1,1}, {3,1}, {2,0}}; - std::vector< LP_Point > v2 = {{0,0}, {0,1}, {1,2}, {2,1}, {2,0}}; - std::vector< LP_Point > v3 = {{0,0}, {1,1}, {2,2}, {3,1}, {2,0}, {1,-1}}; - - LP_Polygon p1(std::move(v1)); - LP_Polygon p2(std::move(v2)); - LP_Polygon p3(std::move(v3)); - - Temp_Task_p tp1 = std::make_shared(std::move(p1)); - Temp_Task_p tp2 = std::make_shared(std::move(p2)); - Temp_Task_p tp3 = std::make_shared(std::move(p3)); - - Task t1(std::move(tp1)); - Task t2(std::move(tp2)); - Task t3(std::move(tp3)); - - t1.solve_stupid(); - t2.solve_stupid(); - t3.solve_stupid(); - - std::cout << "4 vertices:\ncorrect: calculated:\n" << "1.414 " << t1.solution() << std::endl; - std::cout << "5 vertices:\ncorrect: calculated:\n" << "4.236 " << t2.solution() << std::endl; - std::cout << "6 vertices:\ncorrect: calculated:\n" << "5.414 " << t1.solution() << std::endl << std::endl; - - t1.solve_less_stupid(); - t2.solve_less_stupid(); - t3.solve_less_stupid(); - - std::cout << "SECOND VERSION:\n\n"; - - std::cout << "4 vertices:\ncorrect: calculated:\n" << "1.414 " << t1.solution() << std::endl; - std::cout << "5 vertices:\ncorrect: calculated:\n" << "4.236 " << t2.solution() << std::endl; - std::cout << "6 vertices:\ncorrect: calculated:\n" << "5.414 " << t1.solution() << std::endl << std::endl; -} - - - //############################################################ MAIN int main(){ @@ -419,5 +475,5 @@ int main(){ // test(); //############################### TRIANGULATION TEST - task_test(); + task_test(); } \ No newline at end of file