暴力法解决最近对问题和凸包问题-实现可视化
- 开发
- 2024-05-10
- 1342热度
- 0评论
最近对问题
顾名思义就是采用蛮力法求出所有点之间的距离,然后进行比较找出第一个最近对,一个一个进行比较。
大概思路就是如图(每个圈代表一个数对)
第一个和其他四个比较
第二个和其他三个比较
最后比较最小的

代码
图形化界面主要是easyx的graphics
#include<iostream> #include <fstream> #include<graphics.h> #include <conio.h> using namespace std; #define Max 20 //20个点的凸包问题 #define maxn 10000 #define time 15 typedef struct { int a; int b; }point; void draw_point(point x[]); void draw_line(int a, int b, int c, int d); void judge(point x[]); int main() { point x[Max]; ifstream in("a.txt"); cout << "从txt中读取点坐标如下:" << endl; for (int i = 0; i < 20; i++) { in >> x[i].a; in >> x[i].b; } for (int i = 0; i < 20; i++) { cout << i + 1 << ":" << "(" << x[i].a << "," << x[i].b << ")" << endl; } cout << endl << endl; in.close(); cout << "存储的数据如下:" << endl; draw_point(x); judge(x); getchar(); return 0; } void judge(point x[]) { int i, j, a, b, c, n, num1 = 0, num2 = 0; int flag; for (i = 0; i < Max; i++) { for (j = i + 1; j < Max; j++) { b = x[i].a - x[j].a; a = x[j].b - x[i].b; c = x[i].a * x[j].b - x[j].a * x[i].b; for (n = 0; n < Max; n++) { if (n != i && n != j) { flag = x[n].a * a + x[n].b * b; if (flag < c) num1++; else if (flag > c) num2++; else { num1++; num2++; } ; } } if (num1 == 18 || num2 == 18) { cout << "如下两点是极边:" << "(" << x[i].a << "," << x[i].b << ")" << "(" << x[j].a << "," << x[j].b << ")" << endl; draw_line(x[i].a, x[i].b, x[j].a, x[j].b); } num1 = num2 = 0; } } } void draw_point(point x[]) { initgraph(880, 680, SHOWCONSOLE); setorigin(320, 240); int a, b; for (int i = 0; i < Max; i++) { a = x[i].a * time; b = x[i].b * time; fillcircle(a, b, 4); } } void draw_line(int a, int b, int c, int d) { line(a * time, b * time, c * time, d * time); }
运行结果
先写一个a.txt文件的点(20个)

运行(可视化界面)

凸包问题
凸包问题就是在一个有n个点集的平面上,找出所有的“极点”,这些极点所构成的边界能够把其他所有的点都能包含在内。
思路
由两个点连起来的直线会将平面分成两部分,其中半个平面的点都满足ax+by>c ,另一半平面中的点都满足ax+by<c ,对于线上的点来说满足ax+by=c。因此,算法的思路就是对于每个点带入ax+by-c,判断表达式结果的符号是否相同即可。
代码
#include<iostream> #include<fstream> #include<graphics.h> #include<cmath> #include<algorithm> using namespace std; #define Max 20 // 最大点数 #define maxn 10000 #define time 15 typedef struct { int a; int b; } point; void draw_point(point x[]); void draw_line(int a, int b, int c, int d); void closest_pair(point x[]); int main() { point x[Max]; ifstream in("points.txt"); cout << "从txt文件中读取点坐标:" << endl; for (int i = 0; i < Max; i++) { in >> x[i].a; in >> x[i].b; } for (int i = 0; i < Max; i++) { cout << i + 1 << ": (" << x[i].a << ", " << x[i].b << ")" << endl; } cout << endl << endl; in.close(); cout << "存储的数据如下:" << endl; draw_point(x); closest_pair(x); getchar(); closegraph(); // 关闭图形窗口 return 0; } void closest_pair(point x[]) { int min_distance = INT_MAX; int pair1 = -1, pair2 = -1; for (int i = 0; i < Max; i++) { for (int j = i + 1; j < Max; j++) { int distance = pow(x[i].a - x[j].a, 2) + pow(x[i].b - x[j].b, 2); if (distance < min_distance) { min_distance = distance; pair1 = i; pair2 = j; } } } cout << "最近的点对:" << endl; cout << "(" << x[pair1].a << ", " << x[pair1].b << ") 和 (" << x[pair2].a << ", " << x[pair2].b << ")" << endl; // 绘制最近的点对连线 draw_line(x[pair1].a, x[pair1].b, x[pair2].a, x[pair2].b); } void draw_point(point x[]) { initgraph(880, 680, SHOWCONSOLE); setorigin(320, 240); int a, b; for (int i = 0; i < Max; i++) { a = x[i].a * time; b = x[i].b * time; fillcircle(a, b, 4); } } void draw_line(int a, int b, int c, int d) { line(a * time, b * time, c * time, d * time); }
运行结果
先写一个points.txt文件的点(20个)

运行:(可视化界面)

