Questions tagged «algorithms»

算法是定义明确的问题解决方案的一系列明确定义的步骤。如果您的问题与算法的设计和分析有关,请使用此标签。

3
为什么Mersenne Twister被认为是很好的?
Mersenne Twister被广泛认为是很好的。哎呀,CPython消息人士说,它“是现有的经过最广泛测试的生成器之一”。但是,这是什么意思?当被要求列出该生成器的属性时,我所能提供的大多数内容都是不好的: 它是庞大而僵化的(例如,无搜索或多个流), 尽管状态规模庞大,但它未能通过标准的统计测试, 它在0左右有严重问题,表明它对自己的随机性很差, 不太快 等等。与诸如XorShift *的简单RNG相比,它也无可避免地变得复杂。 因此,我寻找一些信息,以了解为什么有人认为这很好。原始论文对“超天文学”时期和623维均匀分布发表了很多评论,他说 在许多已知的测量方法中,基于较高尺寸均匀性的测试(如下面所述的光谱测试(参见Knuth [1981])和k分布测试)被认为是最强的。 但是,对于此属性,发电机会被足够长的计数器打败!这没有评论本地分布,这是您实际上在生成器中关心的(尽管“本地”可能意味着各种事情)。甚至CSPRNG都不在意这么长时间,因为这并不重要。 论文中有很多数学,但据我所知,这实际上与随机性无关。几乎所有对此的提及都会迅速跳回这些原始的,基本上无用的主张。 似乎人们以牺牲较旧,更可靠的技术为代价而跳上了潮流。例如,如果您将LCG中的单词数增加到3(比Mersenne Twister的“仅624”少得多)并在每次通过时输出最高单词,则它会通过BigCrush(TestU01测试套件的更难部分)),尽管Twister失败了(PCG纸,图2)。鉴于此,以及证据不足,我能够在支持梅森倍捻机的发现,是什么做的原因关注过其他的选择青睐呢? 这也不是纯粹的历史。有人告诉我,Mersenne Twister在实践中至少比PCG random更为有效。但是用例是否如此清晰,以至于它们可以比我们的测试组合做得更好?一些谷歌搜索暗示他们可能不是。 简而言之,我想知道Mersenne Twister在其历史背景或其他方面如何获得广泛的正面声誉。一方面,我显然对它的质量表示怀疑,但另一方面,很难想象它是完全随机发生的。

3
阶乘算法比朴素乘法更有效
我知道如何使用迭代和递归(例如n * factorial(n-1),例如)为阶乘编码。我读过一本教科书(没有给出任何进一步的解释),发现通过递归将因式分解成两半,有一种更有效的编码方式。 我知道为什么会这样。但是我想尝试自己编码,但是我不知道从哪里开始。一位朋友建议我先写基本案例。我当时在考虑使用数组,以便可以跟踪数字...但是我真的看不出设计这种代码的任何出路。 我应该研究哪种技术?

6
从任何基数转换为任何基数而不经过基数10的背后的数学运算?
我一直在研究从任何基础转换为任何基础的数学运算。这比确认我的结果更重要。我在mathforum.org上找到了我的答案,但是我仍然不确定我是否正确。我可以从较大的基数转换为较小的基数,因为这只是将第一位数字乘以要添加下一位数字重复的基数即可。我的问题是从较小的基数转换为较大的基数时出现的。在执行此操作时,他们会讨论如何将所需的较大基准转换为较小的基准。一个例子是从4到6的基数,您需要将数字6转换为4到12的基数。然后执行与从大到小转换时相同的操作。我遇到的困难是,似乎您需要知道另一个数中的一个。因此,我需要知道4中的6是什么。这在我脑海中产生了一个大问题,因为那时我需要一个表。有谁知道以更好的方式做到这一点的方法。 我以为基本转换会有所帮助,但找不到任何有效的方法。从我发现的站点来看,它似乎允许您从基数转换为基数,而无需经过10底,但是您首先需要知道如何将第一个数字从基数转换为基数。这使得它毫无意义。 评论员说我需要能够将字母转换为数字。如果是这样,我已经知道了。但是那不是我的问题。我的问题是为了将大基数转换为小基数,我需要先将我拥有的基数转换为所需的基数。这样做我无法达到目的,因为如果我能够将这些碱基转换为其他碱基,那么我已经解决了我的问题。 编辑:我已经找到了如何从小于或等于10的基数转换为小于或等于10的其他基数的方法。我也可以从大于10的基数转换为小于等于10的任何基数。当从大于10的基数转换为大于10的基数时,或者从小于10的基数变为大于10的基数时,问题就开始了。我不需要代码,我只需要它后面的基本数学即可。适用于代码。

