KD - Tree 学习笔记

kd-tree详解 kd-tree适用的范围:        二维平面最近点对之间的操作,动态维护、询问、查询等。包括曼哈顿距离和欧几里德距离。曼哈顿距离和欧几里德距离:1.曼哈顿距离曼哈顿距离又称Manhattan distance,还见到过更加形象的,叫出租车距离的。具体贴一张图,应该就能明白。上图摘自维基百科,红蓝黄皆为曼哈顿距离,绿色为欧式距离。2.欧式距离欧式距离又称欧几里得距离或欧几里得度量(Euclid... 阅读详情

(这本是 P4169 的一篇无法提交的题解)

而 KD - Tree 本身在竞赛中的应用就比较少,又几乎不作为正解出现,所以这里只拿一道例题来举例讲解

题意:

给定一个二维点集 S ,每次有两种操作:

操作 1 : 往点集 S 中加入一个点

操作 2 : 给定一个点 ( x , y ) (x, y) (x,y) ,询问该点到点集 S 中每个点曼哈顿距离的最小值

两点 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1, y_1), (x_2, y_2) (x1​,y1​),(x2​,y2​) 之间的曼哈顿距离定义为:

∣ x 1 − x 2 ∣ − ∣ y 1 − y 2 ∣ |x_1 - x_2| - |y_1 - y_2| ∣x1​−x2​∣−∣y1​−y2​∣

题解:

这题正解是一个 O ( ( n + m ) log ⁡ 2 2   ( n + m ) ) O((n + m) \log_2^2~ (n + m)) O((n+m)log22​ (n+m)) 复杂度的做法,需要用到 CDQ 分治

不过既然是 KD - Tree 的学笔,我们就用 KD - Tree 来做这道题

首先来介绍一下 KD - Tree :


1. 定义 & 前置知识

KD - Tree ,原名 K - Dimension Tree ,是一种可以高效处理 k 维空间信息的数据结构

(然而 OI 中很少考到高维的 DS 题目)

(微信步数显然不是 DS 题目吧)

所以 KD - Tree 在 OI 中的应用大多数是二维(例如这道题),少数会有三维

而且 KD - Tree 据说可以配合其它的一些算法 比如乱搞 来获得较高分数

在学习 KD - Tree 之前,你需要了解如下东西:

  • 平衡树(这里特指替罪羊树)

  • STL 中的 nth_element 函数

没了,就这些,所以 KD - Tree 的入门是比较简单的,学会了上手就会很快

2. 建树过程

类似平衡树,KD - Tree 是一种 BST

但是和 BST 不同,在 k 维空间中,KD - Tree 每个结点参与比较的键值是有 k 个的(即每一维的坐标)

不过 KD - Tree 在检索的时候仍然能保证一定的次序

我们只需要在每一个深度都定义一个参与比较的维度,那么这样在检索时,每次究竟是往左子树走还是往右子树走,只要看这个点在当前检索到的深度的“比较维度”上的键值是多少即可

建树的算法已经给你了,关键是如何选择恰当的方式优化,避免像 BST 一样退化成链

那么有两个问题:

  1. 每个深度怎样选维度?

  2. 每个深度选好维度后怎样选点?

对于第一个问题,我们可以选择 1 ~ k 维轮流来

但是有一种更优的选择方式:选择方差最大的一维,具体证明不明,而且实现据说极为复杂

(识相点就选第一种吧,反正很少有出题人会想到要卡你)

对于第二个问题,显然选这个维度的中位数即可,这样左右两边的结点数是相等的

以上两种方式基本可以保证建树时间复杂度为 O ( n log ⁡ 2 n ) O(n\log_2n) O(nlog2​n),深度为 O ( log ⁡ 2 n ) O(\log_2n) O(log2​n)

具体实现时,中位数可以使用 STL 中的 nth_element 函数,不会影响复杂度,用法请上网查找

这样讲会很抽象,给一张例图:

首先我们以横坐标为关键字,找到这一维的中位数

排序后即为:

A , H , C , B , E , D , G , F A,H,C,B,E,D,G,F A,H,C,B,E,D,G,F

