我的问题如下:
我必须遍历95个元素的所有可能性(0或1)。
例如,如果有2个元素,可能性为: 00,01,10,11
总可能性的数量是2 ^ n,因此它增长得非常快。 2 ^ 95 = 39614081257132168796771975168
我如何有效地从0迭代到2 ^ 95?
P.S。选择编程语言并不重要,但我猜C或C ++应该是最快的选择。
P.P.S。我认为BigInt实现似乎比原始类型慢得多,将数字拆分为X个原语可能是个好主意。到目前为止我没有运气。
P.P.S。我有一个函数,它可以通过提供0到2 ^ 95的数字来生成可能性
答案 0 :(得分:8)
现代CPU以几千兆赫的速度运行,因此可能能够每秒迭代超过十亿个值(如果你没有做太多其他的话)。
每秒10亿次迭代,需要超过1.2万亿年才能达到2次 95 次迭代。
你需要找到一种不同的方式去做你正在做的事情。
答案 1 :(得分:2)
除非你有量子计算机,否则你无法逃避整个范围的迭代。最简单的方法是将95位拆分为一组基元。例如,如果您的系统使用64位数字运行,则可以使用其中的2位数。 伪代码将是这样的:
lowBound <-- 2^64-1
highBound <-- 2^31-1
for highIdx = 0 up to highBound
for lowIdx = 0 up to lowBound
; Do your thing here, if you need the actual index,
; it's combinable from lowIdx and highIdx
最快的方法是使用Assembly
和特定于体系结构的指令来更好地利用系统资源来加速进程(寄存器,缓存等)。您也可以考虑使用GPU - 它们非常适合并行化任务,因此如果您的操作在每次迭代时都相似,那么它可以具有良好的性能。
然而,所有这些都是无用的,你应该为你正在做的而不是迭代设计一个更好的算法,就像在@KeithThompson的回答中所提到的那样。
答案 2 :(得分:2)
在理论中,以下是您的工作:
int exp = 95;
UInt64 hmax = 2 ^ (exp - 64);
UInt64 lmax = 2 ^ 63 + (2 ^ 63 - 1);
for (UInt64 high = 0; high < hmax; high++) {
for (UInt64 low = 0; low <= lmax; low++) {
// do stuff
}
}
现在循环控件high
保持高位字,循环控制low
保持低位字。现在你可以这样做:
// where UInt128 is your big integer type
// cast the high word to prevent overflow
UInt128 word = (UInt128)high << 64 | low;
或者将它们连接成字符串。
循环模式如下所示(使用字节表示):
00000000 00000000
00000000 00000001
00000000 00000010
and eventually you get to
00000000 11111111
inner loop completes and it goes to
00000001 00000000
00000001 00000001
答案 3 :(得分:1)
我的猜测是你需要量子比特(http://en.wikipedia.org/wiki/Qubit)进行计算,但因为它们本质上是理论性的,也许现在最好开始你的迭代,看它是否会更快或量子计算将很快得到答案。
使用量子计算,您可以一次测试所有组合。
从这里开始阅读,它可能无法解决您的问题,但确实很有趣:http://physics.about.com/od/physicsqtot/g/quantumparallel.htm