k近邻算法C++二维实现

这是一个k近邻算法的二维实现(即K=2的情况)。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const double inf = 1000.0;
const int maxn = ; void debug_dfs(int);
void go_method();
bool should_go(int);
void dfs(int);
void back_method(); double Left[maxn], Right[maxn], Top[maxn], Button[maxn];
int tree[maxn][], parent[maxn], cnt = , n;
int depth[maxn];
struct point {
double x, y;
};
vector<point> points[maxn];
queue<int> q;
point tmp[maxn];
point node[maxn];
point p0, anspoint;
int ansid;
double R;
bool cmpx(point a, point b) {
return a.x < b.x;
}
bool cmpy(point a, point b) {
return a.y < b.y;
}
int main() {
scanf("%d", &n);
point p;
for(int i=;i<n;i++) {
scanf("%lf%lf", &p.x , &p.y);
points[cnt].push_back(p);
}
depth[cnt] = ;
Left[cnt] = Button[cnt] = -inf;
Right[cnt] = Top[cnt] = inf;
parent[cnt] = -;
q.push(cnt);
while(!q.empty()) {
int u = q.front();
q.pop();
vector<point> &ps = points[u];
int sz = ps.size();
if(sz <= ) continue;
if(sz == ) {
node[u] = ps[];
continue;
}
for(int i=;i<sz;i++) {
tmp[i] = ps[i];
}
if(depth[u] % == ) sort(tmp, tmp+sz, cmpx);
else sort(tmp, tmp+sz, cmpy);
int mid = sz / ;
node[u] = tmp[mid];
int lsz = mid, rsz = sz - - mid;
if(lsz) {
int l = ++cnt;
tree[u][] = l;
parent[l] = u;
depth[l] = depth[u] + ;
q.push(l);
for(int i=;i<mid;i++) points[l].push_back(tmp[i]);
Left[l] = Left[u]; Right[l] = Right[u]; Top[l] = Top[u]; Button[l] = Button[u];
if(depth[u] % == ) Right[l] = tmp[mid].x;
else Top[l] = tmp[mid].y;
}
if(rsz) {
int r = ++cnt;
tree[u][] = r;
parent[r] = u;
depth[r] = depth[u] + ;
q.push(r);
for(int i=mid+;i<sz;i++) points[r].push_back(tmp[i]);
Left[r] = Left[u]; Right[r] = Right[u]; Top[r] = Top[u]; Button[r] = Button[u];
if(depth[u] % == ) Left[r] = tmp[mid].x;
else Button[r] = tmp[mid].y;
} }
scanf("%lf%lf", &p0.x, &p0.y);
back_method(); printf("(%.2lf,%.2lf)\n", node[ansid].x, node[ansid].y); //debug_dfs(0);
return ;
} void go_method() {
int cur = ;
ansid = cur;
while(true) {
int l = tree[cur][], r = tree[cur][];
if(l && Left[l] <= p0.x && Right[l] >= p0.x && Button[l] <= p0.y && Top[l] >= p0.y) {
cur = l;
ansid = l;
} else if(r && Left[r] <= p0.x && Right[r] >= p0.x && Button[r] <= p0.y && Top[r] >= p0.y) {
cur = r;
ansid = r;
} else {
R = sqrt((p0.x-node[ansid].x)*(p0.x-node[ansid].x)+(p0.y-node[ansid].y)*(p0.y-node[ansid].y));
return;
}
}
} bool should_go(int u) {
double dd, tt;
dd = fabs(p0.x - Left[u]);
if(dd < R) {
tt = sqrt(R*R-dd*dd);
if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;
if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;
if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;
if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;
}
dd = fabs(p0.x - Right[u]);
if(dd < R) {
tt = sqrt(R*R-dd*dd);
if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;
if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;
if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;
if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;
}
dd = fabs(p0.y - Button[u]);
if(dd < R) {
tt = sqrt(R*R-dd*dd);
if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;
if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;
if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;
if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;
}
dd = fabs(p0.y - Top[u]);
if(dd < R) {
tt = sqrt(R*R-dd*dd);
if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;
if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;
if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;
if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;
}
return false;
} void dfs(int u) {
double _x = node[u].x, _y = node[u].y;
double _r = sqrt((_x-p0.x)*(_x-p0.x)+(_y-p0.y)*(_y-p0.y));
if(_r < R) {
R = _r;
ansid = u;
}
int l = tree[u][], r = tree[u][];
if(l && should_go(l)) dfs(l);
if(r && should_go(r)) dfs(r);
return;
} void back_method() {
go_method();
int cur = ansid, precur;
while(cur != ) {
precur = cur;
cur = parent[cur];
int l = tree[cur][], r = tree[cur][];
if(precur == l && r && should_go(r)) dfs(r);
else if(precur == r && l && should_go(l)) dfs(l);
}
} void debug_dfs(int u) {
printf("dep[%d] = %d; (%.2lf,%.2lf); left:%.2lf,right:%.2lf,button:%.2lf,top:%.2lf\n",
u, depth[u], node[u].x , node[u].y, Left[u], Right[u], Button[u], Top[u]);
int l = tree[u][], r = tree[u][];
if(l) debug_dfs(l);
if(r) debug_dfs(r);
}

