python:基于二叉树速解凑:基于二叉树速解凑24点问题点问题
凑24点问题,是基于加减乘除四则运算,将四个数进行处理凑出24点的游戏。例如经典24点例题(4,4,7,7)如何凑出24点
呢?本文运用二叉树的思想,运用下面的代码可以秒出答案,只需使用itrertools排列组合包即可。
这里贴一个原理链接:遗传规划方法概述
本质上是可以直接调用遗传规划包的,但还是依据原理实现了一遍,感兴趣的可以复制下面的代码,玩一下24点噢~
# 暨南大学 王杰安
import itertools
def add(a, b):
return a+b
def sub(a, b):
return a-b
def pro(a, b):
return a*b
def div(a, b):
return a/b
def wcd_find_tree(tree):
root = []; root_leaf = [] deep = max(map(lambda x: x[0], tree))
trees = dict.fromkeys(range(1,deep+1), [])
for leaf in tree:
trees[leaf[0]] = trees[leaf[0]]+[leaf] for level in range(1,deep+1):
for i in range(int(len(trees[deep+1-level])/2)):
_1 = trees[deep+1-level][i*2] _2 = trees[deep+1-level][i*2+1] father_root= (_1[0]-1, int((_1[1]+_2[1]+1)/4))
if father_root in trees[deep-level]:
root.append(str(father_root))
root_leaf.append([str(father_root), '{}({},{})'.format(father_root,_1,_2)])
root_leaf.sort()
for i in range(1,len(root_leaf)):
target = root_leaf[0][1] tool_key = root_leaf[i][0] tool = root_leaf[i][1] root_leaf[0][1] = target.replace(tool_key,tool)
leaf = [str(x) for x in tree if str(x) not in root] root.sort(); leaf.sort()
return root, leaf, root_leaf[0][1]
def wja_solve(root, leaf, function, operation, num):
num_combine = list(set(list(itertools.permutations(num, 4))))
ope_combine = list(itertools.product(operation, repeat=3))
for nums in num_combine:
for opes in ope_combine:
equation = function
foot_function = dict(zip(root, list(opes)))
leaf_function = dict(zip(leaf, list(nums)))
replace_rule = dict(foot_function, **leaf_function)
for key in replace_rule.keys():
equation = equation.replace(key, str(replace_rule[key]))
try:
if eval(equation)==24:
print(equation)
except:
continue
if __name__ == '__main__':
operation = ['add', 'sub', 'pro', 'div']; num = [4,4,7,7] # 树构造,这一块懒得写代码了,这一块由于24点的特殊性,所以跳过树
构造的过程
# 理论上这里还可以写一个树构造的代码,有兴趣的自己写一写
tree_1 = [(1,1),(2,1),(2,2),(3,1),(3,2),(3,3),(3,4)] tree_2 = [(1,1),(2,1),(2,2),(3,1),(3,2),(4,1),(4,2)] tree_3 = [(1,1),(2,1),(2,2),(3,1),
(3,2),(4,3),(4,4)] tree_4 = [(1,1),(2,1),(2,2),(3,3),(3,4),(4,5),(4,6)] tree_5 = [(1,1),(2,1),(2,2),(3,3),(3,4),(4,7),(4,8)] for tree in
[tree_1, tree_2, tree_3, tree_4, tree_5]:
root, leaf, root_leaf = wcd_find_tree(tree)
wja_solve(root, leaf, root_leaf, operation, num)
秒出答案
pro(sub(4,div(4,7)),7)
pro(7,sub(4,div(4,7)))
评论0
最新资源