triangulation fix + infrastructure improvements

This commit is contained in:
TUNQRT 2025-03-25 09:58:44 +01:00
parent b66adf7ab5
commit 341b496b40
4 changed files with 147 additions and 88 deletions

View File

@ -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 && \

View File

@ -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 .
docker build -t cpp20 .
./kill.sh

View File

@ -1,3 +1,3 @@
#!/bin/bash
docker ps --filter name=triangulation --format "{{.ID}}"| xargs -L1 docker kill
docker ps --filter name=triangulation --format "{{.ID}}"| ifne xargs -L1 docker kill

View File

@ -45,7 +45,8 @@ private:
double triangulate_basic(LP_Polygon* p);
double triangulate();
double triangulate_subpolys(std::vector<bool> poly_key, std::map<int, double>* m);
double triangulate_subpolys(std::vector<bool> poly_key,
std::map< std::vector<bool>, double>* m);
std::vector<bool> create_key(std::vector<int>* indices);
public:
@ -105,6 +106,84 @@ public:
using task_queue_ptr = std::shared_ptr<Queue>;
//############################################################ 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<Temp_Task>(std::move(p1));
Temp_Task_p tp2 = std::make_shared<Temp_Task>(std::move(p2));
Temp_Task_p tp3 = std::make_shared<Temp_Task>(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<std::chrono::microseconds>(end1 - start1);
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
auto duration3 = std::chrono::duration_cast<std::chrono::microseconds>(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<std::chrono::microseconds>(end1 - start1);
duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
duration3 = std::chrono::duration_cast<std::chrono::microseconds>(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<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_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<int, double> m;
std::map<std::vector<bool>, double> m;
std::vector<bool> poly_key(task->p.points.size(), true);
return triangulate_subpolys(poly_key, &m);
//
// return triangulate_subpolys_but_better();
}
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;
}
std::vector<bool> Task::create_key(std::vector<int>* indices){
size_t key_length = task->p.points.size();
@ -285,15 +378,10 @@ std::vector<bool> Task::create_key(std::vector<int>* indices){
return key;
}
double Task::triangulate_subpolys(std::vector<bool> poly_key, std::map<int, double>* m){
// convert p to int
int key = vec_to_int(&poly_key);
double Task::triangulate_subpolys(std::vector<bool> poly_key, std::map< std::vector<bool>, 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<LP_Point> curr_points;
std::vector<int> curr_indices;
for(size_t i = 0; i < task->p.points.size(); i++){
@ -302,23 +390,32 @@ double Task::triangulate_subpolys(std::vector<bool> poly_key, std::map<int, doub
curr_indices.push_back(i);
}
}
LP_Polygon poly(std::move(curr_points));
// use stupid triangulation but create poly_key instead of small_poly
// save value in map before any return
size_t poly_size = poly.points.size();
if(poly_size == 3){
(*m)[key] = 0.;
return 0.;
}
double triangulation;
double triangulation = INFINITY;
double min_triangulation = INFINITY;
// EDGE CASES
if(poly_size == 3){
(*m)[poly_key] = 0.;
return 0.;
}
if(poly_size == 4){
Line cut1(curr_points[0],
curr_points[2]);
Line cut2(curr_points[1],
curr_points[3]);
min_triangulation = std::min(cut1.length, cut2.length);
(*m)[poly_key] = min_triangulation;
return min_triangulation;
}
for (size_t point_idx = 0; point_idx < poly_size; point_idx++){
Line cut(poly.points.at( (point_idx - 1) % poly_size ),
poly.points.at( (point_idx + 1) % poly_size ));
Line cut(poly.points.at( (point_idx + poly_size - 1) % poly_size ),
poly.points.at( (point_idx + poly_size + 1) % poly_size ));
std::vector<int> sub_indices = curr_indices;
sub_indices.erase(sub_indices.begin() + point_idx);
@ -326,58 +423,17 @@ double Task::triangulate_subpolys(std::vector<bool> poly_key, std::map<int, doub
triangulation = triangulate_subpolys( create_key( &sub_indices ), m )
+ cut.length;
if(triangulation < min_triangulation) min_triangulation = triangulation;
min_triangulation = std::min(triangulation, min_triangulation);
// if(triangulation < min_triangulation) min_triangulation = triangulation;
}
(*m)[key] = min_triangulation;
(*m)[poly_key] = min_triangulation;
// return found value
return min_triangulation;
}
//########################### dynamic something but better
//############################################################ TRIANGULATION TEST
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<Temp_Task>(std::move(p1));
Temp_Task_p tp2 = std::make_shared<Temp_Task>(std::move(p2));
Temp_Task_p tp3 = std::make_shared<Temp_Task>(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();
}