📜  回溯和Branch-N-Bound技术之间的区别(1)

📅  最后修改于: 2023-12-03 15:23:01.970000             🧑  作者: Mango

回溯和Branch-N-Bound技术之间的区别

回溯(Backtracking)和Branch-N-Bound(分支定界)都是求解一些复杂问题的算法。虽然它们的实现方法很相似,但是它们的工作方式和目标有很大的不同。

回溯
工作方式

回溯是一种基于深度优先搜索的算法,它通过试探和回溯的方式遍历所有可能的解,直到找到一个满足条件的解为止。在回溯的过程中,我们维护一个状态树,在每一层节点上,我们会选择一种情况进行尝试,如果该情况无法满足条件,我们就会回溯到上一层节点,并尝试其他情况。通过这样的方式,我们可以遍历所有可能的情况,找到所有符合条件的解。

目标

回溯的目标是找到所有的解。它不像其他算法一样,只找到一个最优解,而是尝试找到所有的解,即使这些解不是最优的。

代码片段

下面是一个用回溯算法解决数独问题的代码片段(Python实现):

def solveSudoku(board):
    def backtrack(i=0, j=0):
        if j == 9:
            i += 1
            j = 0
        if i == 9:
            return True
        if board[i][j] != '.':
            return backtrack(i, j+1)
        for c in map(str, range(1, 10)):
            if valid(c, i, j):
                board[i][j] = c
                if backtrack(i, j+1):
                    return True
                board[i][j] = '.'
        return False
    
    def valid(c, i, j):
        for k in range(9):
            if board[i][k] == c or board[k][j] == c or board[3*(i//3)+k//3][3*(j//3)+k%3] == c:
                return False
        return True
    
    backtrack()
Branch-N-Bound
工作方式

Branch-N-Bound是一种启发式的算法,它通过解决最优化问题来找到最优解。与回溯算法不同,Branch-N-Bound使用一种限制条件来削减搜索空间。在搜索过程中,我们维护一个带有界限条件和优先级的状态队列,我们首先尝试搜索具有最高优先级的状态,然后再将该状态分解成子问题。我们对每个子问题应用相同的搜索策略,直到找到最优解或无法进一步分解。

目标

Branch-N-Bound的目标是找到最优解。它不像回溯算法那样找所有可能的解,而是限制搜索空间,仅搜索最可能的解。

代码片段

下面是一个用Branch-N-Bound算法解决0/1背包问题的代码片段(Python实现):

def knapsack(n, W, wt, val):
    items = sorted([(v/w, w, v) for w, v in zip(wt, val)], reverse=True)
    bound = i = value = 0
    heap = [(-bound, -n, i, 0)]  # (-bound, -cost, i, items_in knapsack)
    while heap:
        bound, cost, i, items = heapq.heappop(heap)
        if i == n or cost - items * items[i][0] > -bound: continue
        w, v = items[i][1:]
        heapq.heappush(heap, (bound, cost, i+1, items))
        if w + items <= W:
            value = max(value, v + cost)
            heapq.heappush(heap, (bound - v, cost - v, i+1, items+1))
    return value
总结

回溯和Branch-N-Bound算法虽然看起来很相似,但是它们的目标和工作方式有很大的不同。如果你需要找到所有可能的解,请使用回溯算法;如果你需要找到最优解,请使用Branch-N-Bound算法。