Esempio n. 1
0
def backtrack(b, e):
    global flag, count

    count = 0

    print("searching backtrack ...")

    flag = False

    m = {"map": b, "parent": None}
    temp = __backtrack(m, e, 0)
    out_asr = []
    if flag:
        asr = [temp.get("map")]
        p = temp.get("parent")
        while p is not None:
            for i in tracked:
                if ef.compare(p, i.get("map")):
                    asr.append(i.get("map"))
                    p = i.get("parent")
                    break
        out_asr = asr.copy()
        print("answer: ")
        while len(asr):
            ef.printMap(asr.pop())
            print()
    else:
        print(flag)
    return out_asr
Esempio n. 2
0
def command(c):
    global b, e
    if c == '3':
        ef.mp_size = 3
        b, e = ef.init_map()
        print("map size changed to 3!")
    elif c == '4':
        ef.mp_size = 4
        b, e = ef.init_map()
        print("map size changed to 4!")
    elif c == 'h' or c == 'help':
        command_help()
    elif c == 'r' or c == 'refresh':
        b, e = ef.init_map()
        print("map refreshed!")
    elif c == "run":
        run()
    elif c == "v" or c == "visualize":
        app = QApplication(sys.argv)
        ex = MainPage()
        app.exec_()
    elif c == "dfs":
        run_func(d.dfs, d)
    elif c == "bfs":
        run_func(bf.bfs, bf)
    elif c == "astar":
        run_func(astar.a_star, astar)
    elif c == "backtrack":
        run_func(bt.backtrack, bt)
    elif c == "begin" or c == "b":
        print("begin:")
        ef.printMap(b)
    elif c == "end" or c == "e":
        print("end:")
        ef.printMap(e)
    else:
        print("没有此指令,请重新输入!")
Esempio n. 3
0
def dfs(b: list, e: list):
    """
    深度优先算法
    :param b: 初始情形
    :param e: 结束情形
    :return: 一个列表,包含从 b->e 的一个解法
    """
    global count, flag
    print("searching dfs ...")

    mp = {
        "map": b,
        "depth": 0,
        "parent": None
    }  # 最初的情形,深度用于判断是否跳出,parent用于最后超出所有路径
    end_pos = e  # 结束节点
    depth = ef.mp_size * ef.mp_size  # 探索的最大深度
    untracked = []  # 维护一个所有没探索过节点的栈
    tracked = []  # 维护一个所有已经探索过节点的栈

    untracked.append(mp)
    out_asr = []  # 输出的结果
    temp = None
    flag = False
    count = 0

    # 当还有没探索过的节点时
    while len(untracked):
        # 探索栈内最后的节点
        temp = untracked[-1].copy()
        tracked.append(untracked.pop())
        count += 1
        # 如果到达目标则跳出
        if ef.compare(temp.get("map"), end_pos):
            flag = True
            break
        # 若果超过探索深度的限制也跳出
        if temp.get("depth") > depth:
            continue

        maybe = []  # 在当前情况的基础下,所有可能出现的情形
        idx = 0
        while idx < 4:
            mmp = temp.get("map")
            # 如果可以朝哪个方向移动,将移动后的情形加入栈
            if ef.can_motion[idx](mmp):
                maybe.append({
                    "map": ef.motion[idx](mmp),
                    "depth": temp.get("depth") + 1,
                    "parent": mmp
                })
            idx += 1

        # 如果可能出现的情形并没有在未探索栈中且未在已探索栈中,则加入未探索栈
        for mb in maybe:
            if not in_list(mb, untracked):
                if not in_list(mb, tracked):
                    untracked.append(mb.copy())

    # 如果找到通路,则输出
    if flag:
        asr = [temp.get("map")]
        p = temp.get("parent")
        while p is not None:
            for i in tracked:
                if ef.compare(p, i.get("map")):
                    asr.append(i.get("map"))
                    p = i.get("parent")
                    break
        print("answer: ")
        out_asr = asr.copy()
        while len(asr):
            ef.printMap(asr.pop())
            print()
    else:
        print(flag)

    return out_asr
