Rozwiązanie mocno średniej zagadki

krótki URL: /75ms

kategorie:Jestem, więc myślę, Serie
tagi:rozwiązanie

Pierwsza część zagadki wydaje się być do ogarnięcia za pomocą komputera, jednak próby napisania w Pythonie algorytmu podziału zbioru na podzbiory pochłonęły mi zaskakująco dużo czasu. W końcu poddałem się i wziąłem gotowca z tej strony, minimalnie tylko przerabiając go na potrzeby zagadki.

import copy

def podział(zbiór):

    def podział_rek(zbiór, indeks, ret):
        if indeks == len(zbiór):
            yield ret
            return

        for i in range(len(ret)):
            ret[i].append(zbiór[indeks])
            yield from podział_rek(zbiór, indeks + 1, ret)
            ret[i].pop()

        ret.append([zbiór[indeks]])
        yield from podział_rek(zbiór, indeks + 1, ret)
        ret.pop()

    ret = []
    yield from podział_rek(zbiór, 0, ret)

def znajdź_optymalne_podziały(N):
    zbiór = list(range(1, N+1))
    średnia_całości = sum(zbiór)/len(zbiór)
    maksymalne_odchylenie = 0
    optymalne_podziały = []

    for p in podział(zbiór):
        średnia_średnich = sum(sum(zbiór)/len(zbiór) for zbiór in p) / len(p)
        odchylenie = abs(średnia_średnich - średnia_całości)

        if odchylenie > maksymalne_odchylenie:
            maksymalne_odchylenie = odchylenie
            optymalne_podziały = [copy.deepcopy(p)]
        elif odchylenie == maksymalne_odchylenie:
            optymalne_podziały.append(copy.deepcopy(p))

    return optymalne_podziały, maksymalne_odchylenie

def main():
    N = 12
    optymalne_podziały, maksymalne_odchylenie = znajdź_optymalne_podziały(N)
    print("Optymalne podziały:")
    for podział in optymalne_podziały:
        print("  ", podział)
    print("Maksymalne odchylenie: ", maksymalne_odchylenie)

if __name__ == '__main__':
    main()

Wynik:

Optymalne podziały:
   [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [11], [12]]
   [[1, 2, 3, 4, 5, 6, 7, 8, 9], [10], [11], [12]]
   [[1], [2], [3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]
   [[1], [2], [3], [4, 5, 6, 7, 8, 9, 10, 11, 12]]
Maksymalne odchylenie:  3.0

Jeżeli chodzi o drugą część zagadki, czyli rozwiązanie ogólne dla dowolnego N, to robi się ciekawie.

Trzeba najpierw zauważyć kilka spraw:

Po pierwsze, jeżeli z optymalnego rozwiązania weźmiemy dwa podzbiory, nazwijmy je S1 i S2, ze średnimi w każdym podzbiorze odpowiednio A1 i A2, takimi, że A1 < A2, to jest gwarantowane, że każda liczba w S1 jest mniejsza od każdej liczby w S2. Gdyby bowiem było inaczej, czyli gdyby w S1 była liczba X większa od liczby Y w S2, to dałoby się poprawić wynik zamieniając X i Y miejscami.

Po drugie zaś, jeżeli mamy dwa podzbiory S1 i S2 (w każdym co najmniej dwie liczby) ze średnimi A1

Komentarze