Practice/FilterTest: 인스턴스 상태, 정렬 일관성, 고정 5조합·중복·과거당첨 제외; README 정리
Made-with: Cursor
This commit is contained in:
@@ -1,38 +1,33 @@
|
||||
"""
|
||||
`1_FilterTest_25.py`와 동일한 역할이며 `final_BallFilter.BallFilter` + `lotto_history.txt`를 사용합니다.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import itertools
|
||||
import os
|
||||
import random
|
||||
import pandas as pd
|
||||
import itertools
|
||||
from final_BallFilter import BallFilter
|
||||
import time
|
||||
import datetime
|
||||
|
||||
import pandas as pd
|
||||
|
||||
from final_BallFilter import BallFilter
|
||||
|
||||
|
||||
class FilterTest:
|
||||
ballFilter = None
|
||||
|
||||
def __init__(self, resources_path):
|
||||
lotto_path = os.path.join(resources_path, "lotto_history.txt")
|
||||
self.ballFilter = BallFilter(lotto_path)
|
||||
lottoHistoryFileName = os.path.join(resources_path, 'lotto_history.json')
|
||||
self.ballFilter = BallFilter(lottoHistoryFileName)
|
||||
|
||||
return
|
||||
|
||||
def find_filter_method(self, df_ball, filter_ball=None):
|
||||
win_count = 0
|
||||
|
||||
no_filter_ball = {}
|
||||
|
||||
printLog = True
|
||||
filter_dic = {}
|
||||
filter_dic_len = {}
|
||||
filter_dic_1 = {}
|
||||
filter_dic_2 = {}
|
||||
for i in range(len(df_ball) - 1, 19, -1):
|
||||
no = df_ball["no"].iloc[i]
|
||||
answer = df_ball[df_ball["no"] == no].values.tolist()[0]
|
||||
answer = sorted(int(x) for x in answer[1:7])
|
||||
for i in range(len(df_ball)-1, 19, -1):
|
||||
|
||||
no = df_ball['no'].iloc[i]
|
||||
answer = df_ball[df_ball['no'] == no].values.tolist()[0]
|
||||
answer = sorted(answer[1:7])
|
||||
|
||||
filter_type = self.ballFilter.filter(ball=answer, no=no, until_end=True, df=df_ball)
|
||||
filter_type = list(filter_type)
|
||||
@@ -44,23 +39,36 @@ class FilterTest:
|
||||
print("\t", no)
|
||||
elif size == 1:
|
||||
key = filter_type[0]
|
||||
filter_dic_1[key] = filter_dic_1.get(key, 0) + 1
|
||||
if key not in filter_dic_1:
|
||||
filter_dic_1[key] = 1
|
||||
else:
|
||||
filter_dic_1[key] += 1
|
||||
|
||||
if printLog:
|
||||
print("\t", no, filter_type)
|
||||
elif size == 2:
|
||||
key = ",".join(filter_type)
|
||||
filter_dic_2[key] = filter_dic_2.get(key, 0) + 1
|
||||
key = ','.join(filter_type)
|
||||
if key not in filter_dic_2:
|
||||
filter_dic_2[key] = 1
|
||||
else:
|
||||
filter_dic_2[key] += 1
|
||||
|
||||
if printLog:
|
||||
print("\t", no, filter_type)
|
||||
else:
|
||||
if printLog:
|
||||
print("\t", no, filter_type)
|
||||
|
||||
# 회차별 필터개수가 적은 것을 정렬하기 위함
|
||||
if size not in filter_dic_len:
|
||||
filter_dic_len[size] = []
|
||||
filter_dic_len[size].append(filter_type)
|
||||
|
||||
for f_t in filter_type:
|
||||
filter_dic[f_t] = filter_dic.get(f_t, 0) + 1
|
||||
if f_t not in filter_dic:
|
||||
filter_dic[f_t] = 1
|
||||
else:
|
||||
filter_dic[f_t] += 1
|
||||
|
||||
print("\n\t[필터 개수가 적은 것부터 최적화를 위함]")
|
||||
sorted_filter_dic_len = sorted(filter_dic_len.keys())
|
||||
@@ -93,28 +101,37 @@ class FilterTest:
|
||||
|
||||
def find_final_candidates(self, no, df_ball, filter_ball=None):
|
||||
final_candidates = []
|
||||
|
||||
generation_balls = list(range(1, 46))
|
||||
|
||||
nCr = list(itertools.combinations(generation_balls, 6))
|
||||
for idx, ball in enumerate(nCr):
|
||||
|
||||
if idx % 1000000 == 0:
|
||||
print(" - {} processed...".format(idx))
|
||||
|
||||
if filter_ball is not None and 0 < len(set(ball) & set(filter_ball)):
|
||||
continue
|
||||
|
||||
filter_type = self.ballFilter.filter(ball=list(ball), no=no, until_end=False, df=df_ball)
|
||||
if filter_type:
|
||||
ball = sorted(list(ball))
|
||||
filter_type = self.ballFilter.filter(ball=ball, no=no, until_end=False, df=df_ball)
|
||||
filter_size = len(filter_type)
|
||||
|
||||
if filter_size:
|
||||
continue
|
||||
|
||||
final_candidates.append(ball)
|
||||
|
||||
return final_candidates
|
||||
|
||||
def check_filter_method(self, df_ball, p_win_count, filter_ball=None):
|
||||
|
||||
win_count = 0
|
||||
for i in range(len(df_ball) - 1, 0, -1):
|
||||
no = df_ball["no"].iloc[i]
|
||||
answer = df_ball[df_ball["no"] == no].values.tolist()[0]
|
||||
answer = sorted(int(x) for x in answer[1:7])
|
||||
for i in range(len(df_ball)-1, 0, -1):
|
||||
|
||||
no = df_ball['no'].iloc[i]
|
||||
answer = df_ball[df_ball['no'] == no].values.tolist()[0]
|
||||
answer = sorted(answer[1:7])
|
||||
|
||||
if filter_ball is not None and len(set(answer) & set(filter_ball)):
|
||||
continue
|
||||
@@ -125,43 +142,74 @@ class FilterTest:
|
||||
win_count += 1
|
||||
print("\t\t>{}. {}".format(no, answer))
|
||||
|
||||
print("\n\t> {} / {} p_win_count, {} total".format(win_count, p_win_count, len(df_ball) - 1))
|
||||
print("\n\t> {} / {} p_win_count, {} total".format( win_count, p_win_count, len(df_ball)-1) )
|
||||
|
||||
def estimate_survivors_mc(self, no, df_ball, n_samples=8000, seed=0):
|
||||
"""전수(814만) 대신 무작위 조합으로 생존 비율을 추정해 대략적인 생존 개수를 반환합니다."""
|
||||
rng = random.Random(seed)
|
||||
generation_balls = list(range(1, 46))
|
||||
total = 8145060
|
||||
hits = 0
|
||||
for _ in range(n_samples):
|
||||
ball = sorted(rng.sample(generation_balls, 6))
|
||||
fts = self.ballFilter.filter(ball=ball, no=no, until_end=False, df=df_ball)
|
||||
if not fts:
|
||||
hits += 1
|
||||
est = int(round(total * (hits / n_samples)))
|
||||
return est, hits, n_samples
|
||||
return
|
||||
|
||||
def validate(self, df_ball, nos=None):
|
||||
win_history = {}
|
||||
|
||||
for no in nos:
|
||||
print(no, "processing...")
|
||||
answer = df_ball[df_ball['no'] == no].values.tolist()[0]
|
||||
answer = sorted(answer[1:7])
|
||||
|
||||
generation_balls = list(range(1, 46))
|
||||
nCr = list(itertools.combinations(generation_balls, 6))
|
||||
for idx, ball in enumerate(nCr):
|
||||
if idx % 1000000 == 0:
|
||||
print(" - {} processed...".format(idx))
|
||||
ball = sorted(list(ball))
|
||||
filter_type = self.ballFilter.extract_final_candidates(ball, no=no, until_end=True, df=df_ball)
|
||||
if 0 == len(filter_type) and len(set(answer)&set(ball))==6:
|
||||
win_history[no] = answer
|
||||
print("win.. no: {}, answer: {}".format(no, str(answer)))
|
||||
break
|
||||
|
||||
return win_history
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--resources", default="resources")
|
||||
parser.add_argument("--mc-no", type=int, default=None, help="생존 MC 추정을 할 회차 번호")
|
||||
parser.add_argument("--mc-samples", type=int, default=8000)
|
||||
args = parser.parse_args()
|
||||
if __name__ == '__main__':
|
||||
|
||||
resources_path = args.resources
|
||||
lottoHistoryFileName = os.path.join(resources_path, "lotto_history.txt")
|
||||
resources_path = 'resources'
|
||||
|
||||
lottoHistoryFileName = os.path.join(resources_path, 'lotto_history.txt')
|
||||
df_ball = pd.read_csv(lottoHistoryFileName, header=None)
|
||||
df_ball.columns = ["no", "b1", "b2", "b3", "b4", "b5", "b6", "bn"]
|
||||
df_ball.columns = ['no', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'bn']
|
||||
|
||||
filter_ball=[]
|
||||
filterTest = FilterTest(resources_path)
|
||||
|
||||
print("STEP #1. 필터 방법 추출")
|
||||
start = time.time()
|
||||
win_count = filterTest.find_filter_method(df_ball)
|
||||
win_count = filterTest.find_filter_method(df_ball, filter_ball)
|
||||
process_time = datetime.timedelta(seconds=time.time() - start)
|
||||
print("process_time: ", process_time)
|
||||
|
||||
if args.mc_no is not None:
|
||||
est, h, n = filterTest.estimate_survivors_mc(args.mc_no, df_ball, n_samples=args.mc_samples)
|
||||
print(f"MC 생존 추정 (회차 {args.mc_no}): 약 {est}개 (표본 통과 {h}/{n})")
|
||||
"""
|
||||
print("\n\n")
|
||||
no = df_ball['no'].values[-1]
|
||||
ball = df_ball[df_ball['no'] == no].values.tolist()[0]
|
||||
answer = ball[1:7]
|
||||
|
||||
print("STEP #0. 최종 후보 선정")
|
||||
start = time.time()
|
||||
final_candidates = filterTest.find_final_candidates(no, df_ball, filter_ball=None)
|
||||
process_time = datetime.timedelta(seconds=time.time() - start)
|
||||
print("process_time: ", process_time)
|
||||
|
||||
print(" > size: {}".format(len(final_candidates)))
|
||||
file_name = os.path.join(resources_path, 'final_candidates.biz_a1.txt')
|
||||
with open(file_name, 'w+') as outFp:
|
||||
for ball in final_candidates:
|
||||
ball_str = [str(b) for b in answer]
|
||||
outFp.write("{}\n".format(','.join(ball_str)))
|
||||
|
||||
print('{}회, 정답: {}\n'.format(no, str(answer)))
|
||||
"""
|
||||
|
||||
#print("\n\n")
|
||||
#print("STEP #2. 당첨 회수 확인")
|
||||
#filterTest.check_filter_method(df_ball, win_count)
|
||||
|
||||
# 오리지널 버전 (자질 파일에 고정): 당첨 22개
|
||||
Reference in New Issue
Block a user