我正在尝试解决离散日志2 ^ x = r(mod m)。 其中m,2 ^ 47
所以我创建了一个大小为2 ^ 24的哈希表,并使用它来存储一个整数键和一个BigInteger值。
这是我的代码:
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Numerics;
namespace Shanks_BSGS_Algorithm
{
class Program
{
static int Main()
{
BigInteger g = 2,temp = 2,n = (Math.Sqrt(281474976710656));
Hashtable b = new Hashtable(n);
int i=0;
b.Add(0, 1);
i++;
for (i = 1; (BigInteger)i < n ; i++)
{
temp *= g;
b.Add(i,temp);
}
return 0;
}
}
}
如果它有所作为。我在具有1.5 GB RAM和32位Windows 7的6年前笔记本电脑上运行Visual C#2010 Express。 提前谢谢。
答案 0 :(得分:0)
temp
变得非常大(高达16777216位)。所以你的hashset包含1600万个非常长的BigIntegers。也许你想减少临时模态,但当g = 2时,这当然会变为0,而m是2的幂。所以你想要做的事情并不是很清楚。
答案 1 :(得分:0)
首先,我认为您需要使用temp
值作为数据的关键:
// this makes more sense, otherwise you
// could simply have an array of BigIntegers
b.Add(temp,i);
关于内存问题,.NET不允许任何进程使用超过2Gb的内存,如果需要连续的块,则允许更少的内存。由于你在处理非常大的数字时,内存耗尽是不可避免的。
一种解决方案(首选,如果您只需要最终结果)将使用不同的算法(Pollard's rho algorithm),这样的空间效率更高,运行时间也相似。
如果您真的想测试BSGS算法,您可能需要选择基于磁盘的哈希表。我不知道.NET的任何实现,但你可能会发现几个C ++项目,看看你是否可以轻松移植它们(例如DBH)。
如果你找不到这样的哈希表,比移植更简单的解决方案(好吧,取决于你的数据库技能)可能是使用你习惯的关系数据库,使用一个可以允许足够大的整数的模式。您可以尝试使用SQLite,将随着它的增长而变慢,但我相信速度对您来说并不重要。具有一些正确索引的SQL Server可能运行良好。