凸包问题
时间:2022-06-22
本文章向大家介绍凸包问题,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
定义1:平面上的点集,如果以该集合中的任意两点P和Q为端点构成的线段属于该集合,就称该集合是凸的。
定义2:一个点集S的凸包是包含S的最小凸集合。
定理:任意包含n > 2个点的集合S的凸包是以S中的某些点为顶点的凸多边形。(如果所有点是共线的,多边形退化为线段)
因此,直观看来,任意的凸多边形都是凸集合。
凸包问题是为一个包含n个点的集合构造一个凸包。
根据上面的定理设计了一个基于线性规划的算法来判断能否构造凸包。算法描述如下:
两点确定一条直线(线段),因此,在n个点的集合中的点i和j可以确定一条直线,当且仅当其余n-2个点位于该直线上或者是该直线同一侧时,点i和j的连线才是凸包的一部分边界。直线的方程:f=ax+by-c=0;其中a=y2-y1;b=x1-x2;c=x1*y2-y1*x2,将剩余的点的坐标带入该方程,如果都是f >= 0或者都是f <= 0,说明(x1,y1),(x2,y2)构成的线段是凸包的边界。代码如下:
#include <iostream>
#include <complex>
#include <cstdlib>
using namespace std;
void fun(complex<int> *point, int n);
int main()
{
complex<int> point[5] = { complex<int>(0,0),complex<int>(2,0),complex<int>(2,2),complex<int>(0,2),complex<int>(1,1) };
fun(point, 5);
system("pause");
}
void fun(complex<int> *point, int n)
{
int count1,count2;
int k;
int temp;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++) //遍历所有可能的线段
{
count1 = 0;
count2 = 0;
for (k = 0; k < n; k++)
{
if (k != i && k != j)
{
//计算公式
temp = point[i].real()*point[j].imag() +
point[k].real()*point[i].imag() +
point[j].real()*point[k].imag() -
point[k].real()*point[j].imag() -
point[j].real()*point[i].imag() -
point[i].real()*point[k].imag();
if (temp > 0)
{
count1++;
}
if (0 == temp)
{
count2++;
}
}
}
if (n - 2 == count2) //在一条直线上的时候
{
cout << "凸多边形退化为线段,两个端点分别是:" <<
point[i] << "和" << point[j] << endl;
return;
}
if ((count1 == n - 2) || (0 == count1)) //不在一条直线上
{
cout << "凸多边形其中一条边的两个端点是:" <<
point[i] << "和" << point[j] << endl;
}
}
}
cout << "凸包构造完毕!" << endl;
}
上述算法的时间复杂度是O(n³),很不理想。有待改进。
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- Linux中selinux基础配置教程详解
- 怎么禁用 Ubuntu 服务器中终端欢迎消息中的广告
- Laravel5.1 框架响应基本用法实例分析
- 在Linux中怎么一次重命名多个文件详解
- python调用私有属性的方法总结
- PHP+MySQL实现在线测试答题实例
- Python异常处理机制结构实例解析
- PHP字符串与数组处理函数用法小结
- 详解Flask前后端分离项目案例
- Laravel5.1 框架表单验证操作实例详解
- 通过实例了解Python异常处理机制底层实现
- header函数设置响应头解决php跨域问题实例详解
- Linux采用双网卡bond、起子接口的方式
- PHP实现字母数字混合验证码功能
- php+pdo实现的购物车类完整示例