トップ 一覧 検索 ヘルプ RSS ログイン

PROG-randの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
!! 乱数 ( XorShift )

32bit 以上が。。

! wikipedia
https://ja.wikipedia.org/wiki/Xorshift

! Qiita
https://qiita.com/yosgspec/items/e4287262f8dbea2aa815

! GitHUB
https://github.com/yosgspec/XorShift128-on-8languages

! 8 bit
https://blog.goo.ne.jp/sim00/e/33b576696be51efbb3eab4b5c61ffb87

! Python3
https://rextester.com/FQDO96576

! Python3 その2
https://qiita.com/SatoshiTerasaki/items/e101d4c0e2e9e0e55663

https://gintenlabo.hatenablog.com/entry/20100928/1285702435

https://qiita.com/SatoshiTerasaki/items/e101d4c0e2e9e0e55663

!! 検証方法
*http://www.nct9.ne.jp/m_hiroi/light/pystat04.html

CODE::

 #!/usr/bin/env python3
 # -*- coding: utf-8 -*-
 """
 Created on Mon Sep  7 14:01:34 2020
 
 @author: green
 """
 #XorShift End
 from time import time
 from copy import copy
 
 class XorShift:
    defaults={
        "x":123456789,
        "y":362436069,
        "z":521288629,
        "w":88675123
    }
 
    def __init__(self,
        w=int(time()),
        x=None,
        y=None,
        z=None
    ):
        if x is None: x=w<<13
        if y is None: y=(w>>9)^(x<<6)
        if z is None: z=y>>7
        self.seeds={"x":x,"y":y,"z":z,"w":w}
        self.randCount=0
        self.__r=self.randGen(w,x,y,z)
 
    def randGen(self,w,x,y,z):
        while True:
            t=x^(x<<11&0xFFFFFFFF)
            x,y,z=y,z,w
            w=(w^(w>>19))^(t^(t>>8))
            yield w
 
    def rand(self):
        self.randCount+=1
        return next(self.__r)
 
    def randInt(self,min=0,max=0x7FFFFFFF):
        return self.rand()%(max+1-min)+min
 
    def randFloat(self,min=0,max=1):
        return self.rand()%0xFFFF/0xFFFF*(max-min)+min
 
    def shuffle(self,_arr):
        arr=copy(_arr)
        if isinstance(arr,list):
            isList=True
        elif isinstance(arr,range) or isinstance(arr,tuple):
            isList=True
            arr=list(arr)
        else:
            isList=False
            arr=list(arr)
 
        for i in range(0,len(arr)-1):
            r=self.randInt(i,len(arr)-1)
            arr[i],arr[r]=arr[r],arr[i]
 
        if not isList:
            arr=iter(arr)
        return arr
 
    def defaultSeed():return type("defaultSeed",(XorShift,),{
        "__init__":lambda self:
            XorShift.__init__(
                self,
                **XorShift.defaults
            )
    })()
 #XorShift End
  
 if __name__=="__main__":
    # r_def=XorShift.defaultSeed()
    # for i in range(255):
    #    print(i,",",r_def.rand())
    
    r_const=XorShift(255)
    for i in range(255):
        print(i,",",r_const.randInt(0,255))
    
 
 
 #from XorShift import XorShift
 if __name__=="__0000__":
    #XorShift乱数ジェネレータの初期化
    # 論文デフォルトシード
    r_def=XorShift.defaultSeed()
    # 固定値シード
    r_const=XorShift(100)
    # 時間シード
    r=XorShift()

 
    #デフォルトシード値の取得
    print(">> defaults")
    print(XorShift.defaults)

 
    #適用したシード値の取得
    print(">> seeds in r")
    print(r.seeds)

 
    #乱数の生データを取得
    print(">> rand 0 to UInt32Max")
    for i in range(5):
        print(r_def.rand())

 
    #0-100の乱数(100含む)を整数で取得
    print(">> randInt 0 to 100")
    for i in range(5):
        print(r_const.randInt(0,100))

 
    #0-1の乱数を浮遊小数点で取得
    print(">> randFloat 0 to 1")
    for i in range(5):
        print(r.randFloat())

 
    #listのシャッフル
    #値渡しとなるので元の配列は破壊されない
    print(">> shuffle list")
    a=list(range(0,20))
    print(r.shuffle(a))
    print(a)

 
    #rangeのシャッフル
    print(">> shuffle range")
    b=range(0,20)
    print(r.shuffle(b))
    print(b)

 
    #tuple(タプル)のシャッフル
    print(">> shuffle tuple")
    c=tuple(range(0,20))
    print(r.shuffle(c))
    print(c)

 
    #iter(イテレータ)のシャッフル
    print(">> shuffle iter")
    d=iter(range(0,20))
    print([i for i in r.shuffle(d)])
    print([i for i in d])