如何处理从0到2 ^ 95的循环?

时间:2013-10-26 18:10:58

标签: loops

我的问题如下:

我必须遍历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的数字来生成可能性

4 个答案:

答案 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