myślę, że jest to wspólny problem kombinatoryki, ale nie wydaje się znaleźć nazwę dla niego lub jakichkolwiek materiałów na jego temat. Robię to w Pythonie i numpy, ale jeśli jest na to szybka metoda macierzowa, prawdopodobnie mogę to przetłumaczyć.Efektywne poz binning algorytm (itertools/numpy)
Zasadniczo, biorąc pod uwagę n przedmiotów, muszę wygenerować wszystkie sposoby, aby umieścić je w m pojemników. Jako przykład binning 4 pozycji na 3 kosze dałby coś podobnego [(4, 0, 0), (3, 1, 0), (3, 0, 1), (2, 2, 0), (2, 1, 1), ...]
. To jest produkt o stałej wartości całkowitej.
Realizacja tego z itertools jest proste.
import itertools
def fixed_total_product(bins, num_items):
""" Return iterator of all item binning possibilities. """
return itertools.ifilter(lambda combo: sum(combo) == num_items,
itertools.product(xrange(num_items + 1), repeat=bins))
Niestety, myślę, że wykonanie kolejnych obliczeń w pętlach będzie nieefektywne. Praca z tym jako tablicą 2D numpy byłaby szybsza później, ale nie mogę wymyślić wydajnego sposobu na zbudowanie tablicy z tym. Mógłbym powtórzyć wynik ifiltera, budując listę możliwości i użyć tego do skonstruowania tablicy, ale wydaje się to ogromnym marnotrawstwem.
Zgaduję, że najlepszym sposobem, aby to zrobić jest budowanie wszystkiego „na drogę” numpy, ale nie jestem pewien, jak to zrobić. Istnieje szybka implementacja produktu na stackoverflow: Using numpy to build an array of all combinations of two arrays. Zgaduję, że możesz to zmienić tylko do produktów wyjściowych z odpowiednią sumą. Rozmiar tablicy powinien wynosić ((m-1) + n) wybrać n, ponieważ istnieją granice bin m-1.
Wszelkie pomysły? Benchmarks bardzo doceniane, ale nie wymagane.
że wspomniane [problem przegroda całkowita] (http://en.wikipedia.org/wiki/Partition_ (number_theory)), który podaje długość podobnej sekwencji. Nie sądzę, że jest to daleko, bo gdy już masz tę całkowitą sekwencję partycji, łatwo jest usunąć kolejność (dodać wszystkie permutacje) i wymusić kilka binów ('m' w' n' bins oznacza, że największa liczba w każdy bin może wynosić co najwyżej 'mn'). –
Oh sorry. Myślałem, że widziałem wcześniej rozwiązane/zamknięte. Muszę się jednak nie zgodzić na to rozwiązanie. Dodałem docstring i bardziej opisowe vars, aby pomóc zrozumieć algorytm ... –