在所有的排序算法实现中,只使用比较(Compare)和交换(exchange)两种函数操作。考虑算法的时间复杂度时,也只考虑这两种操作(如果没有交换操作,则考虑数组访问(array access)的代价);考虑空间复杂度时,需考虑排序算法是在原处修改还是新建了一个数组来存储排序结果。
有时候,我们在比较时,只需要比较每个元素的某个特征来对他们排序(以人为元素,我们可能只比较身高,而不比较他们的其他特征)。以下为求简介,统一称为“比较元素”
随便写写
在所有的排序算法实现中,只使用比较(Compare)和交换(exchange)两种函数操作。考虑算法的时间复杂度时,也只考虑这两种操作(如果没有交换操作,则考虑数组访问(array access)的代价);考虑空间复杂度时,需考虑排序算法是在原处修改还是新建了一个数组来存储排序结果。
有时候,我们在比较时,只需要比较每个元素的某个特征来对他们排序(以人为元素,我们可能只比较身高,而不比较他们的其他特征)。以下为求简介,统一称为“比较元素”
花了两三天的工夫,终于搭好了博客。最先是因为忍受不了csdn blog的markdown排版才打算自己建一个博客。从一开始尝试 worldpress 到后来捣鼓 jekyll, 再到现在终于用 hexo 搭好平台,走了不少弯路。
基本的抽象数据类型涉及若干对象的集合以及在这个集合上定义的一些操作,包括添加、删除和集合中的对象等。下面主要以三种基本类型(Bag Stack Queue)来说明。
在许多应用中,二叉搜索树可以工作得很好,然而在最差情况下(插入一个有序序列),它的性能得不到保证。下面介绍一种平衡搜索树,可以在任何情况下保证 O(logN) 的时间复杂度。
理想情况下,我们希望树的形状是完美平衡的,这样的话,查找效率就是 O(lgN);然而,对于不可预料的动态插入操作,保持树形状完美平衡的开销太大。我们稍稍放松对完美平衡的要求,便可以对所有操作提供 O(logN) 的保证
我们现在允许树的一个节点中有两个值(Key),连接着三个子节点(Link),将这样的节点称为3-节点,原来那样的节点称为2-节点。
————————————————————————
一个2-3搜索树要么是空的,要么是:
一个 2-节点,左链接连接着一棵2-3搜索树(所有的值小于当前节点的值),右链接连接着一棵2-3搜索树(所有的值大于当前结点的值)
一个 3-节点,左链接连接着一棵2-3搜索树(所有的值小于当前节点中较小的那个值),中链接连接着一棵2-3搜索树(所有值在当前结点两个值之间),右链接连接着一棵2-3搜索树(所有的值大于当前结点较大的那个值)
————————————————————————
如果一个2-3搜索树的所有空链接到根节点的距离都相等,那么我们就说这棵2-3搜索树是平衡的。
————————————————————————
从根节点开始向下比较,如果与节点中任一值相等,则搜索命中;如果不相等,我们按照左中右连接进行分流;如果遇到空节点,则说明查找失败。
用一个 3-节点 替换掉原来的 2-节点
把3-节点变成一个暂时的4-节点,然后把这个4-节点分成三个2-节点
把3-节点变成一个暂时的4-节点,然后把这个4-节点分成三个2-节点,将父节点变为一个3-节点
向上把每个3-节点变成一个暂时的4-节点,然后把这个4-节点分成三个2-节点,将父节点变为一个暂时的4-节点。由此向上,直到遇到一个2-节点,或到根节点时让整个树增加1层。
————————————————————————
对于一个含有N个元素的2-3树,搜索和插入操作保证最多访问 lgN 个节点
————————————————————————
最自然的方法是利用二分查找树(BST),然后添加一些信息来标记 3-节点
我们把链接分为两种:
特别地,我们用向左倾斜的红链接连接着的两个2-节点来表示一个3-节点
————————————————————————
红黑树是满足下列调节的具有红黑链接的二叉树:
————————————————————————
红黑树即是2-3树,也是BST,所以它结合了BST的高效搜索方法和2-3树的平衡插入特点
在节点的定义里加入一个 bool 变量来表示当前结点与父节点的链接是不是红链接
在红黑书的实现中,我们暂时允许以下情况:
我们用旋转来修正第一种情况
Node rotateLeft(Node h)
{
Node x = h.right;
h.right = x.left;
x.left = h;
x.color = h.color;
h.color = RED;
x.N = h.N;
h.N = 1 + size(h.left) + size(h.right);
return x;
}
Node rotateRight(Node h)
{
Node x = h.left;
h.left = x.right;
x.right = h;
x.color = h.color;
h.color = RED;
x.N = h.N;
h.N = 1 + size(h.left) + size(h.right);
return x;
}
如果新插入的节点比原来的节点小,则将它正常插入,然后把新节点的颜色设为红色;如果比原来的大,则正常插入,把新节点的颜色设置为红色,然后进行一次左旋转。
void flipColors(Node h)
{
h.color = RED;
h.left.color = BLACK;
h.right.color = BLACK;
}
上面的代码有可能会使根节点的颜色变为红色,所以每次插入操作后,我们要让根节点的颜色变回黑色。注意到,每当根节点颜色变红时,树的高度就增加了1。
相当于将一个新的红链接逐层向上传递,直到符合顺序(没有右倾斜的红链接,没有两个红链接连着同一个节点等),或到达根节点。
public void put(Key key, Value val)
{
root = put(root, key, val);
root.color = BLACK;
}
private Node put(Node h, Key key, Value val)
{
if (h == null) return new Node(key, val, 1, RED);
int cmp = key.compareTo(h.key);
if (cmp < 0) h.left = put(h.left, key, val);
else if (cmp > 0) h.right = put(h.right, key, val);
else h.val = val;
if (isRed(h.right) && !isRed(h.left)) h = rotateLeft(h);
if (isRed(h.left) && isRed(h.left.left) h = rotateRight(h);
if (isRed(h.left) && isRed(h.right)) flipColors(h);
h.N = size(h.left) + size(h.right) + 1;
return h;
}
[[[要先看线性高斯模型那一节]]]
本文主要是PRML一书8.1节的笔记。
贝叶斯网络是概率图模型中重要的一种模型,用有向无环图(DAG)来描述概率分布。
有向图的图模型称为贝叶斯网络,而无向图的图模型称为马尔科夫随机场(也称为马尔科夫网)。有向图适合表示随机变量之间的因果关系,而无向图适合表示随机变量之间的软约束(soft constraints)。
先看一种最简单的MRF:成对MRF。下图代表了一个四人学习小组,其中有边相连表示两个人一起学习,而没有边则表示他们没有一起学习(可能是关系不合等)。
图中的边意味着两个人一起学习时就可能互相影响,由于这种影响是双向的,所以用无向图来建模。
过拟合指的是在机器学习过程中过度拟合训练集数据, 使得数据中的噪声对习得的模型产生很大影响。模型在训练集上的误差很小,但泛化能力差。
偏差(Bias) | 方差(Variance) | 模型复杂度(Complexity) | 模型灵活性(Flexibility) | 模型泛化能力(Generalization) | |
---|---|---|---|---|---|
欠拟合(Underfitting) | 高 | 低 | 低 | 低 | 高 |
过拟合(Overfitting) | 低 | 高 | 高 | 高 | 低 |
Boosting是集成学习中一种重要的方法,通过集成弱分类器,可以获得比单一学习器性能都好的一个模型。XGBoosting是在Gradient Boosting基础上,进行了一些改动设计,使得算法效率显著提高,并可以并行化。