【发布时间】:2008-10-05 19:33:48
【问题描述】:
我喜欢阅读新的和聪明的算法。而且我喜欢开箱即用,因此欢迎来自各个计算领域的各种算法。
我不时阅读研究论文以跟上当前的研究并扩大我的视野。我也喜欢学习新的技巧。不幸的是,我倾向于只专注于我感兴趣的领域,所以我错过了很多有用的东西。
我们不要发布主流的东西。而是写一些让你觉得特别的东西:“哇——现在这是一个聪明的解决方案!”。
【问题讨论】:
标签: algorithm language-agnostic
我喜欢阅读新的和聪明的算法。而且我喜欢开箱即用,因此欢迎来自各个计算领域的各种算法。
我不时阅读研究论文以跟上当前的研究并扩大我的视野。我也喜欢学习新的技巧。不幸的是,我倾向于只专注于我感兴趣的领域,所以我错过了很多有用的东西。
我们不要发布主流的东西。而是写一些让你觉得特别的东西:“哇——现在这是一个聪明的解决方案!”。
【问题讨论】:
标签: algorithm language-agnostic
我将从每个人都可以使用的东西开始:内省排序。 http://en.wikipedia.org/wiki/Introsort
一种新的排序算法,结合了快速、插入和堆排序的优点。确切地说,它本身并不是一个新算法,而是一个非常巧妙的组合。
您可以将快速排序的速度提高到快速排序遇到退化 O(n²) 情况的程度。这几乎可以免费检测到。剩余的分区使用堆排序或合并排序进行排序。这不仅避免了退化的情况,而且还为堆栈使用创建了明确定义的上限。
插入排序 - 像往常一样 - 关心快速排序过程中留下的所有小分区。
对我来说,这是一个新发现,因为我不再对我的应用程序使用快速排序。
我在嵌入式设备上做了很多工作,我确实必须关心堆栈的使用。使用快速排序总是有点冒险,因为它在堆栈上运行异常的可能性很小。即使您知道使用当前数据一切都会好起来的,您永远不知道是否有人后来将您的代码剪切'n'粘贴到不同的项目中并将其用于从未提及的数据。
多亏了自省排序,我现在可以完全控制堆栈的使用并获得性能提升。
【讨论】:
这不是全新的或令人兴奋的东西,但我喜欢Levenshtein Distance。
Levenshtein 距离通常被称为两个字符串之间的 编辑距离,它基本上是一种度量标准,通过计算将一个字符串转换为另一个字符串的最小操作数来衡量两个字符串之间的差异.
我正在使用此算法来建议对多个字符串进行排序,以匹配(可能不同)字符串的外部源的顺序。
【讨论】:
我最近重新发现了用于整数平方根的旧 Marchant 计算器算法的二进制变体。没有乘法或除法,只有加法、减法和移位。对不起,我失去了参考:
def assert
raise "Assertion failed !" if $DEBUG and not yield
end
def sqrt(v)
value = v.abs
residue = value
root = 0
onebit = 1
onebit <<= 8 while (onebit < residue)
onebit >>= 2 while (onebit > residue)
while (onebit > 0)
x = root + onebit
if (residue >= x) then
residue -= x
root = x + onebit
end
root >>= 1
onebit >>= 2
end
assert {value == (root**2+residue)}
assert {value < ((root+1)**2)}
return [root,residue]
end
$DEBUG = true
a = sqrt(4141290379431273280)
puts a.inspect
非常抱歉,对于不熟悉的人,忘记说这是 Ruby。
【讨论】:
我一直认为 Quake 中的magic square-root 功能非常聪明。它非常快,因为它避免了任何较慢的操作,例如除法等。
float SquareRootFloat(float num) {
long i;
float x, y;
const float f = 1.5F;
x = num * 0.5F;
y = num;
i = * ( long * ) &y;
i = 0x5f3759df - ( i >> 1 );
y = * ( float * ) &i;
y = y * ( f - ( x * y * y ) );
y = y * ( f - ( x * y * y ) );
return num * y;
}
他还有一个相关的magic inverse square-root。
【讨论】:
这是我最近“发现”的Viterbi algorithm 的实现。这里的目的是决定视频编码中帧类型的最佳分布。 Viterbi 本身有时有点难以理解,所以我认为最好的方法是通过实际示例。
在本例中,最大连续 B 帧数为 2。所有路径都必须以 P 帧结束。
路径长度为 1 为我们提供了最佳路径 P,因为所有路径都必须以 P 帧结束,因此别无选择。
路径长度为 2 给我们BP 和_P。 "_" 是长度为 1 的最佳路径。
这给了我们BP 和PP。现在,我们计算实际成本。
假设为了这个例子,BP 是最好的。
路径长度为 3 为我们提供 BBP 和 _BP 和 __P。 "__" 是长度为 2 的最佳路径。
这给了我们BBP 和PBP 和BPP。现在,我们计算实际成本。
假设为了这个例子,BBP 是最好的。
路径长度为 4 为我们提供了 _BBP 和 __BP 和 ___P。 "___" 是长度为 3 的最佳路径。
这给了我们 PBBP 和 BPBP 和 BBPP。现在,我们计算实际成本。
假设为了这个例子,BPBP 是最好的。
路径长度为 4 为我们提供 __BBP 和 ___BP 和 ____P。 "____" 是长度为 4 的最佳路径。
这给了我们BPBBP 和BBPBP 和BPBPP。
现在——等一下——所有路径都同意第一帧是B!所以第一帧是B。
重复过程直到他们同意哪一帧是第一个 P 帧,然后开始编码。
该算法可以适应许多领域的大量问题;它也是我在this post中提到的相同算法。
【讨论】:
当我了解到用于数据压缩的 Burrows-Wheeler block sorting algorithm(在 bzip2 中使用)时,我印象深刻。令人惊讶的是,排序步骤是可逆的!
【讨论】:
生物信息学充满了以奇怪的形式生成大量数据的实验案例,需要富有想象力的算法来处理。
an introduction to bioinformatics algorithms 非常适合阅读此类内容
【讨论】:
Dynamic programming 与optimal control problems 一起发挥其全部力量。很清爽。
【讨论】:
它不像其他的那样华而不实,但它派上了用场:
((m+n) + (m-n)) / 2 === m (for any two real numbers m and n)
我在 SQL 中使用了一些聚合查询逻辑来计算项目的评分。评级为 +1 和 -1。我需要知道仅给出评分总数及其总和的正面评分数 (m)。
使用此逻辑确实加快了查询速度,并允许我返回评分为 0 的项目的结果。
(我没有选择 +1 和 -1;我继承了它。)
【讨论】:
我发现这个非常有用的证明 a^n = b^n + c^n 但仅适用于 n=2。
不幸的是,这个评论框太小了,无法容纳它!
【讨论】: