defenforce_node_consistency(self):"""
Update `self.domains` such that each variable is node-consistent.
(Remove any values that are inconsistent with a variable's unary
constraints; in this case, the length of the word.)
"""forwordinself.crossword.words:l=len(word)forvarinself.crossword.variables:ifvar.length!=l:self.domains[var].remove(word)
这里算是遍历一遍 word 和 var,通过长度作为判断依据,把长度不匹配的 word 从 var 的 domain 中移除
defrevise(self,x,y):"""
Make variable `x` arc consistent with variable `y`.
To do so, remove values from `self.domains[x]` for which there is no
possible corresponding value for `y` in `self.domains[y]`.
Return True if a revision was made to the domain of `x`; return
False if no revision was made.
"""overlap=self.crossword.overlaps[x,y]#获得重叠部分ifoverlapisNone:#无重叠时returnFalseelse:i,j=overlap#赋值edit=False#初始化edit,用于判断是否修改并在最后返回to_remove=set()#新建一个set,用于存储记录将要移除的元素,用于最后一块移除forx_wordinself.domains[x]:#遍历xfind=Falsefory_wordinself.domains[y]:ifx_word[i]==y_word[j]:#如果x 可以满足某个 y,则不用被删find=TrueiffindisFalse:#x 里这个 word 不满足弧一致to_remove.add(x_word)edit=Trueforwordinto_remove:#统一进行删除self.domains[x].remove(word)returnedit
defac3(self,arcs=None):"""
Update `self.domains` such that each variable is arc consistent.
If `arcs` is None, begin with initial list of all arcs in the problem.
Otherwise, use `arcs` as the initial list of arcs to make consistent.
Return True if arc consistency is enforced and no domains are empty;
return False if one or more domains end up empty.
"""ifarcsisNone:#没有输入arcs时,检查全部的arcs,需要注意不要重复,不要找没有关系的queue=[(x,y)forxinself.domainsforyinself.domainsifx!=yandself.crossword.overlaps[x,y]isnotNone]else:queue=list(arcs)#传入弧转换为 listwhilequeue:(x,y)=queue.pop(0)#从list中取出一个ifself.revise(x,y):#如果经过修改iflen(self.domains[x])==0:#看看 x 还有没有剩的,为后面遍历做准备returnFalseforzinself.crossword.neighbors(x)-{y}:#遍历“邻居”,把成对的添加到队列中queue.append((z,x))returnTrue
这里需要注意:
添加全部数对的时候需要检查不要重复、不要添加无关的两个节点作为边
传入 arcs 时,需要用 list 包成列表
这里可以通过调用 pop 方法,取出元素
需要在修改后检查 x 的 domain 是否为空,防止报错
assignment_complete
1
2
3
4
5
6
7
8
9
defassignment_complete(self,assignment):"""
Return True if `assignment` is complete (i.e., assigns a value to each
crossword variable); return False otherwise.
"""forvarinself.domains:#遍历所有的空ifvarnotinassignment:#看看空有没有填上returnFalsereturnTrue
defconsistent(self,assignment):"""
Return True if `assignment` is consistent (i.e., words fit in crossword
puzzle without conflicting characters); return False otherwise.
"""#检查单词是否重复used_words=set()forvarinassignment:word=assignment[var]ifwordinused_words:returnFalseelse:used_words.add(word)#检查长度是否正确iflen(word)!=var.length:returnFalse#检查相邻变量是否重复forvar1inassignment:forvar2inassignment:ifvar1!=var2:overlap=self.crossword.overlaps[var1,var2]ifoverlap!=None:i,j=overlapword1=assignment[var1]word2=assignment[var2]ifword1[i]!=word2[j]:returnFalsereturnTrue