Python实现AO*算法进行与或图搜索

只适用与结构比较简单的图搜索

以下图为例:

 其中n3、n5、n7为已解决节点 

h_list = [0, 3, 4, 5, 6, 3, 5, 9]  # 初始化各节点h值


class node:
    def __init__(self, in_num):
        self.num = in_num
        self.bro = None
        self.son = []
        self.goodson = None
        self.father = []
        self.state = 0  # 不可解
        self.h = h_list[self.num]
        self.son_have_bro = 0   #是否有与弧
        pass

    def appendSon(self, node):
        self.son.append(node)
        node.father.append(self)

    def appendBro(self, node):
        self.bro = node
        node.bro = self
        pass


def build(n0):
    # <editor-fold desc="树的构建">
    n0.appendSon(n1)
    n0.appendSon(n2)
    n1.appendSon(n3)
    n1.appendSon(n4)
    n2.appendSon(n5)
    n2.appendSon(n6)
    n4.appendSon(n6)
    n6.appendSon(n7)

    n3.appendBro(n4)
    n5.appendBro(n6)
    # </editor-fold>

    n3.state = 1
    n5.state = 1
    n7.state = 1

    n1.son_have_bro = 1
    n2.son_have_bro = 1
    return


def get_h(node):
    all_h = []
    for son in node.son:
        if node.son_have_bro == 0:
            all_h.append(son.h + 1)
        else:
            all_h.append(son.h + son.bro.h + 2)
    min = all_h[0]
    index = 0
    for item in all_h:
        if item < min:
            min = item
            index = all_h.index(min)
    node.goodson = node.son[index]
    node.h = min
    return


def AOstar(n0):
    G = []
    G.append(n0)
    while n0.state != 1:
        node1 = G[0]
        G.remove(node1)
        node_son = node1.son.copy()
        for item in node_son:
            if item in node1.father or item.state == 1:  # 选择加入G的节点
                node_son.remove(item)
        G.extend(node_son)

        S = [node1]
        while S != []:
            current = None
            for item in S:
                can = 1
                for cur_son in item.son:
                    if cur_son in S:
                        can = 0
                if can:
                    current = item
                    break
            S.remove(current)
            a = current.h  # 保留副本,观察是否改变
            if current.state != 1:
                get_h(current)
            if current.goodson.state == 1 and (current.son_have_bro == 0 or current.goodson.bro.state == 1):
                current.state = 1
            if current.h != a or current.state == 1:
                fat = current
                for index, item in enumerate(fat.father):  # 回传
                    S.append(item)

    return


n0 = node(0)

# <editor-fold desc="新建七个节点">
n1 = node(1)
n2 = node(2)
n3 = node(3)
n4 = node(4)
n5 = node(5)
n6 = node(6)
n7 = node(7)
# </editor-fold>

build(n0)
AOstar(n0)  # 获取n的h值与代价最小的路径
node = n0
while node != None:
    if node.goodson != None:
        print("n%d" % node.num, end="->")
        node = node.goodson
    elif node.bro != None and node.bro.goodson != None:
        print("n%d" % node.bro.num, end="->")
        node = node.bro.goodson
    else:
        print("n%d" % node.num)
        break

运行结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值