2

Angenommen, wir haben eine Reihe von Elementen E und eine Reihe von Sets S.Zuweisungen mit minimalen Brüche

Wir brauchen Elemente setzt, so dass zuzuweisen:

  1. Alle in etwa die gleiche Anzahl von Elementen (Mindest Unterschied in Satzgröße zwischen dem kleinsten und dem größten Satz)
  2. Die Anzahl der Elemente enthalten Sätze pro Satz sollte so klein wie möglich sein.
  3. Jedes Element muss mindestens ein Minimum% der Sätze der Gesamtmenge zugewiesen werden. Diese% für jedes Element angegeben wird (diese bedeutet, dass Elemente sind natürlich entsprechend mehrere Sätze zugeordnet werden)

Beachten Sie, dass (1) und (2) sind Problem Ziele, und in einigen Fällen gibt es ein Nachteil ist, zwischen ihnen. Ich suche effektiv nach einer mathematischen Formulierung/Lösung, die diesen Kompromiss parameterisiert. Unterdessen (3) ist nur eine Problemeinschränkung.

Wie finden wir eine optimale Zuordnung? Hat dieses Problem einen Namen in der Literatur? Falls es darauf ankommt, suche ich speziell nach einer Lösung in Python.


Als Beispiel, sagen wir 3 Sätze und 10 Elemente haben, wobei jede von ihnen die min angibt. Fraktion von Sets wie folgt:

0  97.844356 
1  48.006223 
2  99.772135 
3  16.899074 
4  0.111023 
5  1.028894 
6  5.315590 
7 100.000000 
8  99.838698 
9  93.323315 
+0

Wenn es nur 3 Sätze gibt, zB 'S = 3', ist die Angabe von min Bruch als' 0.111023' oder '1.028894' nicht sinnvoll, da es genau 33 entspricht. –

+0

Dank @DmitriChubarov, deshalb sind sie Mindest. Brüche, aber ich verstehe Ihren Standpunkt. –

+0

Die Ziele 1 (minimaler Unterschied) und 3 (minimale Anzahl von Elementen) sind widersprüchlich: Angenommen, wir haben eine machbare Lösung, die die Bedingung 2 (minimale% der Mengen) erfüllt, die # (set1) = # (set2)> # (Satz3). Sollten wir set3 ein Element hinzufügen, um Ziel 1 zu verbessern oder es zu verlassen, um Ziel 3 beizubehalten? –

Antwort

2

Man könnte einfach drehen stufenlos über die Sätze, um den nächsten Satz zu bestimmen, zuzuordnen. Dann für jedes Element berechnet, wie viele Sätze es zugewiesen werden soll, und dann tun, um die Zuordnung entsprechend:

from itertools import cycle 
from math import ceil 

elems = [ 
    [0, 97.844356], 
    [1, 48.006223], 
    [2, 99.772135], 
    [3, 16.899074], 
    [4, 0.111023], 
    [5, 1.028894], 
    [6, 5.315590], 
    [7, 100.000000], 
    [8, 99.838698], 
    [9, 93.323315] 
] 

def assign(elements, n): 
    sets = [[] for _ in range(n)] 
    gen = (e for e, p in elements for _ in range(ceil(p*n/100))) 

    for s, e in zip(cycle(sets), gen): 
     s.append(e) 

    return sets 

print(assign(elems, 3)) 

Output:

[[0, 1, 2, 4, 7, 8, 9], [0, 1, 2, 5, 7, 8, 9], [0, 2, 3, 6, 7, 8, 9]] 

In oben cycle verwendet wird unendlich über die Zielsätze iterieren. gen ist ein Generator, der die minimale Menge an Elementen kehrt auf den Wahrscheinlichkeiten hinzuzufügen basiert:

>>> n = 3 
>>> gen = (e for e, p in elems for _ in range(ceil(p*n/100))) 
>>> list(gen) 
[0, 0, 0, 1, 1, 2, 2, 2, 3, 4, 5, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9] 

Schließlich zip verwendet wird (target set, element) Tupeln zu erzeugen, die dann in einer Schleife zugeordnet sind.

+0

Danke @niemmi. Das ist phänomenal. Wissen Sie zufällig, ob es in der Literatur einen Namen für dieses Problem gibt? –

+1

@ AmelioVazquez-Reina Ich habe keine Ahnung, wie der Name sein könnte, kam nur mit der Lösung, wenn ich das Problem gelesen habe. – niemmi