2016-09-19 7 views
0

Ich habe zwei Iteratoren in Python und beide sollten die gleiche "zufällige" Verteilung folgen (beide sollten parallel laufen). Zum Beispiel:Parallele Zufallsverteilung

class Iter1(object): 
    def __iter__(self): 
     for i in random_generator(): 
      yield i 

class Iter2(object): 
    def __iter__(self): 
     for i in random_generator(): 
      yield i 

for el1, el2 in zip(Iter1(), Iter2()): 
    print '{} {}'.format(el1, el2) 

Ausgabe sollte somethig wie:

0.53534 0.53534 
0.12312 0.12312 
0.19238 0.19238 

Wie kann ich random_generator() in einer Art und Weise zu definieren, dass sie die gleichen Zufallsverteilungen parallel für beiden Iteratoren erzeugt.

Hinweis:

  • Sie parallel
  • laufen sollte ich die Reihenfolge im Voraus nicht erzeugen kann (es ist ein Streaming, also ich weiß nicht, die Größe der Sequenz)

Danke.

+0

nur die eine Ausbeute einer variablen zuweisen und diese Variable verwenden zweimal – iScrE4m

+0

Wenn Sie zwei Kopien der gleichen Iteration benötigen, verwenden Sie 'itertools.tee' – jonrsharpe

+0

Warum nicht ein zu erzeugen und es in eine andere kopieren? – Jeon

Antwort

2

Geben Sie den gleichen Samen zu jedem Aufruf von random_generator:

import random 

def random_generator(l, seed=None): 
    r = random.Random(seed) 
    for i in range(l): 
     yield r.random() 


class Iter1(object): 
    def __init__(self, seed): 
     self.seed = seed 

    def __iter__(self): 
     for i in random_generator(10, self.seed): 
      yield i 


class Iter2(object): 
    def __init__(self, seed): 
     self.seed = seed 
    def __iter__(self): 
     for i in random_generator(10, self.seed): 
      yield i 


# The seed can be any hashable object, but don't use None; that 
# tells random.seed() to use the current time. But make sure that 
# Python itself isn't using hash randomization. 
common_seed = object() 
for el1, el2 in zip(Iter1(common_seed), Iter2(common_seed)): 
    print '{} {}'.format(el1, el2) 
+0

Sind Sie sicher, dass das funktioniert? Ich würde erwarten, verschiedene Zahlen von jedem bekommen, weil sie Zahlen aus dem gleichen zugrunde liegenden Strom von Zufallszahlen nehmen. – jonrsharpe

+0

Als ich anfing, wollte ich nicht die globale Funktion 'random' verwenden und ein neues' Random' Objekt instanziieren, aber dann wurde ich aufgeregt, als ich bemerkte, dass 'same' auch eine globale Funktion war. Ich sollte das wiederholen. – chepner

+0

Ich sehe keinen Grund, zwei 'Iter' Klassen zu deklarieren - warum nicht einfach zwei Instanzen von 'Iter1' mit dem gleichen Seed erzeugen? –

0

Es gibt keine Möglichkeit, die Zufallsgenerierungsnummer auf diese Weise zu steuern. Wenn Sie das tun möchten, sollten Sie Ihre eigene Zufallsfunktion erstellen. Aber als eine andere pythonic und einfachere Art und Weise können Sie nur ein Objekt erstellen und verwenden itertools.tee um Ihre Iterator-Objekt zu kopieren das gleiche Ergebnis haben für Ihre Zufallsfolgen:

In [28]: class Iter1(object): 
      def __init__(self, number): 
       self.number = number 
      def __iter__(self): 
       for _ in range(self.number): 
        yield random.random() 
    ....:     

In [29]: 

In [29]: num = Iter1(5) 

In [30]: from itertools import tee 

In [31]: num, num2 = tee(num) 

In [32]: list(zip(num, num2)) 
Out[32]: 
[(0.485400998727448, 0.485400998727448), 
(0.8801649381536764, 0.8801649381536764), 
(0.9684025615967844, 0.9684025615967844), 
(0.9980073706742334, 0.9980073706742334), 
(0.1963579685642387, 0.1963579685642387)]