我们选择中位数 B 作为根节点,此时可以把所有点分成两个部分:

那么我们递归处理左右子树,此时关键字变成纵坐标

左子树排好序后为: A , C , H A,C,H A,C,H,取中位数 C 作为 B 点的左儿子,继续递归 ⋯ ⋯ \cdots\cdots ⋯⋯

右子树排好序后为: D , F , G , E D,F,G,E D,F,G,E,取中位数 F 做为 B 点的右儿子,继续递归 ⋯ ⋯ \cdots\cdots ⋯⋯

那么建出来的 KD - Tree 如下图:

3. 插入 & 删除

插入操作很简单,类似 BST,我们直接通过检索找到新结点应该插入的位置即可

但是只要出题人想卡你,把新结点都放在一个位置,这样 KD - Tree 的深度越来越高,整颗树越来越不平衡,怎么办?

这个时候,替罪羊树的重构思想就派上用场了

我们是先钦定一个“平衡因子” α \alpha α(一般取 0.75 最优),当插入某个结点后,某个子树的大小超过了以它父亲为根的子树大小乘上 α \alpha α 时,我们直接把整颗子树拿出来重构

表达式:

s i z e ( f a t h e r ) ∗ α < s i z e ( l e f t c h i l d   o r   r i g h t c h i l d ) size(father) * \alpha < size(leftchild ~ or ~ rightchild) size(father)∗α<size(leftchild or rightchild)

但是每次可能会有多个满足条件的结点,取出深度最小的结点重构即可

(实际上本题对于每个满足条件的点都可以选择暴力重构,洛谷上不会超时)

删除操作稍微有点复杂,因为 KD - Tree 是比较偏静态的数据结构

我们可以采用惰性删除的方法,删除时先给这个点打标记,并更新它的祖先,到重构时再真正从树的结构里删去

然而如果一个子树中删除掉的结点过多,使得未被删去的结点数小于子树总结点数乘上 α \alpha α,我们同样需要重构(这样就可以爽快地删掉那些本该被删的结点了)

带重构的 KD - Tree,采用势能分析法,均摊时间复杂度仍然是 O ( n log ⁡ 2 n ) O(n\log_2n) O(nlog2​n) 的


回到这题,我们有一个显然的做法,就是先建好 KD - Tree,然后对于每次询问遍历整颗 KD - Tree,求出最短哈密顿距离

显然 TLE

显然要剪枝

我们需要考虑一种最优性剪枝

比如现在已经求得的答案是 a n s ans ans,现在所在的结点是 n o w now now

我们一定要进入 n o w now now 的左右子树吗?并不一定

类似 A ∗ A* A∗,我们可以用一个估价函数,求出一个理论上一定小于等于实际距离的最短距离

什么意思?就是说当前询问的点对于某颗子树估计的最短距离,一定要小于等于真实的最短距离

如果这个估计出来的最短距离大于等于 a n s ans ans,那么显然实际的最短距离一定会大于等于这个估计距离,也就大于等于 a n s ans ans,因此,我们进入这颗子树,对答案不会有任何贡献

如何估计呢?我们对于一颗子树,维护一个最小的,可以包括子树内所有点的矩形

那么这个点到这个矩形的最小曼哈顿距离,一定小于实际上的最小曼哈顿距离

这样的算法已经很优秀了,但是即使吸氧也会 T 掉一个点

我们还可以进行一个优化:

假设左子树的估价为 l e f t v a l u e leftvalue leftvalue,右子树的估价为 r i g h t v a l u e rightvalue rightvalue

如果 l e f t v a l u e < r i g h t v a l u e leftvalue < rightvalue leftvalue<rightvalue,我们实际上可以先递归左子树,再递归右子树

这样,当进入左子树时,我们有望可以获得更小的 a n s ans ans ,然后就有一定概率不会进入右子树

以上所有操作的理论复杂度为 O ( ( n + m ) n + m ) O((n + m) \sqrt{n + m}) O((n+m)n+m ​),实际则不是很稳定,要注意常数不要过大

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<algorithm>

#define MAXN 600005
#define INF 0x3F3F3F3F

