トップ 差分 一覧 ソース 検索 ヘルプ 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

  検証方法

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])