go-ml.dev/pkg/base@v0.0.0-20200610162856-60c38abac71b/fu/naivernd.go (about)

     1  package fu
     2  
     3  import (
     4  	"math"
     5  	"os"
     6  	"sync/atomic"
     7  	"time"
     8  )
     9  
    10  type NaiveRandom struct {
    11  	Value uint32
    12  }
    13  
    14  func (nr *NaiveRandom) Reseed() {
    15  	atomic.StoreUint32(&nr.Value, uint32(time.Now().UnixNano()+int64(os.Getpid())))
    16  }
    17  
    18  func (nr *NaiveRandom) Uint32() (r uint32) {
    19  	for {
    20  		r = atomic.LoadUint32(&nr.Value)
    21  		rx := r
    22  		r = r*1664525 + 1013904223
    23  		if atomic.CompareAndSwapUint32(&nr.Value, rx, r) {
    24  			break
    25  		}
    26  	}
    27  	return
    28  }
    29  
    30  func (nr *NaiveRandom) Uint() uint {
    31  	return uint(nr.Uint32())
    32  }
    33  
    34  func (nr *NaiveRandom) Int() int {
    35  	return int(nr.Uint32())
    36  }
    37  func (nr *NaiveRandom) Float() float64 {
    38  	return float64(nr.Uint()) / (float64(math.MaxUint32) + 1)
    39  }
    40  
    41  func Seed(seed int) int {
    42  	if seed != 0 {
    43  		return seed
    44  	}
    45  	return int(time.Now().UnixNano() + int64(os.Getpid()))
    46  }
    47  
    48  func Seed32(seed int) uint32 {
    49  	return uint32(Seed(seed))
    50  }
    51  
    52  func Seed64(seed int) int64 {
    53  	return int64(Seed(seed))
    54  }
    55  
    56  func RandomInts(seed int, count int) []int {
    57  	nr := NaiveRandom{Value: uint32(seed)}
    58  	m := map[int]bool{}
    59  	for i := 0; i < count; {
    60  		v := nr.Int()
    61  		if _, ok := m[v]; !ok {
    62  			m[v] = true
    63  			i++
    64  		}
    65  	}
    66  	r := make([]int, count)
    67  	i := 0
    68  	for k := range m {
    69  		r[i] = k
    70  		i++
    71  	}
    72  	return r
    73  }