#define up(i, l, r) for(int i = (l); i <= (r); i = -~i)
#define down(i, l, r) for(int i = (l); i >= (r); i--)

using i64 = long long;
using namespace std;

namespace IO
{
	int f; char c;

	template<typename T> inline void _Read(T &v)
	{
		v = 0; f = 1; c = getchar();
		while(!isdigit(c)) { if(c == '-') f = -1; c = getchar(); }
		while(isdigit(c)) { v = (v << 3) + (v << 1) + (int)(c - '0'); c = getchar(); }
		v *= f;
		return;
	}

	template<typename T> inline void _Write(T k)
	{
		if(k < 0) { putchar('-'); k = -k; }
		if(k > 9) _Write(k / 10);
		putchar((char)(k % 10 + '0'));
		return;
	}

	inline int Read() { int v; _Read(v); return v; }
	inline i64 Read64() { i64 v; _Read(v); return v; }
	inline void Write(int v, char ed = '\n') { _Write(v); putchar(ed); return; }
	inline void Write64(i64 v, char ed = '\n') { _Write(v); putchar(ed); return; }
}

using IO :: Read;
using IO :: Read64;
using IO :: Write;
using IO :: Write64;

int n, m, cnt, rt, top, stk[MAXN];
bool wyh;
const double Alpha = 0.75;

struct Point { int a[2]; bool operator < (const Point &t) const { return a[wyh] < t.a[wyh]; } } p[MAXN]; 

struct KD_Tree
{
	int ls[MAXN], rs[MAXN], si[MAXN], mx[MAXN][2], mi[MAXN][2];
	Point val[MAXN];

	inline int New_Node() { return top ? stk[top--] : ++cnt; }

	inline int Pushup(int now)
	{
		up(i, 0, 1)
		{
			mx[now][i] = mi[now][i] = val[now].a[i];
			if(ls[now]) mx[now][i] = max(mx[now][i], mx[ls[now]][i]), mi[now][i] = min(mi[now][i], mi[ls[now]][i]);
			if(rs[now]) mx[now][i] = max(mx[now][i], mx[rs[now]][i]), mi[now][i] = min(mi[now][i], mi[rs[now]][i]);
		}
		return si[now] = si[ls[now]] + si[rs[now]] + 1, now;
	}

	inline int Build(int l, int r, int dep)
	{
		wyh = dep ^ 1; int mid = (l + r) >> 1; nth_element(p + l, p + mid, p + r + 1);
		int now = New_Node(); val[now] = p[mid];
		ls[now] = l < mid ? Build(l, mid - 1, dep + 1) : 0, rs[now] = mid < r ? Build(mid + 1, r, dep + 1) : 0;
		return Pushup(now);
	}

	inline void Pia(int now, int tot)
	{
		if(ls[now]) Pia(ls[now], tot);
		p[tot + si[ls[now]] + 1] = val[now], stk[++top] = now;
		if(rs[now]) Pia(rs[now], tot + si[ls[now]] + 1);
		return;
	}

	inline void Check(int &now, int dep)
	{
		if((double)si[ls[now]] > Alpha * si[now] || (double)si[rs[now]] > Alpha * si[now]) Pia(now, 0), now = Build(1, si[now], dep);
		return;
	}

	inline void Insert(int &now, Point ins, int dep)
	{
		if(!now) return now = New_Node(), val[now] = ins, ls[now] = rs[now] = 0, Pushup(now), void();
		if(ins.a[dep ^ 1] <= val[now].a[dep ^ 1]) Insert(ls[now], ins, dep + 1);
		else Insert(rs[now], ins, dep + 1);
		return Pushup(now), Check(now, dep);
	}

	inline int Dist(Point p, Point q) { return abs(p.a[0] - q.a[0]) + abs(p.a[1] - q.a[1]); }

	inline int Get_Dis(Point k, int c)
	{
		int res = 0;
		up(i, 0, 1) res += max(0, k.a[i] - mx[c][i]) + max(0, mi[c][i] - k.a[i]);
		return res;
	}

