k近邻算法C++二维情况下的实现
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++二维情况下的实现的更多相关文章
- K近邻算法(二)
def KNN_classify(k, X_train, y_train, x): assert 1 <= k <= X_train.shape[0], "k must be v ...
- 02-16 k近邻算法
目录 k近邻算法 一.k近邻算法学习目标 二.k近邻算法引入 三.k近邻算法详解 3.1 k近邻算法三要素 3.1.1 k值的选择 3.1.2 最近邻算法 3.1.3 距离度量的方式 3.1.4 分类 ...
- python 机器学习(二)分类算法-k近邻算法
一.什么是K近邻算法? 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别. 来源: KNN算法最早是由Cover和Hart提 ...
- 机器学习(四) 机器学习(四) 分类算法--K近邻算法 KNN (下)
六.网格搜索与 K 邻近算法中更多的超参数 七.数据归一化 Feature Scaling 解决方案:将所有的数据映射到同一尺度 八.scikit-learn 中的 Scaler preprocess ...
- <转>从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
转自 http://blog.csdn.net/likika2012/article/details/39619687 前两日,在微博上说:“到今天为止,我至少亏欠了3篇文章待写:1.KD树:2.神经 ...
- 用Python从零开始实现K近邻算法
KNN算法的定义: KNN通过测量不同样本的特征值之间的距离进行分类.它的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别.K通 ...
- 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法
转载自:http://blog.csdn.net/v_july_v/article/details/8203674/ 从K近邻算法.距离度量谈到KD树.SIFT+BBF算法 前言 前两日,在微博上说: ...
- 一看就懂的K近邻算法(KNN),K-D树,并实现手写数字识别!
1. 什么是KNN 1.1 KNN的通俗解释 何谓K近邻算法,即K-Nearest Neighbor algorithm,简称KNN算法,单从名字来猜想,可以简单粗暴的认为是:K个最近的邻居,当K=1 ...
- 数据挖掘算法(一)--K近邻算法 (KNN)
数据挖掘算法学习笔记汇总 数据挖掘算法(一)–K近邻算法 (KNN) 数据挖掘算法(二)–决策树 数据挖掘算法(三)–logistic回归 算法简介 KNN算法的训练样本是多维特征空间向量,其中每个训 ...
随机推荐
- $.queue() 与 $.dequeue() -- 队列
JQuery 运用队列为动画模块服务,但好像它应该有更多用处,我觉得的,那试试就知道咯. 简单的来讲,它就是形成队列和出列, 也就因此可以进行很有规律的回调和延时了呀(暂停感觉有难度),当然这就是后面 ...
- PHP扩展模块Pecl、Pear以及Perl的区别
一.简短总结:pear:一个书写的比较规范,国外较流行的工具箱代码集pecl:php扩展包,但不属于php基本扩展范围perl:一种早于php出现的脚本级语言,php借鉴了他的正则表达式部分 二.Pe ...
- redis 数据导入导出,实例内db迁移
源实例db0迁移至目标实例db1 [root@172.20.0.1 ~]# cat redis_mv.sh #!/bin/bash redis-cli -h -a password -n keys & ...
- 《机器学习实战-KNN》—如何在cmd命令提示符下运行numpy和matplotlib
问题背景:好吧,文章标题是瞎取得.平常用cmd运行python代码问题不大,我在学习<机器学习实战>这本书时,发现cmd无法运行import numpy as np以及import mat ...
- 使用eclipse搭建第一个python+Django的web开发实例
python+Django的web开发实例 一.创建一个项目如果这是你第一次使用Django,那么你必须进行一些初始设置.也就是通过自动生成代码来建立一个Django项目--一个Django项目的 ...
- springmvc时间类型值传输映射
背景:springmvc4.3.2+spring4.3.2+mybatis3.4.1 当前台传递的参数有时间类型时,封装的vo对象也有对应的时间类型与之对象, 但是如果此时用对象去接收后台会报错,类型 ...
- Windows batch: call more than one command in a FOR loop?
https://stackoverflow.com/questions/2252979/windows-batch-call-more-than-one-command-in-a-for-loop U ...
- 2017 GDS 全球域名大会7月7日举行
2017年域名行业历经产业波澜,引发域名圈内对域名价值衍生及商业模式的探索.如今无论域名注册商.域名交易平台.域名拍卖平台都在寻找更好的商业模式,开启域名行业新航向. 7月,在中国域名之都厦门将掀起一 ...
- mysql在表的某一位置增加一列的命令
如果想在一个已经建好的表中添加一列,可以用诸如: alter table t1 add column addr varchar(20) not null; 这条语句会向已有的表t1中加入一列addr, ...
- ubuntu/centos printk 终端中不能打印信息及解决办法
今天用ubuntu来调试信息,printk死活打印不出信息,即使把级别跳到<0>,即KERN_ALERT也不行,后再搜了好长时间网络, 这个地址:http://bbs.chinaunix. ...