2016-08-03 25 views
1

Ich bin auf der Suche nach ein paar Funktionen, die den Index eines Vektors auf effiziente Weise per Seeding mit 128-Bit-Schlüssel permieren. Optimierung ist für mich kritisch, da ich die gleiche Operation mehrmals mache.Pseudo-zufällige Permutation mit 128 Bit Seed

Kann jemand eine C/C++ - Open-Source-Bibliothek vorschlagen, in der 128-Bit-Seeding verfügbar ist und eine Funktion wie Permute (Seed, Range (Min, Max), Sample_Size) unterstützt?

Zum Beispiel; Wenn die Funktion permute (1, [0,10], 10) das Ergebnis als 3 6 7 2 4 9 8 1 0 5 ergibt, dann sollte permute (1, [0,10], 5) 3 6 7 2 ergeben 4.

Parameter min, max und sample_size sind dynamische Variablen. Es ändert sich bei jeder Iteration.

+0

Dies unwahrscheinlich klingt, es zu finden ... Ihre beste Option könnte sein, es selbst zu schreiben. – Antzi

+0

Was machen Sie mit dem Ergebnisvektor? Wenn Sie Leistung benötigen, können Sie sie möglicherweise vollständig beseitigen. – sh1

+0

Eigentlich verwende ich eine C++ - Open-Source-Bibliothek namens PCG Random Number Generator. Es erlaubt 128-Bit-PRNG zu verwenden, unterstützt aber keine Permutationsfunktion wie Shuffle. – metlira

Antwort

1

Keine Notwendigkeit für eine Bibliothek (! So ist es eigentlich beim Thema)

std::shuffle gibt Ihnen die Permutation; Es dauert ein UniformRandomBitGenerator wie std::mt19937. std::mt19937::seed() nimmt eine Sequenz, so können Sie es 128 Bits des Ausgangszustands füttern. Und einen Teilbereich zu nehmen ist natürlich trivial.

+0

eine der Lösung ist genau so. aber das Problem ist PRNG mit 128-Bit-Schlüssel Seeding. Soweit ich weiß, verwendet mt19937 einen 32-Bit-Schlüssel und mt19937_64 einen 64-Bit-Schlüssel. – metlira

+0

@metlira: Nein, wie gesagt, 'seed()' nimmt eine Sequenz. IIRC, es gibt mehr als ** 500 ** Bundesstaaten. – MSalters

1

können Sie Fisher–Yates_shuffle verwenden:

// Fisher–Yates_shuffle 
std::vector<int> 
FisherYatesShuffle(std::size_t size, std::size_t max_size, std::mt19937& gen) 
{ 
    assert(size < max_size); 
    std::vector<int> res(size); 

    for (std::size_t i = 0; i != max_size; ++i) { 
     std::uniform_int_distribution<> dis(0, i); 
     std::size_t j = dis(gen); 
     if (j < res.size()) { 
      if (i < res.size()) { 
       res[i] = res[j]; 
      } 
      res[j] = i; 
     } 
    } 
    return res; 
} 

Live example

+0

was ist mit dem scope-operator die Hölle? Sie ** wissen **, dass es ein Schlüsselwort namens "using" gibt, oder? – specializt

+0

@specializt: Haben Sie sich [Warum-verwendet-Namespace-std-in-c-in Betracht gezogen-Bad-Praxis] (http://stackoverflow.com/questions/1452721/why-isusing-namespace-) std-in-c-betrachtet-schlechte-Praxis)? – Jarod42

+0

Lösung: http://Stackoverflow.com/a/1455227/351861 und ** vor allem **: http://Stackoverflow.com/a/26722134/351861 – specializt