	inline void Query(int now, Point qry, int &ans)
	{
		ans = min(ans, Dist(qry, val[now]));
		int L = INF, R = INF;
		if(ls[now]) L = Get_Dis(qry, ls[now]); 
		if(rs[now]) R = Get_Dis(qry, rs[now]);
		if(L < R)
		{
			if(L < ans) Query(ls[now], qry, ans);
			if(R < ans) Query(rs[now], qry, ans);
		}
		else
		{
			if(R < ans) Query(rs[now], qry, ans);
			if(L < ans) Query(ls[now], qry, ans);
		}
		return;
	}
} kdt;

int main()
{
	n = Read(), m = Read();
	up(i, 1, n) p[i].a[0] = Read(), p[i].a[1] = Read();
	rt = kdt.Build(1, n, 1);
	while(m--)
	{
		int op = Read();
		Point tmp; tmp.a[0] = Read(), tmp.a[1] = Read();
		if(op & 1) kdt.Insert(rt, tmp, 1);
		else
		{
			int ans = INF;
			kdt.Query(rt, tmp, ans);
			Write(ans);
		}
	}
	return 0;
}

E N D \mathit{END} END

KD Tree学习笔记 KD Tree学习笔记 KD Tree 是一种用于多维数点的数据结构(一般是二维)。它并不特别复杂,本质其实很暴力,和替罪羊树与线段树都比较类似。 大致思路:每次把点分为尽可能平衡的两半,然后通过类似线段树的方式拆分查询区间,以此控制复杂度。 算法流程 构建: 如果已经给定了一些元素(k维),构建kdtree采用以下的方式: 首先,将当前区间按照第d维的中间数左右分段。d每分一层便换到下一个维度,... 阅读详情

相关推荐

[学习笔记]kd-tree

kd-tree学习笔记

YveH 3016

[学习笔记] [机器学习] 3. KNN( K-近邻算法、距离度量:曼哈顿距离,切比雪夫距离、K值选择、kd树、鸢尾花种类预测、特征工程、交叉验证、网格搜索、Facebook签到位置、数据分割)

K-近邻算法、距离度量:曼哈顿距离,切比雪夫距离、K值选择、kd树、鸢尾花种类预测、特征工程、交叉验证、网格搜索、Facebook签到位置、数据分割

Le0v1n 的博客 6161

KD-Tree学习笔记

KD-Tree学习笔记

OIljt12138的博客 755

BZOJ 4066 - KDtree + 重构

题目链接:点击这里 解题思路: 这题被强制在线了如果是离线(BZOJ 2683)可以CDQ分治 + 树状数组做. 所以只能用KDtree了. 若每次都将新节点插入原DKT中,最终会导致树会非常的不平衡,而失去了意义,导致超时. 所以我们要设置一个阈值,当节点数到达阈值时就对KDT进行重构保证稳定. #include&lt;cstdio&gt; #include&lt;cs...

过路人丶的博客 397

Rust 与 C/C++:Rust 比 C/C++ 更好还是只是“技能问题”?

对于许多嵌入式系统开发人员而言,的崛起似乎掀起了一股不小的浪潮,特别是在相较于传统的语言,Rust的“内存安全”优势让人眼前一亮。然而,是否可以将Rust作为C/C++的替代品?或者说,Rust是否真的比C/C++更好,抑或它只是一个“技能问题”呢?在嵌入式开发的领域,我观察到,尽管Rust在一些高性能、内存安全敏感的场景中受到了广泛推崇,但它在实际应用中的普及度,特别是在嵌入式领域,依然有限。今天,我会从多个角度探讨这个问题,并且分享一些对于Rust、C/C++以及嵌入式系统开发的个人见解。

qq_63315166的博客 1300

Cosmos Transfer2.5多模态AI模型部署与优化实战

多模态AI技术通过融合文本、图像、代码等不同模态数据,实现跨模态理解与生成。其核心原理基于Transformer架构的注意力机制,结合对比学习实现模态对齐。这类技术在智能内容创作、跨模态搜索等领域具有重要价值,尤其适合电商营销图文生成、UI设计转代码等场景。Cosmos Transfer2.5作为先进的多模态模型,支持8192 tokens长文本窗口和混合模态输入,实测推理速度达17.5 samples/s(T4显卡)。部署时需注意FlashAttention优化可提升3倍长文本处理效率,8-bit量化则能