2
为什么二进制搜索的big-O中的日志不是以2为底的?
我是了解计算机科学算法的新手。我了解二进制搜索的过程,但是我对其效率有些误解。 在元素的大小中,平均需要步骤才能找到特定元素。取双方的底数为2的对数,得出。那么二分查找算法的平均步数不是吗? n log 2(s )= n log 2(s )s=2ns=2ns = 2^nnnnlog2(s)=nlog2⁡(s)=n\log_2(s) = nlog2(s)log2⁡(s)\log_2(s) 维基百科有关二进制搜索算法的文章说,平均性能为。为什么会这样呢?为什么这个数字不是?log 2(n )O(logn)O(log⁡n)O(\log n)log2(n)log2⁡(n)\log_2(n)

3
最坏情况
我很难找到可以给出最坏情况良好资源,而不是稳定排序算法。有人知道任何好的资源吗?O(nlnn)O(nln⁡n)O(n \ln n) 提醒一下,这意味着它使用传入的数组,并且排序算法仅允许使用恒定的额外空间。稳定意味着具有相同键的元素在排序数组中的顺序与原始数组中的顺序相同。 例如,朴素的合并排序是最坏的情况且稳定,但使用多余的空间。可以使标准的快速排序稳定,到位,但最坏的情况是。堆排序已经到位,最坏的情况是O(n \ ln n),但不稳定。 维基百科上有一张很好的图表,说明了哪种排序算法有哪些弊端。请注意,他们没有列出列出所有具有稳定性的三个条件的排序算法,最坏情况为O(n \ ln n)且处于适当状态。O(nlnn)O(nln⁡n)O(n \ln n)O(n)O(n)O(n)O(n2)O(n2)O(n^2)O(nlnn)O(nln⁡n)O(n \ln n)O(nlnn)O(nln⁡n)O(n \ln n) 我发现Katajainen,Pasanen和Teuhola撰写了一篇名为“ Practical in-place mergesort”的论文,该论文声称就地稳定的mergesortsort变种最坏的情况。如果我正确理解了它们的结果,它们将在数组的第一个和数组的后一个上递归使用(bottom-up?)mergesort,然后使用第二个作为合并的临时空间。我仍在阅读此书,因此感谢您提供有关我是否正确解释其结果的更多信息。O(nlnn)O(nln⁡n)O(n \ln n)1414\frac{1}{4}1212\frac{1}{2}1414\frac{1}{4} 我也会对最坏情况进行稳定快速排序感兴趣。据我了解,将快速排序修改为最坏的情况需要选择一个适当的枢轴,这将破坏原本通常会享有的稳定性。O(nlnn)O(nln⁡n)O(n \ln n)O(nlnn)O(nln⁡n)O(n \ln n) 这纯粹是理论上的兴趣,我没有实际应用。我只想知道具有所有这三个功能的算法。

