高阶算法


35

从它们的输入和输出是“普通”数据的意义上讲,大多数众所周知的算法都是一阶的。有些是简单的二阶方法,例如排序,哈希表或map和fold函数:它们是通过函数进行参数化的,但是除了在其他输入数据上调用它外,它们实际上并没有做任何有趣的事情。

有些也是二阶的,但更有趣:

  • 由monoids参数化的手指树
  • 在单调谓词上分裂手指树
  • 前缀和算法,通常又用一个monoid或谓词等参数化。

最后,在我最感兴趣的意义上,有些是“真正的”高阶:

  • Y组合器
  • 差异清单

是否存在其他非平凡的高阶算法?

为了澄清我的问题,在“非平凡的高阶”下,我的意思是“在算法的接口和/或实现中以关键的方式使用计算形式主义的高阶设施”


3
我曾经问过类似的问题。一些答案在这里:caml.inria.fr/pub/ml-archives/caml-list/2004/09/...
拉杜·格里戈里

你们在谈论采用算法和/或返回算法的算法吗?
Pratik Deoghare's

Answers:


13

http://math.andrej.com/上有很多高阶函数,例如在有关双指数的帖子中,出现以下Haskell类型(类型同义词已扩展):

shift :: Bool -> ((Int -> Bool) -> Bool) -> ((Int -> Bool) -> Bool)

您也可以通过A Haskell Monad无限时无限搜索帖子获得很多乐趣-例如:

newtype S a = S ((a -> Bool) -> a)
bigUnion :: S (S a) -> S a

我猜想bigUnion的类型是4或5阶!


22

尽管通常没有在这些术语中明确描述,但有一堆算法是“真正的二阶”。每当我们有次线性时间算法时,隐式就是对输入的某种oracle访问,即,实际上将输入视为函数。

例子:

(1)使用“分离预言”时的椭球算法(例如,http : //math.mit.edu/~vempala/18.433/L18.pdf

(2)亚模块功能的最小化(例如http://people.commerce.ubc.ca/faculty/mccormick/sfmchap8a.pdf

(3)属性测试的整个领域实际上就是这种形式(http://www.wisdom.weizmann.ac.il/~oded/test.html

(4)查询模型中的组合拍卖(例如 http://pluto.huji.ac.il/~blumrosen/papers/iter.pdf


15

这个问题还有另一个答案:没有。更具体地,任何这样的(可执行!)较高阶算法是机械地等效于一阶算法,利用去官能化

更准确地说:尽管确实存在实际的高阶算法,但实际上始终可以将每个实例重写为纯一阶程序。换句话说,没有饱和的高阶程序-实质上是因为程序的输入/输出是位字符串。[是的,这些位串可以表示功能,但这就是要点:它们表示功能,不是功能]。

已经给出的答案非常好,我的答案不应被认为与它们矛盾。应该认为它是在稍大的上下文(完整的程序而不是独立的算法)中回答问题。上下文的这种变化从根本上改变了答案。我的答案是要提醒人们这一点,这太容易忘记了。


我同意,任何高阶算法都等同于具有相同外部规范的某些一阶算法,但这并不妨碍我们争论它们的内部属性。代表事物与成为事物没有什么区别。
jkff

1
@jkff:我同意您的第一点-我们绝对应该讨论这些内部属性。我强烈不同意第二点:您以某种方式声称扩展名和内涵是“相同的”,这显然是错误的。[让我想起马蒂斯的画作“这不是烟斗”]
雅克·卡莱特

嗯,是的,“ Eta转换的叛逆”。(\\() -> "Ceci n'est pas une fonction") ()
CA McCann

我声称如果两件事是等效的(彼此代表),则您不能否认其中之一的存在:)
jkff 2010年

@jkff:很难不同意!
雅克·卡莱特

13

在解析器组合器库中,功能的顺序通常很高。查看甚至更高阶的函数进行解析,或者为什么有人要使用六阶函数?克里斯·冈崎(Chris Okasaki)。Journal of Functional Programming,8(2):195-199,1998年3月。


这是一篇很棒的论文,但不是我想要的东西。尽管组合器是高阶的,但它们非常简单且独立,并且几乎不将它们视为非平凡的算法/数据结构(但是,组合器解析器本身可能会)。相反,Y组合器是查找固定点的非常简单的算法,而差异列表是完全由高阶函数构建的聪明数据结构。(我不会破坏您的答案,只是想澄清我的问题)
jkff

13

可计算分析以编程方式表征实数,因为实数包含无限量的信息,因此在问题意义上对实数的运算是高阶的。通常,使用无限位流(康托尔空间)上的拓扑视图来表示实数,从而使可计算拓扑的领域更为广泛。

克劳斯·魏拉赫(Klaus Weihrach)将其称为可计算拓扑有效性第二类层次结构。有关更多信息,请参见Weihrach&Grubba,2009年,《基本可计算拓扑》,以及John Tucker的研究页面,《使用拓扑数据进行计算》。我在问题“ Cantor Space的应用”中提到了塔克的页面。


这自然很自然地扩展到可计算的数学对象:其他可计算的数字(不一定是实数),无限组的可计算元素(环,代数等),空间中的可计算点等。在所有此类情况下,算法理论涉及从功能表示(如何计算数学对象)中提取信息,而不是从对象本身中提取信息。
ex0du5 2012年

13

连续模功能是地图m,它接受一(连续)的功能F : (nat -> nat) -> nat,并输出一个数k,使得F f = F g无论何时f i = g i所有i < k。有一些算法可以计算连续性模量(不是很有效),因此使其成为三阶算法的一个实例。


9

为了补充Noam的答案,在几种情况下,使输出成为函数(明确表示)也很重要。

C:0,1n0,1mA (α,L,ϵ)CnAM1,,ML

w0,1m,PrA[m, (Ag(C(m),w)α i[L], j[n], PrMi[Mi(j)=mj]1ϵ)]2/3

AgA2/3ϵmmα


5

在图算法中,顶点和边通常被认为是纯数据,但实际上可以将它们有效地概括起来,以便按需以编程方式生成它们。

在攻读博士学位(计算化学)期间,我以高阶形式实现了许多图算法,以便将它们应用于隐式图的分析,这主要是因为我的实际图是无限的,所以我无法显式存储它们!具体而言,我正在研究以晶胞(超级晶胞)的3D拼贴形式表示的非晶材料的拓扑。

例如,您可以编写一个函数来计算原始顶点的第n个最近的邻居壳,i如下所示:

nth i 0 = {i}
nth i 1 = neighbors i
nth i n = diff (diff (fold union empty (map neighbors (nth i (n-1)))) (nth i (n-1))) (nth i (n-2))

其中neighbors的一个函数可将一组相邻顶点返回给定顶点。

例如,二维方格:

neighbors (x, y) = {(x-1, y), (x+1, y), (x, y-1), (x, y+1)}

在这种情况下,其他有趣的算法包括Franzblau的最短路径环统计。


这使我想到了一个问题。如果有通过编程方式定义图的方式,是否有一种方法可以定义自指自矛盾图?
Suresh Venkat 2012年

1
{x:xx}{x:xx}

当然。但这是一个自指吗?
Suresh Venkat 2012年

@Suresh:这是用功能语言定义的图,表示存在一种U顶点类型和一条U -> U -> Bool边函数。
sdcvvc 2012年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.