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. Ubuntu启动自动登录并启动程序

    最近在研究Ubuntu,需要在系统启动之后自动登录,并且启动某个程序. 手上拿到的系统只有一个空桌面,其他嘛也没有,鼠标右键也不管用.于是借助自己的虚拟机研究发现,自动启动程序配置文件在: /home ...

  2. P4317 花神的数论题

    题目 洛谷 数学方法学不会%>_<% 做法 爆搜二进制下存在\(i\)位\(1\)的情况,然后快速幂乘起来 My complete code #include<bits/stdc++ ...

  3. 自定义美化UL OL发光列表

    在线演示 本地下载

  4. Cocos2d-x项目移植到WP8系列之一:前传

    原文链接: http://www.cnblogs.com/zouzf/p/3969993.html 许久没动笔了,随想一直都有动笔的想法,但拖来拖去,归根到底还是一个懒字吧 .发现人的惰性真是太强大了 ...

  5. Spring Cloud Stream消息总线

    Springcloud 里面对于MQ的整合一个是前一篇的消息总线一个是本文介绍的消息驱动 大体要学习这么几个知识点: 课题:SpringCloud消息驱动Stream1.什么是SpringCloud消 ...

  6. 【bzoj1899】[Zjoi2004]Lunch 午餐(贪心+dp)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1899 显然为了节省时间,吃饭慢的人要先打饭.于是我们可以先把所有人按吃饭时间排序,于是 ...

  7. CentOS 7 安装 docker-compose

    compose是用来在docker中定义和运行复杂应用的小工具,比如在一个文件中定义多个容器,只用一行命令就可以让一切就绪并运行. 安装pip: 这里显示,找不到相应的包?? 说没有python-pi ...

  8. Redis 创建多个端口

    默认的是6379 可以用6380,6381开启多个 1.开启 ./redis-server ../etc/redis.6380.conf & 2.链接 redis-cli -p 6380 查看 ...

  9. MySQL数据copy

    摘自http://database.51cto.com/art/201011/234776.htm 1. 下面这个语句会拷贝表结构到新表newadmin中. (不会拷贝表中的数据) CREATE TA ...

  10. keystone uwsgi failed

    ~$ /usr/local/bin/uwsgi /etc/keystone/keystone-uwsgi-public.ini[uWSGI] getting INI configuration fro ...