weixin_29038303的博客 281

K近邻算法的kd树实现

k近邻算法的介绍 k近邻算法是一种基本的分类和回归方法,这里只实现分类的k近邻算法。k近邻算法的输入为实例的特征向量,对应特征空间的点;输出为实例的类别,可以取多类。k近邻算法不具有显式的学习过程,实际上k近邻算法是利用训练数据集对特征向量空间进行划分。将划分的空间模型作为其分类模型。 k近邻算法的三要素 k值的选择:即分类决策时选择...

weixin_33762321的博客 369

SIwave:在 SIwave 中释放计算频率扫描的强大功能

AEDT 的电路工具允许注入正确的电压和电流。要使用电路工具,SIwave 必须首先使用 PI 求解器求解结构的 S 参数。

jkh920184196的博客 1475

Kd-Tree算法原理 最近邻查找

文章出处:http://blog.sina.com.cn/s/blog_6f611c300101bysf.html 本文介绍一种用于高维空间中的快速最近邻和近似最近邻查找技术——Kd-Tree(Kd树)。Kd-Tree,即K-dimensional tree,是一种高维索引树形数据结构,常用于在大规模的高维数据空间进行最近邻查找(Nearest Neighbor)和近似最近邻查找(Approxi...

留下的,留不下的 5249

嵌入式主板系统配置实战:OTG切换、双网共存与开机自启详解

在嵌入式Linux系统开发中,系统配置是连接硬件平台与应用功能的关键桥梁。其核心原理在于通过内核参数、文件系统接口和系统服务等机制,实现对硬件资源和系统行为的精细控制。掌握这些配置技术,对于提升开发效率、保障系统稳定性和实现产品差异化至关重要。无论是工业物联网网关、智能终端还是边缘计算设备,都需要对网络、USB、启动项等基础功能进行可靠配置。本文聚焦于嵌入式主板开发中的高频需求,例如OTG功能模式切换、双网共存路由策略以及基于systemd的开机自启动实现,通过具体的命令和脚本示例,为开发者提供一套可直接复

weixin_30827827的博客 320

论文理解【LLM-Clarification】—— 【QDrawer】Asking the Right Question at the Right Time: Human and Model Unce

本文基于 CoDraw 任务对 LLM 澄清提问的触发方式进行探索,发现模型内部不确定性与人类澄清决策相关性弱,使用不确定性阈值触发澄清提问相比模仿人类提问时机,性能和计算效率都更好

佚失的诗篇 770

KD-tree学习笔记

来源:在ICP算法中,提到在目标点云中寻找若干特征点,然后利用K-D tree寻找这些特征点在参考点云中的最近点。此步骤目的是减少泛时间代价O(logNx) 如上图(a),我们先对待识别的物体的图像进行SIFT特征点的检测和特征点的描述,然后得到了SIFT特征点集合。接下来生成物体目标描述要做的就是对特征点集合进行数据组织,形成一种特殊的表示,其作用是为了加速特征点匹配的过程。所谓的

krystalcui 769

