"""
learnstock.py
帰納的学習による10桁のパターン探索
パターンA・B・C・Dの比較
"""
import random
# グローバル変数
SETSIZE = 100 # 学習データの数
CNO = 10 # パターンの桁数
GENMAX = 10000 # 解候補を生成する回数
SEED = 7 # 乱数の初期値
# 学習データと教師データを読み込む関数
def readdata(data, teacher):
for i in range(SETSIZE):
line = input()
data[i] = [int(num) for num in line.split()]
teacher[i] = data[i][CNO]
# 解候補のスコアを計算する関数
def calcscore(data, teacher, answer):
score = 0
for i in range(SETSIZE):
point = 0
# 学習データと解候補の一致度を調べる
for j in range(CNO):
if answer[j] == 2:
point += 1
elif answer[j] == data[i][j]:
point += 1
# 教師データに対する正解数を数える
if point == CNO and teacher[i] == 1:
score += 1
elif point != CNO and teacher[i] == 0:
score += 1
return score
# パターンを検査データに適用する関数
def predict(pattern, testdata):
result = []
for row in testdata:
point = 0
for j in range(CNO):
if pattern[j] == 2:
point += 1
elif pattern[j] == row[j]:
point += 1
# 10桁すべてが一致すれば1、そうでなければ0
if point == CNO:
result.append(1)
else:
result.append(0)
return result
# 表2.2の検査データ
testdata = [
[0, 0, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 0, 1, 0, 0, 1, 0, 0],
[0, 0, 1, 0, 0, 1, 0, 0, 1, 1],
[1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 0, 0, 1, 0, 1, 0, 1],
[1, 0, 1, 1, 1, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 1, 1, 1, 1, 0, 1],
[0, 1, 1, 0, 1, 0, 1, 1, 1, 1],
[0, 0, 1, 0, 1, 0, 1, 0, 1, 1],
[1, 1, 1, 0, 1, 0, 1, 0, 1, 1]
]
# 表2.2に記載された正しい結果
correct = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0]
# メイン処理
data = [[] for i in range(SETSIZE)]
teacher = [0 for i in range(SETSIZE)]
bestscore = 0
bestanswer = [0 for i in range(CNO)]
# パターンA・Bを設定する
patternA = [2, 2, 0, 2, 2, 2, 0, 2, 0, 2]
patternB = [2, 2, 0, 2, 2, 2, 2, 2, 0, 2]
# パターンC・Dの候補を保存する
candidate_patterns = {}
# 乱数を初期化する
random.seed(SEED)
# 学習データを読み込む
readdata(data, teacher)
# パターンA・Bの学習データに対するスコア
scoreA = calcscore(data, teacher, patternA)
scoreB = calcscore(data, teacher, patternB)
print("パターンAのスコア =", scoreA)
print("パターンBのスコア =", scoreB)
# 解候補を生成して評価する
for i in range(GENMAX):
answer = [random.randint(0, 2) for j in range(CNO)]
score = calcscore(data, teacher, answer)
# 全体の最良解を更新する
if score > bestscore:
bestscore = score
bestanswer = answer.copy()
# スコア84点・100点以外の候補を記録する
if score != 84 and score != 100:
pattern = tuple(answer)
# 同じパターンを重複して登録しない
if pattern not in candidate_patterns:
candidate_patterns[pattern] = score
# スコアの高い順に並べる
sorted_patterns = sorted(
candidate_patterns.items(),
key=lambda item: item[1],
reverse=True
)
# A・Bと同じパターンは候補から除く
patternA_tuple = tuple(patternA)
patternB_tuple = tuple(patternB)
sorted_patterns = [
item for item in sorted_patterns
if item[0] != patternA_tuple
and item[0] != patternB_tuple
]
# C・Dを選ぶ
patterns = {
"A": patternA,
"B": patternB
}
if len(sorted_patterns) >= 1:
patterns["C"] = list(sorted_patterns[0][0])
if len(sorted_patterns) >= 2:
patterns["D"] = list(sorted_patterns[1][0])
# A・B・C・Dの予測結果を表示する
print("\n表2.2 検査データの予測結果")
print("番号 正解 A予測 B予測 C予測 D予測")
predictions = {}
for name, pattern in patterns.items():
predictions[name] = predict(pattern, testdata)
for i in range(len(testdata)):
values = []
for name in ["A", "B", "C", "D"]:
if name in predictions:
values.append(str(predictions[name][i]))
else:
values.append("-")
print(
i + 1, correct[i],
values[0], values[1], values[2], values[3]
)
# 各パターンの正解数を表示する
print("\n検査データ10例の正解数")
for name in ["A", "B", "C", "D"]:
if name in predictions:
count = 0
for i in range(len(correct)):
if predictions[name][i] == correct[i]:
count += 1
print(name, ":", count, "/ 10")
# 探索全体の最良解を表示する
print("\n探索全体の最良解")
print(bestanswer, ":score=", bestscore)
# your code goes here
CiIiIgpsZWFybnN0b2NrLnB5CuW4sOe0jeeahOWtpue/kuOBq+OCiOOCizEw5qGB44Gu44OR44K/44O844Oz5o6i57SiCuODkeOCv+ODvOODs0Hjg7tC44O7Q+ODu0Tjga7mr5TovIMKIiIiCgppbXBvcnQgcmFuZG9tCgojIOOCsOODreODvOODkOODq+WkieaVsApTRVRTSVpFID0gMTAwICAgICAgICMg5a2m57+S44OH44O844K/44Gu5pWwCkNOTyA9IDEwICAgICAgICAgICAgIyDjg5Hjgr/jg7zjg7Pjga7moYHmlbAKR0VOTUFYID0gMTAwMDAgICAgICAjIOino+WAmeijnOOCkueUn+aIkOOBmeOCi+WbnuaVsApTRUVEID0gNyAgICAgICAgICAgICMg5Lmx5pWw44Gu5Yid5pyf5YCkCgoKIyDlrabnv5Ljg4fjg7zjgr/jgajmlZnluKvjg4fjg7zjgr/jgpLoqq3jgb/ovrzjgoDplqLmlbAKZGVmIHJlYWRkYXRhKGRhdGEsIHRlYWNoZXIpOgogICAgZm9yIGkgaW4gcmFuZ2UoU0VUU0laRSk6CiAgICAgICAgbGluZSA9IGlucHV0KCkKICAgICAgICBkYXRhW2ldID0gW2ludChudW0pIGZvciBudW0gaW4gbGluZS5zcGxpdCgpXQogICAgICAgIHRlYWNoZXJbaV0gPSBkYXRhW2ldW0NOT10KCgojIOino+WAmeijnOOBruOCueOCs+OCouOCkuioiOeul+OBmeOCi+mWouaVsApkZWYgY2FsY3Njb3JlKGRhdGEsIHRlYWNoZXIsIGFuc3dlcik6CiAgICBzY29yZSA9IDAKCiAgICBmb3IgaSBpbiByYW5nZShTRVRTSVpFKToKICAgICAgICBwb2ludCA9IDAKCiAgICAgICAgIyDlrabnv5Ljg4fjg7zjgr/jgajop6PlgJnoo5zjga7kuIDoh7TluqbjgpLoqr/jgbnjgosKICAgICAgICBmb3IgaiBpbiByYW5nZShDTk8pOgogICAgICAgICAgICBpZiBhbnN3ZXJbal0gPT0gMjoKICAgICAgICAgICAgICAgIHBvaW50ICs9IDEKICAgICAgICAgICAgZWxpZiBhbnN3ZXJbal0gPT0gZGF0YVtpXVtqXToKICAgICAgICAgICAgICAgIHBvaW50ICs9IDEKCiAgICAgICAgIyDmlZnluKvjg4fjg7zjgr/jgavlr77jgZnjgovmraPop6PmlbDjgpLmlbDjgYjjgosKICAgICAgICBpZiBwb2ludCA9PSBDTk8gYW5kIHRlYWNoZXJbaV0gPT0gMToKICAgICAgICAgICAgc2NvcmUgKz0gMQogICAgICAgIGVsaWYgcG9pbnQgIT0gQ05PIGFuZCB0ZWFjaGVyW2ldID09IDA6CiAgICAgICAgICAgIHNjb3JlICs9IDEKCiAgICByZXR1cm4gc2NvcmUKCgojIOODkeOCv+ODvOODs+OCkuaknOafu+ODh+ODvOOCv+OBq+mBqeeUqOOBmeOCi+mWouaVsApkZWYgcHJlZGljdChwYXR0ZXJuLCB0ZXN0ZGF0YSk6CiAgICByZXN1bHQgPSBbXQoKICAgIGZvciByb3cgaW4gdGVzdGRhdGE6CiAgICAgICAgcG9pbnQgPSAwCgogICAgICAgIGZvciBqIGluIHJhbmdlKENOTyk6CiAgICAgICAgICAgIGlmIHBhdHRlcm5bal0gPT0gMjoKICAgICAgICAgICAgICAgIHBvaW50ICs9IDEKICAgICAgICAgICAgZWxpZiBwYXR0ZXJuW2pdID09IHJvd1tqXToKICAgICAgICAgICAgICAgIHBvaW50ICs9IDEKCiAgICAgICAgIyAxMOahgeOBmeOBueOBpuOBjOS4gOiHtOOBmeOCjOOBsDHjgIHjgZ3jgYbjgafjgarjgZHjgozjgbAwCiAgICAgICAgaWYgcG9pbnQgPT0gQ05POgogICAgICAgICAgICByZXN1bHQuYXBwZW5kKDEpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgcmVzdWx0LmFwcGVuZCgwKQoKICAgIHJldHVybiByZXN1bHQKCgojIOihqDIuMuOBruaknOafu+ODh+ODvOOCvwp0ZXN0ZGF0YSA9IFsKICAgIFswLCAwLCAwLCAxLCAwLCAxLCAwLCAwLCAwLCAwXSwKICAgIFswLCAwLCAxLCAwLCAxLCAwLCAwLCAxLCAwLCAwXSwKICAgIFswLCAwLCAxLCAwLCAwLCAxLCAwLCAwLCAxLCAxXSwKICAgIFsxLCAxLCAxLCAxLCAwLCAxLCAwLCAxLCAwLCAxXSwKICAgIFsxLCAwLCAxLCAwLCAwLCAxLCAwLCAxLCAwLCAxXSwKICAgIFsxLCAwLCAxLCAxLCAxLCAxLCAwLCAxLCAwLCAxXSwKICAgIFswLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAwLCAxXSwKICAgIFswLCAxLCAxLCAwLCAxLCAwLCAxLCAxLCAxLCAxXSwKICAgIFswLCAwLCAxLCAwLCAxLCAwLCAxLCAwLCAxLCAxXSwKICAgIFsxLCAxLCAxLCAwLCAxLCAwLCAxLCAwLCAxLCAxXQpdCgojIOihqDIuMuOBq+iomOi8ieOBleOCjOOBn+ato+OBl+OBhOe1kOaenApjb3JyZWN0ID0gWzEsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDBdCgoKIyDjg6HjgqTjg7Plh6bnkIYKZGF0YSA9IFtbXSBmb3IgaSBpbiByYW5nZShTRVRTSVpFKV0KdGVhY2hlciA9IFswIGZvciBpIGluIHJhbmdlKFNFVFNJWkUpXQoKYmVzdHNjb3JlID0gMApiZXN0YW5zd2VyID0gWzAgZm9yIGkgaW4gcmFuZ2UoQ05PKV0KCiMg44OR44K/44O844OzQeODu0LjgpLoqK3lrprjgZnjgosKcGF0dGVybkEgPSBbMiwgMiwgMCwgMiwgMiwgMiwgMCwgMiwgMCwgMl0KcGF0dGVybkIgPSBbMiwgMiwgMCwgMiwgMiwgMiwgMiwgMiwgMCwgMl0KCiMg44OR44K/44O844OzQ+ODu0Tjga7lgJnoo5zjgpLkv53lrZjjgZnjgosKY2FuZGlkYXRlX3BhdHRlcm5zID0ge30KCiMg5Lmx5pWw44KS5Yid5pyf5YyW44GZ44KLCnJhbmRvbS5zZWVkKFNFRUQpCgojIOWtpue/kuODh+ODvOOCv+OCkuiqreOBv+i+vOOCgApyZWFkZGF0YShkYXRhLCB0ZWFjaGVyKQoKIyDjg5Hjgr/jg7zjg7NB44O7QuOBruWtpue/kuODh+ODvOOCv+OBq+WvvuOBmeOCi+OCueOCs+OCogpzY29yZUEgPSBjYWxjc2NvcmUoZGF0YSwgdGVhY2hlciwgcGF0dGVybkEpCnNjb3JlQiA9IGNhbGNzY29yZShkYXRhLCB0ZWFjaGVyLCBwYXR0ZXJuQikKCnByaW50KCLjg5Hjgr/jg7zjg7NB44Gu44K544Kz44KiID0iLCBzY29yZUEpCnByaW50KCLjg5Hjgr/jg7zjg7NC44Gu44K544Kz44KiID0iLCBzY29yZUIpCgojIOino+WAmeijnOOCkueUn+aIkOOBl+OBpuipleS+oeOBmeOCiwpmb3IgaSBpbiByYW5nZShHRU5NQVgpOgogICAgYW5zd2VyID0gW3JhbmRvbS5yYW5kaW50KDAsIDIpIGZvciBqIGluIHJhbmdlKENOTyldCgogICAgc2NvcmUgPSBjYWxjc2NvcmUoZGF0YSwgdGVhY2hlciwgYW5zd2VyKQoKICAgICMg5YWo5L2T44Gu5pyA6Imv6Kej44KS5pu05paw44GZ44KLCiAgICBpZiBzY29yZSA+IGJlc3RzY29yZToKICAgICAgICBiZXN0c2NvcmUgPSBzY29yZQogICAgICAgIGJlc3RhbnN3ZXIgPSBhbnN3ZXIuY29weSgpCgogICAgIyDjgrnjgrPjgqI4NOeCueODuzEwMOeCueS7peWkluOBruWAmeijnOOCkuiomOmMsuOBmeOCiwogICAgaWYgc2NvcmUgIT0gODQgYW5kIHNjb3JlICE9IDEwMDoKICAgICAgICBwYXR0ZXJuID0gdHVwbGUoYW5zd2VyKQoKICAgICAgICAjIOWQjOOBmOODkeOCv+ODvOODs+OCkumHjeikh+OBl+OBpueZu+mMsuOBl+OBquOBhAogICAgICAgIGlmIHBhdHRlcm4gbm90IGluIGNhbmRpZGF0ZV9wYXR0ZXJuczoKICAgICAgICAgICAgY2FuZGlkYXRlX3BhdHRlcm5zW3BhdHRlcm5dID0gc2NvcmUKCiMg44K544Kz44Ki44Gu6auY44GE6aCG44Gr5Lim44G544KLCnNvcnRlZF9wYXR0ZXJucyA9IHNvcnRlZCgKICAgIGNhbmRpZGF0ZV9wYXR0ZXJucy5pdGVtcygpLAogICAga2V5PWxhbWJkYSBpdGVtOiBpdGVtWzFdLAogICAgcmV2ZXJzZT1UcnVlCikKCiMgQeODu0LjgajlkIzjgZjjg5Hjgr/jg7zjg7Pjga/lgJnoo5zjgYvjgonpmaTjgY8KcGF0dGVybkFfdHVwbGUgPSB0dXBsZShwYXR0ZXJuQSkKcGF0dGVybkJfdHVwbGUgPSB0dXBsZShwYXR0ZXJuQikKCnNvcnRlZF9wYXR0ZXJucyA9IFsKICAgIGl0ZW0gZm9yIGl0ZW0gaW4gc29ydGVkX3BhdHRlcm5zCiAgICBpZiBpdGVtWzBdICE9IHBhdHRlcm5BX3R1cGxlCiAgICBhbmQgaXRlbVswXSAhPSBwYXR0ZXJuQl90dXBsZQpdCgojIEPjg7tE44KS6YG444G2CnBhdHRlcm5zID0gewogICAgIkEiOiBwYXR0ZXJuQSwKICAgICJCIjogcGF0dGVybkIKfQoKaWYgbGVuKHNvcnRlZF9wYXR0ZXJucykgPj0gMToKICAgIHBhdHRlcm5zWyJDIl0gPSBsaXN0KHNvcnRlZF9wYXR0ZXJuc1swXVswXSkKCmlmIGxlbihzb3J0ZWRfcGF0dGVybnMpID49IDI6CiAgICBwYXR0ZXJuc1siRCJdID0gbGlzdChzb3J0ZWRfcGF0dGVybnNbMV1bMF0pCgojIEHjg7tC44O7Q+ODu0Tjga7kuojmuKzntZDmnpzjgpLooajnpLrjgZnjgosKcHJpbnQoIlxu6KGoMi4yIOaknOafu+ODh+ODvOOCv+OBruS6iOa4rOe1kOaenCIpCnByaW50KCLnlarlj7cgIOato+inoyAgQeS6iOa4rCAgQuS6iOa4rCAgQ+S6iOa4rCAgROS6iOa4rCIpCgpwcmVkaWN0aW9ucyA9IHt9Cgpmb3IgbmFtZSwgcGF0dGVybiBpbiBwYXR0ZXJucy5pdGVtcygpOgogICAgcHJlZGljdGlvbnNbbmFtZV0gPSBwcmVkaWN0KHBhdHRlcm4sIHRlc3RkYXRhKQoKZm9yIGkgaW4gcmFuZ2UobGVuKHRlc3RkYXRhKSk6CiAgICB2YWx1ZXMgPSBbXQoKICAgIGZvciBuYW1lIGluIFsiQSIsICJCIiwgIkMiLCAiRCJdOgogICAgICAgIGlmIG5hbWUgaW4gcHJlZGljdGlvbnM6CiAgICAgICAgICAgIHZhbHVlcy5hcHBlbmQoc3RyKHByZWRpY3Rpb25zW25hbWVdW2ldKSkKICAgICAgICBlbHNlOgogICAgICAgICAgICB2YWx1ZXMuYXBwZW5kKCItIikKCiAgICBwcmludCgKICAgICAgICBpICsgMSwgY29ycmVjdFtpXSwKICAgICAgICB2YWx1ZXNbMF0sIHZhbHVlc1sxXSwgdmFsdWVzWzJdLCB2YWx1ZXNbM10KICAgICkKCiMg5ZCE44OR44K/44O844Oz44Gu5q2j6Kej5pWw44KS6KGo56S644GZ44KLCnByaW50KCJcbuaknOafu+ODh+ODvOOCvzEw5L6L44Gu5q2j6Kej5pWwIikKCmZvciBuYW1lIGluIFsiQSIsICJCIiwgIkMiLCAiRCJdOgogICAgaWYgbmFtZSBpbiBwcmVkaWN0aW9uczoKICAgICAgICBjb3VudCA9IDAKCiAgICAgICAgZm9yIGkgaW4gcmFuZ2UobGVuKGNvcnJlY3QpKToKICAgICAgICAgICAgaWYgcHJlZGljdGlvbnNbbmFtZV1baV0gPT0gY29ycmVjdFtpXToKICAgICAgICAgICAgICAgIGNvdW50ICs9IDEKCiAgICAgICAgcHJpbnQobmFtZSwgIjoiLCBjb3VudCwgIi8gMTAiKQoKIyDmjqLntKLlhajkvZPjga7mnIDoia/op6PjgpLooajnpLrjgZnjgosKcHJpbnQoIlxu5o6i57Si5YWo5L2T44Gu5pyA6Imv6KejIikKcHJpbnQoYmVzdGFuc3dlciwgIjpzY29yZT0iLCBiZXN0c2NvcmUpCiMgeW91ciBjb2RlIGdvZXMgaGVyZQ==