Реализуйте включение-исключение эффективно - PullRequest
1 голос
/ 26 мая 2019

Я пытаюсь эффективно реализовать включение-исключение для следующих значений:

2/5, 2/5, 2/10, 2/10, 2/15, 2/15, ...

Конечно, программа не может работать бесконечно долго, поэтому я хотел бы поставитьнастраиваемый лимит на количество терминов.

Например, допустим, я ограничил свой расчет:

2/5, 2/5, 2/10, 2/10

Тогда расчет будет:

+ 2/5 + 2/5 + 2/10 + 2/10                  # choose 1 out of 4 terms
- 4/25 - 4/50 - 4/50 - 4/50 - 4/50 - 4/100 # choose 2 out of 4 terms
+ 8/250 + 8/250 + 8/500 + 8/500            # choose 3 out of 4 terms
- 16/2500                                  # choose 4 out of 4 terms

Iнайти, что «выбрать x из y» итеративным способом немного сложнее.

Вот моя текущая реализация:

from decimal import Decimal
from decimal import getcontext

getcontext().prec = 100

def getBits(num):
    bit = 0
    bits = []
    while num > 0:
        if num & 1:
            bits.append(bit)
        bit += 1
        num >>= 1
    return bits

def prod(arr):
    res = Decimal(1)
    for val in arr:
        res *= val
    return res

SIZE = 20
sums = [Decimal(0) for k in range(SIZE)]
temp = [Decimal(2)/(5*k) for k in range(1,SIZE)]
probabilities = [p for pair in zip(temp,temp) for p in pair][:SIZE]

for n in range(1,1<<SIZE):
    bits = getBits(n)
    sums[len(bits)-1] += prod([probabilities[bit] for bit in bits])

total = 0
for k in range(SIZE):
    total += sums[k]*(-1)**k
print(total)

Как вы можете видеть, я делаю «выбор»x из y термов "путем генерации каждой возможной битовой комбинации между 1 и 2 ** SIZE, а затем выбора термов в массиве probabilities, которые расположены в позициях, отмеченных 1 в текущем битовом коде.комбинация.

Я, по сути, ищу более эффективный способ сделать это, поскольку число итераций растет экспоненциально на величину SIZE.

Я осознаю тот факт, что этоможет быть неосуществимым, потому чтообщее количество членов в выражении включения-исключения является технически экспоненциальным (сумма строки в треугольнике Паскаля).

Однако, поскольку значения в probabilities все известны и «хороши» (т. е.степень 2, деленная на произведение 5), я подумал, что здесь, возможно, есть «ярлык», который я упустил.

Большое спасибо за любые идеи !!!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...