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. SOA 面向服务架构 阅读笔记(一)

    Service Oriented Architecture 面向服务架构 学习笔记(一) 1.业务自由 1.1  在很多企业中,业务和IT技术是各自独立的,无法使用通用的统一语言进行管理. 1.2  ...

  2. asp.net 5 (mvc 6) 获取网站的物理路径

    public static IApplicationEnvironment GetApplication(this RazorPage page) { var ae = page.Context.Re ...

  3. Python httpServer服务器(初级)

    使用原生的python开发的web服务器,入门级! #!/usr/bin/python # -*- coding: UTF-8 -*- import os #Python的标准库中的os模块包含普遍的 ...

  4. MyEclipse+PyDev配置搭建Python开发环境

    打开help-> install from catalog 输入pydev查找并安装pydev 根据提示进行安装,安装完后重启myeclipse

  5. Spring初学之annotation实现AOP前置通知和后置通知

    实现两个整数的加减乘除,并在每个计算前后打印出日志. ArithmeticCalculator.java: package spring.aop.impl; public interface Arit ...

  6. Python之Django总结

    一.Django 总结django知识点   一.视图函数:     请求对象-----------request:           1.HttpRequest.body:         请求原 ...

  7. 如何创建效率高sql-建立索引

      我们做开发的人员,虽说自己不是专业从事数据库方面研究的(如DBA),但很多时候,公司没有专门的DBA,所以拿到具体的项目中,整体的数据库设计都是开发人员自己写的,随着时间的推移,加上开发经验的增长 ...

  8. spring:自定义限定符注解@interface, 首选bean

    spring:自定义限定符注解@interface, 首选bean 1.首选bean 在声明bean的时候,通过将其中一个可选的bean设置为首选(primary)bean能够避免自动装配时的歧义性. ...

  9. 计时器(C#)

    很多项目要用到计时器,我就自己包装了一个,倒计时还没加,有时间再加上吧.持续更新 using UnityEngine; using UnityEngine.UI; /// <summary> ...

  10. openGL 3.3+ 场景渲染

    这个渲染程序是研一下学期的计算机图形学课程大作业,花了两三周学习使用了下 openGL 3.3+ 库,整合出了这个渲染程序,完成于 2013/07/05. 相对于老版本的库,新版本更开放,给了程序员更 ...