Python代码
: 猜数字游戏8步以内的完全求解决策树生成程序
001
#coding=utf-8
002
003
#猜数字游戏8步以内的求解决策树生成程序
004
# 解题思路与一步步的解题程序参见:
005
# http://www.fayaa.com/code/view/116/
006
#
007
008
#使用方法:
009
# 1. 保存代码为guessall.py
010
# 2. 执行python guessall.py > result.txt
011
# 3. 打开result.txt看结果
012
013
#为了可读性和简单性使用了列表推导,其他方法参见:
014
# http://www.fayaa.com/code/view/114/
015
# http://www.fayaa.com/code/view/118/
016
def
init_set
():
017
r10
=
range
(
10
)
018
return
[(
i
,
j
,
k
,
l
)
019
for
i
in
r10
for
j
in
r10
for
k
in
r10
for
l
in
r10
020
if
(
i
!=
j
and
i
!=
k
and
i
!=
l
and
j
!=
k
and
j
!=
l
and
k
!=
l
)
]
021
022
#对给定的两组数,计算xAyB
023
#不知道能不能更快些
024
def
get_match_ab
(
target
,
source
):
025
la
,
lb
=
0
,
0
026
for
(
i
,
t
)
in
enumerate
(
target
):
027
for
(
j
,
s
)
in
enumerate
(
source
):
028
if
s
==
t
:
029
if
i
==
j
:
030
la
+=
1
031
else
:
032
lb
+=
1
033
#break this loop since we already found match
034
break
035
return
(
la
,
lb
)
036
037
#by lancer
038
#思路很好,把原来的16次比较变成了8次
039
#经过timeit验证确实速度有所提高
040
def
get_match_ab2
(
target
,
source
):
041
table
=
[
-
1
]
*
10
042
la
,
lb
=
0
,
0
043
for
i
in
xrange
(
len
(
source
)):
044
table
[
source
[
i
]]
=
i
045
for
i
in
xrange
(
len
(
target
)):
046
if
table
[
target
[
i
]]
==
i
:
047
la
+=
1
048
elif
table
[
target
[
i
]]
!=
-
1
:
049
lb
+=
1
050
return
(
la
,
lb
)
051
052
#nums: the number_set list to be checked
053
#guess: last guess
054
#a, b: the number of aAbB
055
#@return: the rest number_sets which matche last guess
056
def
check_and_remove
(
nums
,
guess
,
a
,
b
):
057
rest_nums
=
[]
058
for
num_set
in
nums
:
059
if
(
a
,
b
)
==
get_match_ab
(
num_set
,
guess
):
060
rest_nums
.
append
(
num_set
)
061
return
rest_nums
062
063
#计算在nums中选择target以后,所有ab分支里面的剩余组合个数
064
def
calc_ab_counts
(
target
,
nums
):
065
#a * 10 + b is used to indicate an "a & b" combination
066
ab_map
=
{}
067
#init ab_map
068
abs
=
(
0
,
1
,
2
,
3
,
4
,
10
,
11
,
12
,
13
,
20
,
21
,
22
,
30
,
31
,
40
)
069
for
ab
in
abs
:
070
ab_map
[
ab
]
=
0
071
#let's do the calculation
072
for
num_set
in
nums
:
073
(
a
,
b
)
=
get_match_ab
(
num_set
,
target
)
074
ab_map
[
a
*
10
+
b
]
+=
1
075
return
[
ab_map
[
ab
]
for
ab
in
abs
]
076
077
#计算一个选择相对于选择集的“标准差”
078
def
calc_standard_deviation
(
target
,
nums
):
079
ab_counts
=
calc_ab_counts
(
target
,
nums
)
080
total
=
sum
(
ab_counts
)
081
avg
=
float
(
total
)
/
len
(
ab_counts
)
082
sd
=
sum
([(
abc
-
avg
)
**
2
for
abc
in
ab_counts
])
083
return
sd
084
085
#根据现有集合寻找下一个集合
086
#采用“最小标准差”作为衡量标准
087
def
next_guess
(
nums
):
088
min_sd
=
0
089
min_set
=
()
090
touched
=
False
091
for
num_set
in
nums
:
092
sd
=
calc_standard_deviation
(
num_set
,
nums
)
093
if
not
touched
or
min_sd
>
sd
:
094
touched
=
True
095
min_set
=
num_set
096
min_sd
=
sd
097
return
min_set
098
099
#根据现有集合寻找下一个集合
100
#随机选取,会有4-5个超过八次
101
def
next_guess2
(
nums
):
102
return
nums
[
0
]
103
104
#折衷的方法:小于500用最小标准差
105
def
next_guess3
(
nums
):
106
if
len
(
nums
)
>
500
:
107
return
next_guess2
(
nums
)
108
else
:
109
return
next_guess
(
nums
)
110
111
#计算熵
112
import
math
113
def
calc_entropy
(
target
,
nums
):
114
ab_counts
=
calc_ab_counts
(
target
,
nums
)
115
total
=
sum
(
ab_counts
)
116
hs
=
[]
117
for
abc
in
ab_counts
:
118
h
=
0
119
if
abc
:
120
p
=
float
(
abc
)
/
total
121
h
=
p
*
math
.
log
(
p
,
2
)
122
hs
.
append
(
h
)
123
return
sum
(
hs
)
124
125
#使用信息量作为衡量标准
126
def
next_guess4
(
nums
):
127
min_sd
=
0
128
min_set
=
()
129
touched
=
False
130
for
num_set
in
nums
:
131
sd
=
calc_entropy
(
num_set
,
nums
)
132
if
not
touched
or
min_sd
>
sd
:
133
touched
=
True
134
min_set
=
num_set
135
min_sd
=
sd
136
return
min_set
137
138
#决策树生成思路
139
#1. 生成所有的四位0-9数字组合,用0123做初始选择,空列表queue=[], result={}
140
# result: (当前选择, {21:(下一个选择, {})}, 13:abcd<最终结果值>, ...})
141
# queue: [(rest_nums, 对应当前猜测状态的result节点), ...]
142
分享到:
相关推荐
### Matlab中求解最小生成树的程序 #### 知识点概述 本篇文章将详细介绍如何在Matlab中实现最小生成树(Minimum Spanning Tree, MST)的计算过程,特别是通过使用避圈法(Kruskal算法、克鲁斯卡尔算法)。最小生成树...
【猜数字游戏的计算机求解】是一篇关于利用计算机算法解决猜数字游戏的文章,作者探讨了多种策略以减少平均猜测次数并优化启发式算法。文章主要涵盖了以下几个方面: 1. **引言**: - 猜数字游戏,也称为Bulls and...
### 数独求解程序游戏设计报告书 #### 一、数独游戏介绍 数独(Sudoku)是一种逻辑填数字游戏,玩家需按照一定的规则在9×9的网格内填入1至9的数字,使得每一行、每一列以及每一个3×3的小宫格内的数字都不重复。...
利用决策树求解回归问题,比较不同的depth下,决策树的效果
本文将详细讲解基于SAT的二进制数独游戏求解程序的设计原理与实现,结合华中科技大学计算机学院的程序设计综合课程,深入探讨这一技术在实际应用中的价值。 首先,我们要理解什么是SAT问题。SAT(Boolean ...
在求解最小生成树问题时,它可能会生成一组可能的树结构,通过选择、交叉和变异等操作迭代地改进种群,直至找到近似最优解。这种方法适用于处理大规模、复杂的问题,但可能不如经典的贪心算法那样提供确定性的结果。...
很好用的excel插件,用于决策分析,求解最优解
利用普里姆算法求解最小生成树 利用普里姆算法求解最小生成树 利用普里姆算法求解最小生成树
最小生成树是图论中的一个重要概念,用于寻找加权无向图中连接所有顶点的边的集合,使得这些边的总权重最小。在实际应用中,如设计网络、优化交通路线等,最小生成树算法有着广泛的应用。本文将详细讨论两种经典算法...
一个连通图的生成树是一个极小连通子图,它含有图中全部顶点,但只有足以构成一棵树的n-1条边。 当用联通网来表示n个城市以及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的...
在本MFC程序中,它采用普林姆算法来求解最小生成树,这是一种高效的方法。 普林姆算法(Prim's Algorithm)是由捷克数学家Vojtěch Jarník于1930年提出,后由美国计算机科学家罗伯特·普林姆改进并推广。该算法...
报告题目:基于SAT的数独游戏求解程序 在计算机科学与技术领域,数独游戏是一种广受欢迎的逻辑推理游戏,而将数独求解与SAT(Boolean Satisfiability Problem,布尔可满足性问题)相结合则是一种巧妙的算法设计。本...
提出了一种基于混合决策树的调度知识获取算法...使用决策树评价混合方法中染色体编码的适应度,在得到不同调度目标下的最优特征子集和最优决策树参数后,生成调度知识。仿真实验结果表明,该算法在性能上优于其他算法。
摘要:本文讨论了猜数字游戏的计算机求解的若干种策略,研究了如何减少平均猜测次数,优化启发式算法的运行效率,并以 C++高效的实现了文中提及的算法。关键词:筛选法
WinQSB是一款强大的决策分析软件,它提供了多种工具来帮助用户解决复杂的决策问题。在案例五中,我们看到WinQSB被应用于先天性心脏病治疗方案的决策分析,这是一个典型的医疗决策问题,涉及到成本效益和患者生存率的...
本次课程设计的主题是“图的遍历和生成树求解实现”,这涵盖了两个核心概念:图的遍历算法(深度优先搜索DFS和广度优先搜索BFS)以及最小生成树(如Prim's算法或Kruskal's算法)。我们将深入探讨这两个知识点,并...
在IT领域,图的遍历和最小生成...在实际应用中,图的遍历和最小生成树求解不仅局限于理论学习,还可以用于解决实际问题,例如网络路由、社交网络分析、资源分配等。因此,熟练掌握这些技能对于IT专业人士来说至关重要。
数独求解算法程序是一种基于计算机的智能工具,用于解决数独游戏的难题。数独是一种逻辑推理游戏,玩家需要在9x9的格子中填入数字,使得每一行、每一列以及每一个3x3的小宫格内,数字1到9都出现且只出现一次。这种...
最小生成树问题是一个经典的图论问题,主要应用于网络设计、数据通信等领域,旨在找到一个加权无向图中连接所有顶点的边的集合,使得这些边的总权重尽可能小。这个问题由Kruskal和Prim两位数学家分别提出了两种解决...