Certo, è abbastanza semplice da fare.
Prendi la somma di entrambi i valori di dominanza e prendi un valore random.randrange()
di questi.
Se quel valore è inferiore al valore di dominanza del genitore A, hai scelto quella caratteristica del genitore, altrimenti è la caratteristica genitore di B che hai scelto:
import random
if random.randrange(parentA.dominance + parentB.dominance) < parentA.dominance:
trait = parentA.trait
else:
trait = parentB.trait
In altre parole, è una selezione casuale ponderata molto semplice tra due opzioni.
Per il tuo esempio specifico, la somma delle dominanze è 9, quindi il valore randrange()
è uno tra 0 e 8; se viene selezionato 0 o 1, viene selezionato il tratto del genitore A, se viene selezionato 2, 3, 4, 5, 6, 7 o 8, allora viene selezionato il tratto del genitore B.
Se invece stai parlando di scegliere un tratto su un intervallo dal valore tratto del genitore A fino al valore tratto del genitore B in cui i tratti sono trattati come un intervallo, allora i tuoi valori di dominanza sono usati per "tirare" un valore tratto verso uno o l'altro genitore.
In pratica si tratta di un tiro alla fune tra i genitori. Con il predominio bilanciato, il tratto scelto sarebbe, in media, sceso al valore medio dei due tratti. Ma con un genitore che domina l'altro, il valore della caratteristica ha selezionato "spostamenti" verso il genitore dominante.
Ciò si traduce in una possibilità che i valori al di sotto del punto medio vengano selezionati per il genitore A abbiano una possibilità di parentA.dominance in (parentA.dominance + parentB.dominance), mentre i valori sopra il punto medio hanno una possibilità di parentB.dominance in (parentA.dominance + parentB.dominance) di essere scelto.
import random
pick = random.random()
# sort parents by trait; smallest trait first
parents = sorted((parentA, parentB), key=attrgetter('trait'))
average = (parents[0].trait + parents[1].trait) / 2.0
weights = []
slots = (parents[1].trait - parents[0].trait + 1.0) * (parents[0].dominance + parents[1].dominance)
for i in range(parents[0].trait, parents[1].trait + 1):
if i <= average:
weights.append(sum(weights) + (parents[0].dominance / slots))
else:
weights.append(sum(weights) + (parents[1].dominance / slots))
if weights[-1] > pick:
return i
Un rapido tratto di raccolta demo tra il genitore A e il genitore B utilizzando il calcolo precedente:
>>> for i in range(40): print pickTrait(),
...
9 9 9 10 6 9 8 10 7 9 9 8 8 8 9 8 9 9 7 5 8 8 9 5 9 9 10 10 10 10 5 5 9 9 8 9 10 7 8 9