Esempio n. 4
0
def a_star(b, e):
    """
    a_star 算法的实现
    :param b: 开始的地图
    :param e: 目标地图
    :return: 存有解题过程的栈
    """
    global flag, depth, count
    print("searching A-Star ...")

    flag = False
    count = 0

    mp = {"map": b, "G": 0, "parent": None, "H": H(b, e)}
    end_pos = e

    untracked = [mp.copy()]  # 所有已经发现但还没有探索过的节点
    tracked = []  # 记录所有已经发现且已经探索过的节点
    temp = None  # 当前正在操作的节点

    while len(untracked):
        # 弹出总消耗(G+H)最小的当前地图
        temp = untracked[0].copy()
        # 加入已经探索的列表
        tracked.append(untracked.pop(0))
        count += 1

        # 如果到达目标则跳出
        if ef.compare(temp.get("map"), end_pos):
            flag = True
            break
        # 若果超过探索深度的限制也跳出
        if temp.get("G") > depth:
            continue

        maybe = []  # 在当前情况的基础下,所有可能出现的情形
        idx = 0
        while idx < 4:
            mmp = temp.get("map")
            # 如果可以朝哪个方向移动,将移动后的情形加入栈
            if ef.can_motion[idx](mmp):
                pos = ef.motion[idx](mmp)
                maybe.append({
                    "map": pos,
                    "G": temp.get("G") + 1,  # 实际的步数在已有的步数上加一
                    "parent": mmp,
                    "H": H(pos, e)
                })  # 预测到最后的步数
            idx += 1

        for mp1 in maybe:
            # 如果已经探索,则什么操作也不做
            if in_list(mp1, tracked):
                continue
            for idx, mp2 in enumerate(untracked):
                if ef.compare(mp2.get("map"), mp1.get("map")):
                    # 如果已经发现,判断G消耗之间的关系,如果小则替代掉,反之则什么也不做
                    if mp1.get("G") > mp2.get("G"):
                        untracked[idx] = mp2.copy()
                        break
            else:
                # 如果当前节点没有被发现,则加入发现列表
                untracked.append(mp1)

        untracked.sort(key=F)  # 按照总消耗进行升序

    out_asr = []
    # 如果找到通路,则输出
    if flag:
        asr = [temp.get("map")]
        # 通过父节点进行判断
        p = temp.get("parent")
        while p is not None:
            for i in tracked:
                if ef.compare(p, i.get("map")):
                    asr.append(i.get("map"))
                    p = i.get("parent")
                    break
        print("answer: ")
        out_asr = asr.copy()
        while len(asr):
            ef.printMap(asr.pop())
            print()
    else:
        print(flag)

    return out_asr
Esempio n. 5
0
def bfs(b, e):
    """
    宽度优先搜索实现
    :param b: 起始状态
    :param e: 结束状态
    :return: 一个包含路径的栈
    """
    global count, flag
    print("searching bfs ...")

    mp = {
        "map": b,
        "board": 0,
        "parent": None
    }  # 最初的情形,宽度用于判断是否跳出,parent用于最后输出所有路径
    end_pos = e  # 结束节点
    board = ef.mp_size * ef.mp_size  # 探索的最大深度
    untracked = []  # 维护一个所有没探索过节点的队列
    tracked = []  # 维护一个所有已经探索过节点的队列

    untracked.append(mp)
    out_asr = []  # 输出的结果
    temp = None
    flag = False
    count = 0

    # 当还有没探索过的节点时
    while len(untracked):
        # 探索队列内第一个节点
        temp = untracked[0].copy()
        tracked.append(untracked.pop(0))
        count += 1
        # 如果到达目标则跳出
        if ef.compare(temp.get("map"), end_pos):
            flag = True
            break
        # 若果超过探索宽度的限制也跳出
        if temp.get("board") > board:
            continue

        maybe = []  # 在当前情况的基础下,所有可能出现的情形
        idx = 0
        while idx < 4:
            mmp = temp.get("map")
            # 如果可以朝哪个方向移动,将移动后的情形加入队列
            if ef.can_motion[idx](mmp):
                maybe.append({
                    "map": ef.motion[idx](mmp),
                    "board": temp.get("board") + 1,
                    "parent": mmp
                })
            idx += 1

        # 如果可能出现的情形并没有在未探索队列中且未在已探索队列中,则加入未探索队列
        for mb in maybe:
            if not in_list(mb, untracked):
                if not in_list(mb, tracked):
                    untracked.append(mb.copy())

    # 如果找到通路,则输出
    if flag:
        asr = [temp.get("map")]
        p = temp.get("parent")
        while p is not None:
            for i in tracked:
                if ef.compare(p, i.get("map")):
                    asr.append(i.get("map"))
                    p = i.get("parent")
                    break
        print("answer: ")
        out_asr = asr.copy()
        while len(asr):
            ef.printMap(asr.pop())
            print()
    else:
        print(flag)

    return out_asr