1
如果在BFS实现中将队列更改为堆栈,是否会获得DFS?
这是广度优先搜索的标准伪​​代码: { seen(x) is false for all x at this point } push(q, x0) seen(x0) := true while (!empty(q)) x := pop(q) visit(x) for each y reachable from x by one edge if not seen(y) push(q, y) seen(y) := true 此处push和pop被假定为队列操作。但是,如果它们是堆栈操作呢?生成的算法是否按深度优先顺序访问顶点? 如果您对“这很琐碎”的评论投了赞成票,请您解释一下为什么这很琐碎。我觉得这个问题很棘手。

3
算法,该算法找到的从简单的路径的数目到在
任何人都可以建议我一个线性时间算法,需要作为输入向无环图和两个顶点和,并返回从简单路径的数目到在。 我有一个算法,其中将运行DFS(深度优先搜索),但如果DFS找到则它将不会更改路径出现的任何节点的颜色(从白色到灰色),以便如果这是任何其他路径的子路径,那么DFS也会再次通过该子路径。例如,考虑邻接列表,我们需要在其中找到从p到v的路径数。G = (V,E)G=(V,E)G=(V,E)sssŤttsssŤttGGGŤtts⇝ts⇝ts \rightsquigarrow tv p o s z o r s v s r r y y v v w zpppvvv posryvzworryvwzsszvposzorsvsrryyvvwzwz\begin{array}{|c|c c c|} \hline p &o &s &z \\ \hline o &r &s &v\\ \hline s &r \\ \hline r &y \\ \hline y &v \\ \hline …



2
天真的改组在渐近性上有多糟糕?
众所周知,这种“天真的”算法通过将每个项目与另一个随机选择的项目交换来改组数组,无法正常工作: for (i=0..n-1) swap(A[i], A[random(n)]); 具体来说,由于在次迭代中的每一次迭代中,都会做出选择之一(概率均等),因此通过计算存在可能的“路径”。因为可能的排列数为不能均匀地将路径数目划分为,该算法不可能产生路径中的每一个等概率排列。(相反,应该使用所谓的Fischer-Yates随机播放,这实际上改变了从[0..n]中选择随机数的调用与从[i..n]中选择随机数的调用;不过,这很无聊。)n nnn nnn nnnn^n n !n!n!n nnnn^n n !n!n! 我想知道的是,天真洗牌有多“糟糕”?更具体地说,令为所有置换的集合,令为通过朴素算法生成的最终置换的路径数,则的渐近行为是什么。功能P (Ñ )P(n)P(n)Ç (ρ )C(ρ)C(\rho)ρ ∈ P (Ñ )ρ∈P(n)\rho\in P(n) M(n)=n!nnmaxρ∈P(n)C(ρ)M(n)=n!nnmaxρ∈P(n)C(ρ)\qquad \displaystyle M(n) = \frac{n!}{n^n}\max_{\rho\in P(n)} C(\rho) 和 m(n)=n!nnminρ∈P(n)C(ρ)m(n)=n!nnminρ∈P(n)C(ρ)\qquad \displaystyle m(n) = \frac{n!}{n^n}\min_{\rho\in P(n)} C(\rho)吗? 首要因素是“标准化”这些值:如果幼稚的随机播放“渐近良好”,则 limn→∞M(n)=limn→∞m(n)=1limn→∞M(n)=limn→∞m(n)=1\qquad \displaystyle \lim_{n\to\infty}M(n) = \lim_{n\to\infty}m(n) = 1。 我怀疑(基于我见过的一些计算机模拟)实际值的界线是1,但是甚至知道limM(n)limM(n)\lim M(n)是有限的,还是limm(n)limm(n)\lim m(n)是界线的呢? …

2
Dana Angluin用于学习常规集的算法是否有改进
Dana Angluin在1987年的开创性论文中提出了一种多项式时间算法,用于从成员资格查询和理论查询(拟议DFA的反例)中学习DFA。 她表明,如果您尝试学习具有个状态的最小DFA ,而最大的countexample的长度为m,那么您需要进行O (m n 2)个成员资格查询,最多需要进行n − 1个理论查询。nnnmmmO(mn2)O(mn2)O(mn^2)n−1n−1n - 1 学习常规集所需的查询数量是否有了重大改进? 参考文献和相关问题 Dana Angluin(1987)“从查询和反例中学习规则集”,《启发与计算》 75:87-106 成员资格查询和反例模型中的学习下限

