Нечеткий выбор между переменным числом наборов - PullRequest
1 голос
/ 25 июня 2011

Мне было интересно, какой самый простой и настраиваемый способ получить то, что мне нужно, в следующей ситуации:

  • У меня есть счетчик, назовем его X, который будет использоваться для извлеченияодин из наборов
  • У меня есть переменное число наборов S1, S2, .., которое можно считать Всего упорядочено между собой
  • Я хочу смешать эти наборы нечетким образомтак что для X = 0 это даст мне S1, для, скажем, X = 20 это даст мне S1 с вероятностью 70% и S2 с вероятностью 30%
  • Увеличение X уменьшит вероятность S1 до 0% при увеличении S2 до 100%, тогда может быть зона, в которой он всегда будет давать мне S2 до нового порога, для которого S2 начнетуменьшится и S3 начнет получать шанс и так далее

Я знаю, как сделать это, жестко закодировав все, но так как это потребует некоторой настройки, я хотел бы применить решение, которое легко позволяет мненастроить сколько установитьУ меня есть и единичные пороги (начало / конец увеличения вероятности и начало / конец уменьшения вероятности).Конечно, мне не нужно пересечение между более чем двумя наборами каждый, и линейное увеличение / уменьшение вероятности в порядке ... есть хорошие подсказки?

Спасибо заранее!

1 Ответ

1 голос
/ 25 июня 2011

Чтобы назначить распределение вероятностей, вы можете использовать полиномы Бернштейна:

http://en.wikipedia.org/wiki/Bernstein_polynomial

Они могут быть эффективно вычислены с использованием алгоритма де Кастельжау (в основном это делает DP на рекурсии вочевидный путь):

http://en.wikipedia.org/wiki/De_Casteljau's_algorithm

http://www.cs.mtu.edu/~shene/COURSES/cs3621/NOTES/spline/Bezier/de-casteljau.html

В результате вы получите набор весов для распределений.Чтобы выбрать один из ваших наборов, вы просто генерируете равномерную случайную переменную в [0,1], а затем выбираете набор, в который она попадает, основываясь на этих весах.

Вот код на python, который делает это:

import random

#Selects one of the n sets with a weight based on x
def pick_a_set(n, x):

    #Compute bernstein polynomials
    weights = [ [ float(i == j)  for j in range(n) ] for i in range(n) ]
    for k in range(n):
        for j in range(n-k-1):
            for i in range(n):
                weights[j][i] = weights[j][i] * (1.0 - x) + weights[j+1][i] * x

    #Select using weights
    u = random.random()
    for k in range(n):
        if u < weights[0][k]:
            return k
        u -= weights[0][k]
    return 0
...