Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C#迁移到Python-随机类_C#_Python_Random - Fatal编程技术网

将C#迁移到Python-随机类

将C#迁移到Python-随机类,c#,python,random,C#,Python,Random,我需要将一些C#代码迁移到Python。原始代码使用Random类。迁移的代码必须是周期精确的(即对Next()的连续调用必须在两个代码中产生相同的结果)。一些问题: 在Python中是否存在与C#的Random等效的调用 头韵地说,假设我可以修改这两个源代码,是否有一个同时适用于C#和Python的伪随机库 我不知道有哪一个库既可用于Python,也可用于C#并且为这两种语言生成相同的随机数。但是,您可以利用IronPython。IronPython和CPython之间默认的Random实现

我需要将一些C#代码迁移到Python。原始代码使用
Random
类。迁移的代码必须是周期精确的(即对
Next()
的连续调用必须在两个代码中产生相同的结果)。一些问题:

  • 在Python中是否存在与C#的
    Random
    等效的调用
  • 头韵地说,假设我可以修改这两个源代码,是否有一个同时适用于C#和Python的伪随机库

我不知道有哪一个库既可用于Python,也可用于C#并且为这两种语言生成相同的随机数。但是,您可以利用IronPython。IronPython和CPython之间默认的
Random
实现不同,但是
WichmannHill
类则不同

您可以使用C#在IronPython中实例化
WichmannHill
类,并为同一种子获得与CPython相同的值。或者,通过在
random.py
中翻译Python代码,您可以相对轻松地在C#中实现Wichmann-Hill算法


另一种选择是采用随机的Mersenne Twister算法,并将其转换为C,以获得相同的结果。

我知道这是一个老问题,但我最终需要一个解决方案。我最终用python实现了C#的随机类。只要你不需要大于2147483647的随机数,它就可以工作。我最终不需要这个功能,所以我没有实现它

从ctypes导入*
#实施日期:
# http://referencesource.microsoft.com/#mscorlib/system/random.cs,dec894a7e816e665
类随机(对象):
定义初始化(self,seed):
self.seed=c_int(seed).value
self.MBIG=2147483647
self.MMIN=-2147483648
self.MZ=0
self.MSEED=161803398
self.SeedArray=[0]*56
如果seed==self.MMIN:
减法=self.MBIG
其他:
减法=绝对值(种子)
mj=c_int(self.MSEED-减法)。值
self.SeedArray[55]=mj
mk=1
对于范围(1,55)内的i:
ii=(21*i)%55
self.SeedArray[ii]=mk
mk=mj-mk
如果mk<0:
mk+=self.MBIG
mj=自种子阵列[ii]
对于范围(1,5)内的k:
对于范围(1,56)内的i:
self.SeedArray[i]-=self.SeedArray[1+(i+30)%55]
如果self.SeedArray[i]<0:
self.SeedArray[i]=c_int(self.SeedArray[i]+self.MBIG).value
self.inxt=0
self.inxtp=21
self.seed=1
def内部样本(自身):
locINext=自身inext+1
locINextp=self.inextp+1
如果locINext>=56:
locINext=1
如果locINextp>=56:
locINextp=1
retVal=c_int(self.SeedArray[locINext]-self.SeedArray[locINext]).value
如果retVal==self.MBIG:
retVal-=1
如果retVal<0:
retVal=c_int(retVal+self.MBIG).value
self.SeedArray[locINext]=retVal
self.inext=locINext
self.inxtp=locinxtp
返回返回
def Next(自我,最小值=无,最大值=无):
如果minValue==无:
返回self.InternalSample()
valRange=最大值-最小值

如果valRange为两种语言编写自己的PRNG,我支持使用Mersenne Twister。它是一个比内置的Random()好得多的randomiser(至少对于c#,我不知道IronPython)。不过,不要将它(或者确实是Random())用于加密。请在此处发布您的实现,以防gist被删除或链接中断。
from ctypes import *
# implemented from:
# http://referencesource.microsoft.com/#mscorlib/system/random.cs,dec894a7e816e665
class Random(object):
    def __init__(self, seed):
        self.seed = c_int(seed).value
        self.MBIG = 2147483647
        self.MMIN = -2147483648
        self.MZ = 0
        self.MSEED = 161803398
        self.SeedArray = [0] * 56

        if seed == self.MMIN:
            subtraction = self.MBIG
        else:
            subtraction = abs(seed)

        mj = c_int(self.MSEED - subtraction).value
        self.SeedArray[55] = mj
        mk = 1
        for i in range(1, 55):
            ii = (21 * i) % 55
            self.SeedArray[ii] = mk
            mk = mj - mk
            if mk < 0:
                mk += self.MBIG
            mj = self.SeedArray[ii]
        for k in range(1, 5):
            for i in range(1, 56):
                self.SeedArray[i] -= self.SeedArray[1 + (i + 30) % 55]
                if self.SeedArray[i] < 0:
                    self.SeedArray[i] = c_int(self.SeedArray[i] + self.MBIG).value
        self.inext = 0
        self.inextp = 21
        self.seed = 1

    def InternalSample(self):
        locINext = self.inext + 1
        locINextp = self.inextp + 1

        if locINext >= 56:
            locINext = 1
        if locINextp >= 56:
            locINextp = 1

        retVal = c_int(self.SeedArray[locINext] - self.SeedArray[locINextp]).value
        if retVal == self.MBIG:
            retVal -= 1
        if retVal < 0:
            retVal = c_int(retVal + self.MBIG).value
        self.SeedArray[locINext] = retVal
        self.inext = locINext
        self.inextp = locINextp
        return retVal

    def Next(self, minValue=None, maxValue=None):
        if minValue == None:
            return self.InternalSample()
        valRange = maxValue - minValue
        if valRange <= self.MBIG:
            return int(c_float(self.Sample() * valRange).value) + minValue
        else:
            return self.GetSampleForLargeRange() * valRange + minValue

    def GetSampleRangeForLargeRange(self):
        pass

    def Sample(self):
        s = self.InternalSample()
        ret = c_double(s * c_double(1.0/self.MBIG).value).value
        # print(f'sample: {s}\nret: {ret}')
        return ret