교수님께 기존 아이디어에 대해 피드백을 드렸더니
브루트포스 알고리즘은 너무 비효율적이고 재미가 없다고 하셨습니다
그래서 다른 알고리즘을 고민해보다가 한가지를 떠올렸습니다.
기존 아이디어가 가능한 모든 답에서 답이 될 수 없는 것들을 지워나가면서 답을 추론했다면
이번엔 거꾸로 제시된 결과를 토대로 가능한 정답군 집합을 만들어버리는 것입니다.
정답군 리스트에서 랜덤하게 수를 하나 제시하면 다시 결과를 알려줄 것이고
그렇다면 그 결과를 토대로 다시 정답군 집합을 또하나 만듭니다.
그리고 그 둘의 교집합을 구하면 되는 것이죠.
이 알고리즘의 단점은 두번째 정답군을 만드는 과정에서
굳이 필요없는 여집합이 될 요소들까지 카운트하게 된다는 점입니다.
이 부분에 대한 개선은 우선 추후에 고민하기로 하고, 앞서 생각한 아이디어를 코드로 구현해보기로 했습니다.
일단은 아이디어가 떠오르지 않아 제시한 숫자에 대한 결과를 보고
가능한 모든 정답을 튜플형태로 집합에 넣어 정답군 집합을 만들도록 하였습니다.
코드를 작성하면서 이게 더 효율적인건가 정말 고민을 많이 했네요...
from random import *
nums_list = []
frt = randint(1,9)
sec = randint(1,9)
while sec == frt: #and deffer:
sec = randint(1,9)
trd = randint(1,9)
while (trd == frt or trd == sec): #and deffer:
trd = randint(1,9)
cpu_try = (frt,sec,trd)
print(cpu_try)
answer_cmp1 = set()
result = tuple(map(int,input().split())) #st, bl
while True:
answer = set() #contemporary answer set
print('after clear :',answer)
if result == (3, 0): # answer = 3S
print('congraturation!')
break
elif result == (2, 0): # 2S 0B
for i in range(1, 10):
if i == frt or i == sec or i == trd:
continue
answer.add((frt, sec, i))
answer.add((frt, i, trd))
answer.add((i, sec, trd))
elif result == (1, 2): # 1S 2B
answer.add((frt, trd, sec))
answer.add((trd, sec, frt))
answer.add((sec, frt, trd))
elif result == (1, 1): # 1S 1B
for i in range(1, 10):
if i == frt or i == sec or i == trd:
continue
answer.add((frt, trd, i))
answer.add((frt, i, sec))
answer.add((trd, sec, i))
answer.add((i, sec, frt))
answer.add((sec, i, trd))
answer.add((i, frt, trd))
elif result == (1, 0): # 1S
for i in range(1, 10):
if i == frt or i == sec or i == trd:
continue
for j in range(1, 10):
if j == i or j == frt or j == sec or j == trd:
continue
answer.add((frt, i, j))
answer.add((i, sec, j))
answer.add((i, j, trd))
elif result == (0, 3): # 3B
answer.add((sec, trd, frt))
answer.add((trd, frt, sec))
elif result == (0, 2): # 2B
for i in range(1, 10):
if i == frt or i == sec or i == trd:
continue
if nums[i] == True:
answer.add((i, trd, sec))
answer.add((trd, i, sec))
answer.add((sec, trd, i))
answer.add((i, trd, frt))
answer.add((trd, i, frt))
answer.add((trd, frt, i))
answer.add((sec, frt, i))
answer.add((sec, i, frt))
answer.add((i, frt, sec))
elif result == (0, 1): # 1B
for i in range(1, 10):
if i == frt or i == sec or i == trd:
continue
for j in range(1, 10):
if j == i or j == frt or j == sec or j == trd:
continue
answer.add((i, frt, j))
answer.add((i, j, frt))
answer.add((sec, i, j))
answer.add((i, j, sec))
answer.add((trd, i, j))
answer.add((i, trd, j))
elif result == (0, 0):
for i in range(1,10):
if i == frt or i == sec or i == trd:
continue
for j in range(1,10):
if j == i or j == frt or j == sec or j == trd:
continue
for k in range(1,10):
if k == j or k == i or k == frt or k == sec or k == trd:
continue
answer.add((i, j, k))
if len(answer_cmp1) == 0:
print('first answer :',answer)
answer_cmp1 = answer
print(len(answer_cmp1))
else:
print('before answer_cmp1 : ', answer_cmp1)
print('after answer :', answer)
print(len(answer))
answer_cmp1 = answer_cmp1 & answer
print('after answer_cmp1 : ', answer_cmp1)
print(len(answer_cmp1))
cpu_try = choice(list(answer_cmp1))
frt = cpu_try[0]; sec = cpu_try[1]; trd = cpu_try[2]
print(cpu_try)
result = tuple(map(int,input().split()))
코드를 보면 알겠지만ㅋㅋ
정말 코드 작성하면서 컴퓨터가 할 노가다를 사람이 대신 해주고 있다는 걸 느꼈습니다
이게 맞는 건지 다시 교수님께 피드백을 받아봐야겠네요....
+++++++++++++++
교수님께 메일로 여쭤보니 위 알고리즘은 BFS알고리즘으로 짠 것 같다고 해주셨고,
지렇게 노가다로 모든 경우의 수를 하나하나 적어서 인공적인 지능이 있는 것처럼 보이게 만드는 것이
오래된 인공지능의 방법론이었다고 합니다.
이 알고리즘을 기반으로 한번 GUI를 입혀봐야겠네요!
'팀 프로젝트 > [2020] 인공지능 숫자야구' 카테고리의 다른 글
[팀프로젝트 01] 인공지능 숫자야구 만들기(4) : tkinter 입히기 (0) | 2020.06.03 |
---|---|
[팀프로젝트 01] 인공지능 숫자야구 만들기(2) : 인공지능 구현 (0) | 2020.05.28 |
[팀프로젝트 01] 인공지능 숫자야구 만들기(1) : 주제 구상 (0) | 2020.05.24 |