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

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

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <iostream>
  4. #include <algorithm>
  5. #include <vector>
  6. #include <queue>
  7. #include <cmath>
  8. using namespace std;
  9. const double inf = 1000.0;
  10. const int maxn = ;
  11.  
  12. void debug_dfs(int);
  13. void go_method();
  14. bool should_go(int);
  15. void dfs(int);
  16. void back_method();
  17.  
  18. double Left[maxn], Right[maxn], Top[maxn], Button[maxn];
  19. int tree[maxn][], parent[maxn], cnt = , n;
  20. int depth[maxn];
  21. struct point {
  22. double x, y;
  23. };
  24. vector<point> points[maxn];
  25. queue<int> q;
  26. point tmp[maxn];
  27. point node[maxn];
  28. point p0, anspoint;
  29. int ansid;
  30. double R;
  31. bool cmpx(point a, point b) {
  32. return a.x < b.x;
  33. }
  34. bool cmpy(point a, point b) {
  35. return a.y < b.y;
  36. }
  37. int main() {
  38. scanf("%d", &n);
  39. point p;
  40. for(int i=;i<n;i++) {
  41. scanf("%lf%lf", &p.x , &p.y);
  42. points[cnt].push_back(p);
  43. }
  44. depth[cnt] = ;
  45. Left[cnt] = Button[cnt] = -inf;
  46. Right[cnt] = Top[cnt] = inf;
  47. parent[cnt] = -;
  48. q.push(cnt);
  49. while(!q.empty()) {
  50. int u = q.front();
  51. q.pop();
  52. vector<point> &ps = points[u];
  53. int sz = ps.size();
  54. if(sz <= ) continue;
  55. if(sz == ) {
  56. node[u] = ps[];
  57. continue;
  58. }
  59. for(int i=;i<sz;i++) {
  60. tmp[i] = ps[i];
  61. }
  62. if(depth[u] % == ) sort(tmp, tmp+sz, cmpx);
  63. else sort(tmp, tmp+sz, cmpy);
  64. int mid = sz / ;
  65. node[u] = tmp[mid];
  66. int lsz = mid, rsz = sz - - mid;
  67. if(lsz) {
  68. int l = ++cnt;
  69. tree[u][] = l;
  70. parent[l] = u;
  71. depth[l] = depth[u] + ;
  72. q.push(l);
  73. for(int i=;i<mid;i++) points[l].push_back(tmp[i]);
  74. Left[l] = Left[u]; Right[l] = Right[u]; Top[l] = Top[u]; Button[l] = Button[u];
  75. if(depth[u] % == ) Right[l] = tmp[mid].x;
  76. else Top[l] = tmp[mid].y;
  77. }
  78. if(rsz) {
  79. int r = ++cnt;
  80. tree[u][] = r;
  81. parent[r] = u;
  82. depth[r] = depth[u] + ;
  83. q.push(r);
  84. for(int i=mid+;i<sz;i++) points[r].push_back(tmp[i]);
  85. Left[r] = Left[u]; Right[r] = Right[u]; Top[r] = Top[u]; Button[r] = Button[u];
  86. if(depth[u] % == ) Left[r] = tmp[mid].x;
  87. else Button[r] = tmp[mid].y;
  88. }
  89.  
  90. }
  91. scanf("%lf%lf", &p0.x, &p0.y);
  92. back_method();
  93.  
  94. printf("(%.2lf,%.2lf)\n", node[ansid].x, node[ansid].y);
  95.  
  96. //debug_dfs(0);
  97. return ;
  98. }
  99.  
  100. void go_method() {
  101. int cur = ;
  102. ansid = cur;
  103. while(true) {
  104. int l = tree[cur][], r = tree[cur][];
  105. if(l && Left[l] <= p0.x && Right[l] >= p0.x && Button[l] <= p0.y && Top[l] >= p0.y) {
  106. cur = l;
  107. ansid = l;
  108. } else if(r && Left[r] <= p0.x && Right[r] >= p0.x && Button[r] <= p0.y && Top[r] >= p0.y) {
  109. cur = r;
  110. ansid = r;
  111. } else {
  112. R = sqrt((p0.x-node[ansid].x)*(p0.x-node[ansid].x)+(p0.y-node[ansid].y)*(p0.y-node[ansid].y));
  113. return;
  114. }
  115. }
  116. }
  117.  
  118. bool should_go(int u) {
  119. double dd, tt;
  120. dd = fabs(p0.x - Left[u]);
  121. if(dd < R) {
  122. tt = sqrt(R*R-dd*dd);
  123. if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;
  124. if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;
  125. if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;
  126. if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;
  127. }
  128. dd = fabs(p0.x - Right[u]);
  129. if(dd < R) {
  130. tt = sqrt(R*R-dd*dd);
  131. if(p0.y-tt > Button[u] && p0.y-tt < Top[u]) return true;
  132. if(p0.y+tt > Button[u] && p0.y+tt < Top[u]) return true;
  133. if(Button[u] > p0.y-tt && Button[u] < p0.y+tt) return true;
  134. if(Top[u] > p0.y-tt && Top[u] < p0.y+tt) return true;
  135. }
  136. dd = fabs(p0.y - Button[u]);
  137. if(dd < R) {
  138. tt = sqrt(R*R-dd*dd);
  139. if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;
  140. if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;
  141. if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;
  142. if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;
  143. }
  144. dd = fabs(p0.y - Top[u]);
  145. if(dd < R) {
  146. tt = sqrt(R*R-dd*dd);
  147. if(p0.x-tt > Left[u] && p0.x+tt < Right[u]) return true;
  148. if(p0.x+tt > Left[u] && p0.x+tt < Right[u]) return true;
  149. if(Left[u] > p0.x-tt && Left[u] < p0.x+tt) return true;
  150. if(Right[u] > p0.x-tt && Right[u] < p0.x+tt) return true;
  151. }
  152. return false;
  153. }
  154.  
  155. void dfs(int u) {
  156. double _x = node[u].x, _y = node[u].y;
  157. double _r = sqrt((_x-p0.x)*(_x-p0.x)+(_y-p0.y)*(_y-p0.y));
  158. if(_r < R) {
  159. R = _r;
  160. ansid = u;
  161. }
  162. int l = tree[u][], r = tree[u][];
  163. if(l && should_go(l)) dfs(l);
  164. if(r && should_go(r)) dfs(r);
  165. return;
  166. }
  167.  
  168. void back_method() {
  169. go_method();
  170. int cur = ansid, precur;
  171. while(cur != ) {
  172. precur = cur;
  173. cur = parent[cur];
  174. int l = tree[cur][], r = tree[cur][];
  175. if(precur == l && r && should_go(r)) dfs(r);
  176. else if(precur == r && l && should_go(l)) dfs(l);
  177. }
  178. }
  179.  
  180. void debug_dfs(int u) {
  181. printf("dep[%d] = %d; (%.2lf,%.2lf); left:%.2lf,right:%.2lf,button:%.2lf,top:%.2lf\n",
  182. u, depth[u], node[u].x , node[u].y, Left[u], Right[u], Button[u], Top[u]);
  183. int l = tree[u][], r = tree[u][];
  184. if(l) debug_dfs(l);
  185. if(r) debug_dfs(r);
  186. }

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. $.queue() 与 $.dequeue() -- 队列

    JQuery 运用队列为动画模块服务,但好像它应该有更多用处,我觉得的,那试试就知道咯. 简单的来讲,它就是形成队列和出列, 也就因此可以进行很有规律的回调和延时了呀(暂停感觉有难度),当然这就是后面 ...

  2. PHP扩展模块Pecl、Pear以及Perl的区别

    一.简短总结:pear:一个书写的比较规范,国外较流行的工具箱代码集pecl:php扩展包,但不属于php基本扩展范围perl:一种早于php出现的脚本级语言,php借鉴了他的正则表达式部分 二.Pe ...

  3. redis 数据导入导出,实例内db迁移

    源实例db0迁移至目标实例db1 [root@172.20.0.1 ~]# cat redis_mv.sh #!/bin/bash redis-cli -h -a password -n keys & ...

  4. 《机器学习实战-KNN》—如何在cmd命令提示符下运行numpy和matplotlib

    问题背景:好吧,文章标题是瞎取得.平常用cmd运行python代码问题不大,我在学习<机器学习实战>这本书时,发现cmd无法运行import numpy as np以及import mat ...

  5. 使用eclipse搭建第一个python+Django的web开发实例

    python+Django的web开发实例   一.创建一个项目如果这是你第一次使用Django,那么你必须进行一些初始设置.也就是通过自动生成代码来建立一个Django项目--一个Django项目的 ...

  6. springmvc时间类型值传输映射

    背景:springmvc4.3.2+spring4.3.2+mybatis3.4.1 当前台传递的参数有时间类型时,封装的vo对象也有对应的时间类型与之对象, 但是如果此时用对象去接收后台会报错,类型 ...

  7. 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 ...

  8. 2017 GDS 全球域名大会7月7日举行

    2017年域名行业历经产业波澜,引发域名圈内对域名价值衍生及商业模式的探索.如今无论域名注册商.域名交易平台.域名拍卖平台都在寻找更好的商业模式,开启域名行业新航向. 7月,在中国域名之都厦门将掀起一 ...

  9. mysql在表的某一位置增加一列的命令

    如果想在一个已经建好的表中添加一列,可以用诸如: alter table t1 add column addr varchar(20) not null; 这条语句会向已有的表t1中加入一列addr, ...

  10. ubuntu/centos printk 终端中不能打印信息及解决办法

    今天用ubuntu来调试信息,printk死活打印不出信息,即使把级别跳到<0>,即KERN_ALERT也不行,后再搜了好长时间网络, 这个地址:http://bbs.chinaunix. ...