2016-11-11 11 views
0

Ich suche eine Person aus einer Liste von Personen, in der jedes Element in der Liste eine gewisse "Gewichtung" hat. Nehmen wir an, die Person-Klasse hat den notwendigen Konstruktor.C# und "Gewichtete Wahrscheinlichkeit"

public class Person { 
    public string Name { get; set; } 
    public float Weighting { get; set; } 
} 

public List<Person> People = new List<Person>(); 

People.Add(new Person("Tim", 1.0)); 
People.Add(new Person("John", 2.0)); 
People.Add(new Person("Michael", 4.0)); 

Jetzt möchte ich zufällig eine Person aus dieser Liste auswählen. Aber im Durchschnitt Ich möchte Michael 4 mal öfter als Tim holen. Und ich möchte John halb (2/4) so ​​oft wie Michael aussuchen. Und natürlich möchte ich Michael doppelt so oft auswählen wie John.

Macht das irgendeinen Sinn?

Ich habe bereits Code zur Auswahl von Personen basierend auf Prozentsätzen. Würde es nicht funktionieren, wenn ich nur die prozentuale Chance von ihnen mit der Gewichtung in diesem Beispiel multipliziere?

Auch mein aktuelles System funktioniert nur mit Chancen von bis zu 100%, nichts darüber. Irgendwelche Tipps, wie Sie diese Einschränkung überwinden können? Ich müsste wahrscheinlich jede Chance nach dem größten Faktor in der Liste skalieren?

public static bool Hit(double pct) { 
    if (rand == null) 
     rand = new Random(); 

    return rand.NextDouble() * 100 <= pct; 
} 

Oder fehlt mir etwas?

+0

Ihre Fragen sind etwas vage, und nicht wirklich geeignet für dieses Forum, aber ich kann nichts falsch mit Ihrer vorgeschlagenen Ansätze sehen. Schlagen Sie vor, dass Sie zuerst etwas versuchen, und wenn es nicht funktioniert, können Sie hier (oder ein geeigneteres Forum) zurückkommen und eine spezifische Frage zu einem bestimmten Codeproblem stellen. – LordWilmore

Antwort

1

Sie behalten keine Prozentsätze für den Anfang.

Ich würde eine Zufallszahl im Bereich von 0 bis zur Summe aller Weighting Werte erstellen. Gehen Sie dann einfach über die Liste und prüfen Sie, ob der Wert niedriger ist als das aktuelle und das eigene Gewicht.

So:

float r = YourRandomNumber(People.Sum(p => p.Weighting)); 
float sum = 0; 

foreach (Person p in People) 
{ 
    if (r < (sum + p.Weighting)) 
    { 
     // hit 
     // save the person somewhere 
     break; 
    } 
    else 
    { 
     sum += p.Weighting; 
    } 
}