k近邻算法C++二维情况下的实现的更多相关文章

  1. K近邻算法(二)

    def KNN_classify(k, X_train, y_train, x): assert 1 <= k <= X_train.shape[0], "k must be v ...

  2. 02-16 k近邻算法

    目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...

  3. python 机器学习(二)分类算法-k近邻算法

      一.什么是K近邻算法? 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. 来源: KNN算法最早是由Cover和Hart提 ...

  4. 机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)

    六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocess ...

  5. <转>从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    转自 http://blog.csdn.net/likika2012/article/details/39619687 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经 ...

  6. 用Python从零开始实现K近邻算法

    KNN算法的定义: KNN通过测量不同样本的特征值之间的距离进行分类.它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别.K通 ...

  7. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    转载自:http://blog.csdn.net/v_july_v/article/details/8203674/ 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说: ...

  8. 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!

    1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...

  9. 数据挖掘算法(一)--K近邻算法 (KNN)

    数据挖掘算法学习笔记汇总 数据挖掘算法(一)–K近邻算法 (KNN) 数据挖掘算法(二)–决策树 数据挖掘算法(三)–logistic回归 算法简介 KNN算法的训练样本是多维特征空间向量,其中每个训 ...

随机推荐

  1. 去duplicate的方法

    1.什么是duplicate,为什么要去除. 什么是duplicate:这是在建库的过程后,对已连有接头的DNA片段进行扩增,然后去接flowcell.之所以在建库后扩增,这是由于接flowcell的 ...

  2. R中的运算符,条件语句,控制语句

    1.运算符 算术运算符:+,-,*,/ 关系运算符:==,!=,>,>=,<,<= 逻辑运算符:&,|,&&,||,! &和|称为短逻辑符,&a ...

  3. 七 、linux正则表达式

    为处理大量的字符串而定义的一套规则和方法 1)linux正则表达式以行为单位处理 2)alians grep = “grep –color=auto”,让匹配的内容显示颜色 3)注意字符集,expor ...

  4. photoshop cs5 序列号永久序列号永久激活破解方法

    photoshop cs5 序列号永久序列号永久激活破解方法 (2016-12-10 07:52:21) 转载▼ 标签: it   PhotoShop CS5 /ps5  序列号激活码 1330-15 ...

  5. Linux与Android 多点触摸协议【转】

    本文转载自:http://blog.csdn.net/xubin341719/article/details/7833277 一.Linux与Android 多点触摸协议 为了使用功能强大的多点触控设 ...

  6. Oracle给不同组数据添加顺序

    SELECT DENSE_RANK() OVER(ORDER BY TABLESPACE_NAME),T.* FROM USER_TABLES T;

  7. MapReduce-join连接

    join连接 MapReduce能够执行大型数据集间的连接(join)操作.连接操作的具体实现技术取决于数据集的规模及分区方式连接操作如果由mapper执行,则称为“map端连接”:如果由reduce ...

  8. 51nod 1289 大鱼吃小鱼 栈

    1289 大鱼吃小鱼 题目来源: Codility 基准时间限制:1 秒 空间限制:131072 KB 有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条 ...

  9. 用SQL语句删除除了id不同,其他都相同的学生表信息

    delete from <table_name> wehere id not in (select max(id) from <table_name> group by < ...

  10. FMX.TTabControl_多行

    1. 重载 TTabControl.RealignTabs; 2. 3.