У меня есть файл Excel с x строками со случайными числами (от 1 до 25). Общее количество столбцов (цифр) может варьироваться (15, 16, 17, 18, 19 или 20):
Мне нужен Python, чтобы сообщить мне мою вероятность выигрыша в лотерею с текущим набором строк (может быть 30 тыс. строк с 15,16,17,18,19 или 20 числами). Лотерея представляет собой розыгрыш 15 номеров из пула из 25 номеров (от 1 до 25).
Это то, что у меня есть до сих пор:
import pandas as pd
from math import comb
# Load the Excel file
file_path = 'combinations.xlsx'
df = pd.read_excel(file_path)
# Define the total number of possible combinations for a 15-number draw from a pool of 25 numbers
total_combinations = comb(25, 15)
# Function to calculate the number of matches
def count_matches(row, drawn_numbers):
return sum(1 for number in row if number in drawn_numbers)
# Since we don't have the drawn numbers, we'll assume a hypothetical draw
# For example, let's assume the drawn numbers are the first 15 numbers in the pool
drawn_numbers = list(range(1, 16))
# Calculate the total probability for the entire file
total_probability = 0
for index, row in df.iterrows():
matches = count_matches(row.dropna().tolist(), drawn_numbers)
probability = matches / total_combinations
total_probability += probability
# Calculate the inverse probability
inverse_probability = 1 / total_probability if total_probability != 0 else float('inf')
# Print the results
print(f"Total probability for the entire file: {total_probability}")
print(f"The probability of winning is 1 in {int(inverse_probability):,}")
Он работает без ошибок, однако результат неверен. глядя на официальный сайт лотереи и рассчитывая вероятность вручную, известно, что:
Вот результат, который мой код дает для файла с простой строкой из 15 чисел:
Мой файл может содержать разные строки из 15, 16, 17,18,19 или 20 чисел, отсюда и необходимость расчета вероятности разных комбинаций.
Есть ли волшебник по Python, который может помочь?
да, однако купить 252 билета с 20 номерами по цене нереально, она будет выше, чем сам приз, кроме того, существует правило, запрещающее такую ставку. Это розыгрыш 15 номеров из пула из 25 номеров (1-25). Можно купить билеты на 15, 16, 17, 18, 19 или 20 номеров или любую их комбинацию, на которую у него есть деньги.
Чтобы создать выигрышную стратегию, необходимо также знать ставку и приз(ы) для каждого из различных вариантов. Но, вероятно, его нет. Ирландская лотерея была довольно глупой ошибкой операторов. Полная история здесь Как выиграть в лотерее
@MartinBrown: Их количество для n чисел равно C(25, 15) / C(n, 15), округленное до целого числа. Другими словами, при наличии n чисел можно выбрать C(n, 15) комбинаций из 15 чисел, так что у них есть C(n, 15) шансов получить выпавшую комбинацию из 15 чисел, причем каждый шанс равен 1 / C(25). , 15).
@EricPostpischil Спасибо за это — я никогда раньше не сталкивался с такой лотереей.
Это требует некоторого вероятностного рассуждения.
Как следует из комментариев, учитывая длину строки n, вероятность того, что эта строка выиграет в лотерею, равна гребенке (n, 15) / гребенке (25, 15). Следовательно, мы можем построить массив вероятностей p для строк длиной 15–20:
p = np.array([comb(n, 15) / comb(25,15) for n in range(15, 21)])
Предполагая, что строки действительно генерируются случайным образом и независимы друг от друга, мы можем вычислить вероятность того, что на листе есть строка, которая выиграет в лотерею:
Поэтому нам нужно посчитать количество строк каждой длины в таблице данных (сколько строк с 15 записями, сколько с 16 и т. д.). Вот функция, которая может это сделать:
def CountRowLength(df):
"""Returns a dictionary with keys corresponding to row length and values corresponding to the number of times they occur"""
answer = dict()
for _, row in df.iterrows():
rowLength = len(row.dropna().tolist())
if rowLength in answer.keys():
answer[rowLength] += 1
else:
answer[rowLength] = 1
return answer
Поэтому все, что остается, — это преобразовать этот словарь в массив/список и подключить его к формуле, полученной ранее:
# Convert the dictionary to a list
dictionary = CountRowLength(df)
lengths = [dictionary[i] if i in dictionary.keys() else 0 for i in range(15,21)]
# The formula from earlier
total_probability = 1 - np.product([(1-p[i])**lengths[i] for i in range(len(p))])
print(f"The probability that a row from this sheet has a lottery win is {total_probability}")
Затем вы можете взять обратную величину, чтобы найти шансы.
Это очень хорошо, спасибо @mraystaf
Значения для 15 и 16 полностью соответствуют формуле «гребень(25,15)» и «гребень(25,16) соответственно, а значения для 17 и выше — нет. Что вы нам не рассказали о правилах вашей лотереи? Я ожидаю, что 17 будет 1:1081575, 18 будет 480700, а 24 будет 1:25. Если шансы действительно такие, как вы их описываете, то вы потенциально можете сорвать банк, купив около 252 или более билетов с 20 номерами за набор чисел, выбранный для максимизации их энтропии. Ирландская лотерея, как известно, не смогла справиться с такой грубой атакой со схемой 6/36 и слишком большим количеством щедрых мелких призов.