4
什么是动态编程?
抱歉,这个问题听起来很愚蠢。 据我所知,使用动态编程构建算法的工作方式如下: 将问题表达为递归关系; 通过备忘或自下而上的方法来实现递归关系。 据我所知,我已经说了有关动态编程的一切。我的意思是:动态编程不会提供工具/规则/方法/定理来表达递归关系,也不会将其转化为代码。 那么,动态编程有什么特别之处呢?除了解决某些问题的模糊方法之外,它还能给您带来什么?

3
硬件/实现会影响算法的时间/空间复杂度吗?
我什至都不是CS学生,所以这可能是一个愚蠢的问题,但是请忍受... 在前计算机时代,我们只能用抽屉数组来实现数组数据结构。由于一个有定位与从它提取值之前对应的索引的抽屉,阵列查找的时间复杂度是,假设二进制搜索。Ø(升Ò 克(n ))Ø(升ØG(ñ))O(log(n)) 但是,计算机的发明产生了很大的变化。现代计算机可以如此快速地从其RAM中读取数据,因此我们现在认为数组查找的时间复杂度为(即使从技术上讲也不是这种情况,因为将寄存器移至更远的距离需要花费更多时间,等等)O (1 )Ø(1个)O(1) 另一个例子是Python字典。虽然人们可能会得到一本字典访问的复杂性与病人写重载魔术方法(或可笑的坏运气,即具有大量的散列冲突的键),它通常被认为是Ø (1 )。在这种情况下,时间复杂度既取决于Python字典的哈希表实现,也取决于哈希函数的键的实现。O (n )Ø(ñ)O(n)__hash__O (1 )Ø(1个)O(1) 这是否意味着硬件/实现会影响算法的时间复杂度?(虽然这两个示例都是关于数据结构而不是算法,但后者是建立在前者之上的,而且我从未听说过数据结构的时间复杂性,因此在这里我使用术语“算法”) 对我来说,算法是抽象的和概念性的,它们的属性(例如时间/空间复杂度)不应受到是否以特定方式实现而受到影响,但它们是吗?

2
什么是暂停状态未知的超短程序?
Binary Lambda微积分中的这个579位程序的暂停状态未知: 01001001000100010001000101100111101111001110010101000001110011101000000111001110 10010000011100111010000001110011101000000111001110100000000111000011100111110100 00101011000000000010111011100101011111000000111001011111101101011010000000100000 10000001011100000000001110010101010101010111100000011100101010110000000001110000 00000111100000000011110000000001100001010101100000001110000000110000000100000001 00000000010010111110111100000010101111110000001100000011100111110000101101101110 00110000101100010111001011111011110000001110010111111000011110011110011110101000 0010110101000011010 即,不知道该程序是否终止。为了确定它,您必须求解Collat​​z猜想 -或至少求解所有2≤256的数字。在此存储库中,有关于如何获取此程序的完整说明。 是否有(很多)较短的BLC程序也具有未知的停止状态?

3
弗洛伊德循环检测算法| 确定周期的起点
我正在寻求帮助来了解弗洛伊德的循环检测算法。我已经对Wikipedia(http://en.wikipedia.org/wiki/Cycle_detection#Tortoise_and_hare)进行了解释。 我可以看到算法如何检测O(n)时间的周期。但是,我无法想象这样一个事实,即一旦乌龟和野兔指针第一次相遇,就可以通过将乌龟指针移回起点,然后一次移动乌龟和野兔一步来确定周期的开始。他们初次见面的时间就是周期的开始。 有人可以提供一种解释,希望与维基百科上的解释有所帮助,因为我无法理解/可视化它?

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.