前言

上一篇说了要给大家用递归来解,昨天的那个算法太诡异了,接下来我们来讲一下,完整代码见 https://github.com/zong4/AILearning。

代码逻辑

数据结构

我这次用的是节点,如下,基本就是把表格信息都存下来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Node:
def __init__(self, name, father=None, mother=None, trait=None):
self.name = name
self.father = father
self.mother = mother
self.trait = trait

...

# name,mother,father,trait
# Harry,Lily,James,
# James,,,1
# Lily,,,0
james = Node("James", None, None, True)
lily = Node("Lily", None, None, False)
harry = Node("Harry", james, lily, None)

递归算法

来看最重要的算法吧,主要是把人分成了三种先。

  1. 第一类人是一点信息都没有的,那就是人群中的随机一人。
  2. 第二类人是只有是否患病的信息,这与上面一类人的概率略有不同,具体可以看代码。
  3. 第三类人是有父母的,那就递归开算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
def get_genes_possibility(self):
ren = None
if self.father is None and self.mother is None:
if self.trait == None:
ren = PROBS["gene"]
else:
genes_0_possibility = PROBS["trait"][0][self.trait] * PROBS["gene"][0]
genes_1_posibility = PROBS["trait"][1][self.trait] * PROBS["gene"][1]
genes_2_possibility = PROBS["trait"][2][self.trait] * PROBS["gene"][2]

ren = {
0: genes_0_possibility / (genes_0_possibility + genes_1_posibility + genes_2_possibility),
1: genes_1_posibility / (genes_0_possibility + genes_1_posibility + genes_2_possibility),
2: genes_2_possibility / (genes_0_possibility + genes_1_posibility + genes_2_possibility),
}
else:
father_genes_possibility = self.father.get_genes_possibility()
mother_genes_possibility = self.mother.get_genes_possibility()

genes_2_possibility = father_genes_possibility[2] * (1 - PROBS["mutation"]) * mother_genes_possibility[2] * (1 - PROBS["mutation"])
genes_2_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[2] * (1 - PROBS["mutation"]) * 2
genes_2_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[1] * 0.5
genes_2_possibility += father_genes_possibility[0] * PROBS["mutation"] * mother_genes_possibility[2] * (1 - PROBS["mutation"]) * 2
genes_2_possibility += father_genes_possibility[0] * PROBS["mutation"] * mother_genes_possibility[1] * 0.5 * 2
genes_2_possibility += father_genes_possibility[0] * PROBS["mutation"] * mother_genes_possibility[0] * PROBS["mutation"]

genes_1_possibility = father_genes_possibility[2] * (1 - PROBS["mutation"]) * mother_genes_possibility[2] * PROBS["mutation"] * 2
genes_1_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[2] * 2
genes_1_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[1] * 0.5
genes_1_possibility += father_genes_possibility[0] * mother_genes_possibility[2] * 2
genes_1_possibility += father_genes_possibility[0] * mother_genes_possibility[1] * 0.5 * 2
genes_1_possibility += father_genes_possibility[0] * PROBS["mutation"] * mother_genes_possibility[0] * (1 - PROBS["mutation"]) * 2

genes_0_possibility = father_genes_possibility[2] * PROBS["mutation"] * mother_genes_possibility[2] * PROBS["mutation"]
genes_0_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[2] * PROBS["mutation"] * 2
genes_0_possibility += father_genes_possibility[1] * 0.5 * mother_genes_possibility[1] * 0.5
genes_0_possibility += father_genes_possibility[0] * (1 - PROBS["mutation"]) * mother_genes_possibility[2] * PROBS["mutation"] * 2
genes_0_possibility += father_genes_possibility[0] * (1 - PROBS["mutation"]) * mother_genes_possibility[1] * 0.5 * 2
genes_0_possibility += father_genes_possibility[0] * (1 - PROBS["mutation"]) * mother_genes_possibility[0] * (1 - PROBS["mutation"])

ren = {
0: genes_0_possibility / (genes_0_possibility + genes_1_possibility + genes_2_possibility),
1: genes_1_possibility / (genes_0_possibility + genes_1_possibility + genes_2_possibility),
2: genes_2_possibility / (genes_0_possibility + genes_1_possibility + genes_2_possibility),
}

print(str(self.name) + " genes possibility: " + str(ren))
return ren

是不是比昨天的算法看起来清晰多了。

但是我的这个概率好像还是有点问题,就中间那一大块,我感觉有突变的算起来头太大了,我觉得我得先去看看遗传学相关的资料才能算对。