使用OpenTK展示3D点云图像(C#)

图中存在一个空的点,可通过阈值分割过滤掉,然后如何保证某个点必然存在后面两个和它构成三角形的点,用一个2x2的结构元腐蚀阈值分割出的区域,得到剩下所有的点必然每个点可以构成三角形,这种得到三角形的算法效率会非常高。然后还有光照,无光照和有光照效果差异很大,处理光照核心在于得到每个点的法向量,用上面的三角形的两条边构成的向量叉乘,及得到这个点的法向量,输入给着色器处理得到光照的渲染效果,如下面两张图对比。我们需要把点连成面,有很多算法可以实现,但我拿到的图为一张tif格式16位的深度图,如下图。

海盗Isaac 2283

KD-Tree 学习笔记

KD-Tree 学习笔记 SDOI2010 捉迷藏 对于i=1...n,求曼哈顿距离距离i最近和最远的点的距离分别是多少。 思路 KD-Tree 的模板题目。 KD-Tree,实际上就是对一个多维空间进行不断的划分,在一维上类似于二叉搜索树。 如果是多维的,我们可以每一次只划分一维,然后这样不断轮流划分不同的维度。 具体的,对于当前维度的划分,我们最优秀的策略就是取所有点按照当前维度排序...

aizhuji9626的博客 178

[Arcgis插件分享]--在线地图、地图配色

插件介绍:MapOnline在线地图插件是一套由北京茗禾科技有限公司研发的基于ArcGIS的插件工具,用户通过注册“数据禾”网站,即可使用MapOnline实现各种在线地图资源的集成加载,以及网站共享资源的免费下载。包括:谷歌地图、谷歌地球(无偏)、高德地图、天地图(无偏)、搜搜地图、必应地图(无偏)、OSM地图(无偏)、Esri影像(无偏),以及自定义切片的加载。⑤在Arcmap操作窗口上方的菜单栏右键,调用「MapOnlinev1.2.4」②双击安装文件夹内的「MapOnline.esriAddIn」

weixin_59101151的博客 5761

FreeRTOS系统从入门到精通万字保姆级教程

例如,在基于ARM的硬件平台上,可能需要实现针对ARM处理器的上下文切换代码,并确保FreeRTOS能够正确地响应和处理ARM架构的中断。需要注意的是,在删除任务之前应确保任务已经完成了其所有重要的工作,并且没有其他的任务依赖于它,以避免数据丢失或系统不稳定。任务的优先级设定是其中的关键环节。在复杂的系统中,可能会有大量的任务需要同时运行,而这些任务的重要性和紧急程度各不相同。这通常包括创建初始任务(这些任务将负责系统的初始化和后续任务的调度)、设置系统时钟(以确保任务的准时调度和延时功能的正确性)等。

大模型大数据攻城狮的专栏 2069

学习笔记:KD-TREE

前言 一个感觉特别单一的数据结构啊,Po大爷才写两个这个题呢。 然后仔细研究了一下KD-TREE为什么要这样做,发现其中的每一个操作都是很巧妙的。 原理简述(瞎逼逼) KD-Tree确实应该算是计算几何的一种东西了吧,可以看作线段树的高维推广还自带离散功能。 KD-Tree也是一个二叉树,并且除了叶子结点外,每个结点都代表了一堆点,叶子结点则代表了一个,和线段树是很像的。 每个点我...

少主大人殿下的博客 1325

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

【算法竞赛学习笔记】KD-Tree

title : KD-Tree date : 2022-4-7 tags : ACM,数据结构 author : Linno K-D tree K-D树是在k维欧几里得空间中组织点的数据结构。在算法竞赛中,K-D树往往用于在二维平面内的信息检索。具体应用如:多维键值搜索(范围搜索及最邻近搜索)下面我们针对二维平面的KD-Tree进行讲解。 定义 K-D Tree是一颗存储k维信息的二叉树,代表对数据集合的划分,每个结点都对应着一个k维超矩形区域。 ①在一维数据情况下,KD-Tree是一颗二叉搜索树。 ②.

SC_Linno的博客 1559

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

[学习笔记] kd-tree

本文参考这位dalao的题解 前置技能:二叉查找树 其实kd-tree很简单的啦 和BST都差不多的啦 就是在划分的时候把每一维都比较一下就行啦 (\(dalao\)的kd-tree教程) 然而本蒟蒻是完全看不懂啊qwq 于是我们从头讲起吧: step 1 首先,我们回忆一下BST, 它是以一个关键字\(val\),来满足它的两个性质反正大家都知道就懒得写了. 而kd-tree,则是对于一个\(k...

weixin_30951231的博客 191

lab4 & kd-tree 学习笔记

给定n组坐标,构建kd-tree,有m次询问,每次询问给出一个目标坐标,返回到此坐标的最近点坐标(距离计算方法为:曼哈顿距离、欧几里得距离、球坐标距离)[什么是kd-tree]()(详解kd-tree留到part2)

2301_79733054的博客 1010
上一篇: NOIP2021 游记
下一篇: 平衡树学习笔记
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值