2016-06-28 10 views
7

Mam dwa wektory z taką samą liczbą elementów, ale ich typy mają zupełnie różne rozmiary. Muszę je przetasować, aby po tasowaniu obie miały tę samą kolejność (każdy element w jednym wektorze jest powiązany z każdym elementem w drugim). Sposób, w jaki to zrobiłem:Czy `std :: shuffle` gwarantuje taką samą kolejność z tym samym materiałem siewnym na różnych wektorach?

// sizeof(a[0]) != sizeof(b[0]) 
// a.size() == b.size() 
{ 
    std::mt19937 g(same_seed); 
    std::shuffle(a.begin(), a.end(), g); 
} 
{ 
    std::mt19937 g(same_seed); 
    std::shuffle(b.begin(), b.end(), g); 
} 

Czy mogę mieć pewność, że oba wektory zostaną przemieszane w ten sam sposób? Czy ta implementacja jest zależna? Czy mam taką gwarancję od specyfikacji std::shuffle?

+4

Najprawdopodobniej najlepiej byłoby spakować je do wektora par przed wykonaniem shuffle, lub zamiast tego stworzyć nowy wektor indeksów, potasować to i użyć go do zindeksowania w równoległych wektorach. – Taywee

+0

Moja pierwsza próba była wektorem indeksów, ale moje dane są duże i nie mieszczą się w dwóch kopiach w mojej pamięci, dlatego próbowałem załadować je z dysku w kolejności losowej, co oczywiście było niesamowicie powolne. Zrobiłem to w inny sposób, aby móc czytać z dysku sekwencyjnie (bardzo szybko) i tasować w miejscu (bez podwójnej pamięci). – lvella

+0

Specyfikacja tego nie gwarantuje, chociaż trudno jest wyobrazić sobie implementację, która nie dałaby ograniczeń, które standard nakłada na przetasowanie. Sam algorytm "suffle" wydaje się dość prosty do napisania, więc napisałbym własną implementację, która dałaby mi gwarancję. https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle – Galik

Odpowiedz

8

Interesujący jest oświadczenie o shuffle specyfikacji:

Uwagi: Do tego stopnia, że ​​realizacja tej funkcji korzysta z liczb losowych, obiekt g powinien służyć jako źródło wdrażania za przypadkowości.

Mimo to takie stwierdzenie nie pomaga. Sekcja "Uwagi" jest tekstem normatywnym, więc mówi się, że g dostarczy losowe liczby w celu określenia kolejności losowej. Jednak nie deklaruje, że jedynym czynnikiem decydującym o permutacji jest g.

Podczas gdy rozmiar wartości pojemnika prawdopodobnie nie ma znaczenia, nie ma gwarancji, że pewna właściwość tego typu nie wpłynie na coś. Na przykład, jeśli typ wartości byłby trywialnie kopiowany, implementacja może używać innej wersji funkcji, która używa nieco innego algorytmu. Jeśli jednak była to wartość wielkości rejestru, może nie być.

W skrócie, nie, std::shuffle nie gwarantuje, czego szukasz.

Powiązane problemy