Mam c++ vector
z std::pair<unsigned long, unsigned long>
przedmiotami. Próbuję wygenerować permutacje obiektów wektora za pomocą std::next_permutation()
. Jednak chcę, aby permutacje miały określony rozmiar, wiesz, podobny do permutations
funkcji w pythonie, w której określono rozmiar oczekiwanej zwróconej permutacji.
Zasadniczo c++
odpowiednik
import itertools
list = [1,2,3,4,5,6,7]
for permutation in itertools.permutations(list, 3):
print(permutation)
(1, 2, 3)
(1, 2, 4)
(1, 2, 5)
(1, 2, 6)
(1, 2, 7)
(1, 3, 2)
(1, 3, 4)
..
(7, 5, 4)
(7, 5, 6)
(7, 6, 1)
(7, 6, 2)
(7, 6, 3)
(7, 6, 4)
(7, 6, 5)
python
c++
permutation
d4rk4ng31
źródło
źródło
(1, 1)
? permutacje Pythona zapewniają duplikaty[(1, 1), (1, 1)]
, alestd::next_permutation
unikaj duplikatów (tylko{1, 1}
).Odpowiedzi:
Możesz użyć 2 pętli:
Próbny
źródło
std::next_permutation
jest „niejasna”, ponieważ liczy się zamiana (liniowa). Ekstrakcję wektora podrzędnego można poprawić, ale nie sądzę, aby zmieniała złożoność. Ponadto liczba permutacji zależy od wielkości wektora, więc parametr 2 nie jest niezależny.std::vector<T>& v
?v
obecnie). Mógłbym przejść przez const referen i zamiast tego utworzyć posortowaną kopię w treści.Jeśli wydajność nie jest najważniejsza, możemy iterować po wszystkich permutacjach i pomijać te, które różnią się sufiksem, wybierając tylko każdą z
(N - k)!
nich. Na przykład dlaN = 4, k = 2
mamy permutacje:gdzie wstawiłem spację dla jasności i oznaczyłem każdą i
(N-k)! = 2! = 2
ostatnią permutację za pomocą<
.Wynik:
źródło
Oto skuteczny algorytm, który nie używa
std::next_permutation
bezpośrednio, ale wykorzystuje konie robocze tej funkcji. To znaczystd::swap
istd::reverse
. Na plus jest w porządku leksykograficznym .I nazywając to mamy:
Oto wynik:
Oto kod, który można uruchomić z ideone
źródło
bool nextPartialPermutation(It begin, It mid, It end)
Włączając odpowiedź Josepha Wooda z interfejsem iteratora, możesz mieć metodę podobną do
std::next_permutation
:Próbny
źródło
To jest moje rozwiązanie po namyśle
Skomentuj swoje przemyślenia
źródło
permute
może w rzeczywistości tylkoset.insert(vec);
usunąć duży czynnik.O(nb_total_perm * log(nb_res))
(nb_total_perm
która jest główniefactorial(job_list.size())
inb_res
wielkość wynikupermutations.size()
:), więc wciąż za duża. (ale teraz radzisz sobie z duplikatami danych sprzecznymi z Evgiem)