function r = rucksackGenetic(leer,auswahl)
    anzahlGenerationen = 100;   % Wie lange soll optimiert werden?
    genpoolGroesse = 100;       % Wie viele Lösungen werden pro Iteration betrachtet?
    genpool = Rucksack.empty;
    fittest = 10;               % Wie viele Lösungen werden jeweils übernommen?
    % Ursprungsgeneration besteht aus zufaellig gepackten Rucksäcken
    for pool = 1:genpoolGroesse
        neu = zufaelligerRucksack(leer,auswahl);
        while neu.gesamtgewicht() > neu.kapazitaet
            neu = zufaelligerRucksack(leer,auswahl);
        end
        genpool = [genpool neu];
    end
    % Eigentliche Optimierung:
    for generation = 1:anzahlGenerationen
            % Survival of the fittest: die besten Rucksäcke aus der letzten
            % Runde werden übernommen
            [~, ind] = sort([genpool.gesamtnutzen],'descend');
            sortiertergenpool = genpool(ind);
            survivors = sortiertergenpool(1:fittest);
            % restlichen Genpool neu füllen mit Mutatioten der besten
            % Rucksäcke
            genpool = survivors;
            for i = fittest+1:genpoolGroesse
                neu = mutation(survivors(randi(fittest)),auswahl);
                if neu.gesamtgewicht > neu.kapazitaet
                    continue;
                end
                genpool = [genpool neu];
            end
    end
    % Am Ende wird nur der beste Rucksack zurückgeliefert
    [~, ind] = sort([genpool.gesamtnutzen],'descend');
    sortiertergenpool = genpool(ind);
    r = genpool(1);
end

function r = zufaelligerRucksack(leer,auswahl)
    % Zufaellig bis zu 10 Gegenstände einpacken
    r = copy(leer);
    for j = 1:randi(10)
        gz = auswahl(randi(length(auswahl)));
        r.gegenstandEinpacken(gz);
    end
end

function r = mutation(alt,auswahl)
    % Einen zufaelligen Gegenstand im Rucksack ersetzen
    r = copy(alt);
    gz = auswahl(randi(length(auswahl)));
    pos = randi(length(r.inhalt));
    r.inhalt(pos) = [];
    r.gegenstandEinpacken(gz);
end