回溯法代码程序

def backtrack(t):
    global bestV,curW,curV,x,bestx
    if t>n:
        if bestV<curV:
            bestV=curV
            bestx=x[:]
    else:
        if curW+w[t]<=c:
            x[t]=1
            curW+=w[t]
            curV+=v[t]
            backtrack(t+1)
            curW-=w[t]
            curV-=v[t]
        x[t]=0
        backtrack(t+1)
if __name__=="__main__":
    bestV=0
    curW=0
    curV=0
    bestx=None

    n=5
    c=10
    w=[2,2,6,5,4]
    v=[6,3,5,4,6]
    x=[0 for i in range(n)]
    backtrack(0)
    print(bestV)
    print(bestx)

#限界条件为cp + rp > bestp
def backtrack(t):
    global bestp,cw,cp,x,bestx,rp
    if t>=n:
        if bestp < cp:
            bestp = cp
            bestx = x[:]
    else:
        if cw + w[t] <= W:
            x[t] = 1
            cw += w[t]
            cp += v[t]
            rp -= v[t]
            backtrack(t+1)
            cw -= w[t]
            cp -= v[t]
            rp += v[t]
        if cp + rp > bestp:
            x[t]=0
            backtrack(t+1)
if __name__=="__main__":
    bestp=0#当前最优值
    cw=0#当前装入背包的重量
    cp=0#当前装入背包的价值
    bestx=None#记录当前最优解
    n=5#物品个数
    W=10#背包容量
    w=[2,2,6,5,4]#物品重量
    v=[6,3,5,4,6]#物品价值
    x=[0 for i in range(n)]#当前可行解
    rp = 0#剩余物品的价值
    for i in range(len(v)):
        rp += v[i]
    backtrack(0)
    print("最大价值为:",bestp)
    print("最优解为:",bestx)

#限界条件为 cp + brp > bestp,留用了数组下标为0 的单元
def bound(i):
    global c,cw,goods,cp,n
    Wleft = c - cw
    b=cp
    while(i<=n and goods[i][1]<=Wleft):
        Wleft -= goods[i][1]
        b +=goods[i][2]
        i +=1
    if(i<=n):
        b += goods[i][2]/goods[i][1]*Wleft;
    return b
  
def backtrack(t):
    global bestp,c,cw,cp,x,bestx,n,goods
    if t>=n:
        if bestp < cp:
            bestp = cp
            bestx = x[:]
    else:
        if cw + goods[t][1] <= c:
            x[goods[t][0]] = 1
            cw += goods[t][1]
            cp += goods[t][2]
            backtrack(t+1)
            cw -= goods[t][1]
            cp -= goods[t][2]
        if bound(t) > bestp:
            x[goods[t][0]]=0
            backtrack(t+1)
if __name__=="__main__":
    bestp=0#当前最大价值
    cw=0#当前重量
    cp=0#当前价值
    bestx=None#最优解
    n=5#问题规模
    c=10#背包容量
    goods = [(0,2,6),(1,2,3),(2,6,5),(3,5,4),(4,4,6)]#物品集合,记录物品的编号、重量、价值
    x=[0 for i in range(n)]#当前解
    goods.sort(key = lambda x:x[2]/x[1],reverse=True)  #按照物品的单位重量的价值由大到小排序
    backtrack(0)
    print("最大价值为:",bestp)
    print("最优解为:",bestx)


旅行商问题
def backtrack(t):
    global n,a,x,bestc,NoEdge,cc,bestx
    g_n = n-1
    if (t == g_n):#g_n是问题的规模
        if (a[x[g_n-1]][x[g_n]] != NoEdge and  a[x[g_n]][1] != NoEdge and (cc + a[x[g_n-1]][x[g_n]] + a[x[g_n]][1] < bestc or bestc == NoEdge)):
            bestx = x[:]
            bestc = cc + a[x[g_n-1]][x[g_n]] + a[x[g_n]][1]
    else:
        for j in range(t,n):
             if (a[x[t-1]][x[j]] != NoEdge and (cc + a[x[t-1]][x[t]] < bestc or bestc == NoEdge)):
                x[t], x[j] = x[j], x[t]
                cc += a[x[t-1]][x[t]]
                backtrack(t+1)
                cc -= a[x[t-1]][x[t]]
                x[t], x[j] = x[j], x[t]
if __name__ == "__main__":
    import sys
    NoEdge = sys.maxsize
    a = [[0,0,0,0,0,0],[0,NoEdge,10,NoEdge,4,12],[0,10,NoEdge,15,8,5],[0,NoEdge,15,NoEdge,7,30],[0,4,8,7,NoEdge,6],[0,12,5,30,6,NoEdge]]
    n = len(a)
    x = [i for i in range(n)]
    bestx =None
    bestc = NoEdge
    cc = 0
    backtrack(2)#第一个城市固定,所以从第二层开始搜索
    print("最短路径长度为:", bestc)
    print("最短路径为:", bestx)

图的m可着色问题
#牺牲下标为0的单元
def Ok(k):
    for j in range(1,k):
        if ((a[k][j]==1) and (x[j]==x[k])):
            return False
    return True
def Backtrack(t):
    global colors,x,sum1,n,m,a
    if (t>n):
        sum1 += 1
        colors.append(x[:])
    else:
        for  i in range(1,m+1):
            x[t]=i
            if (Ok(t)):
               # print(i)
                Backtrack(t+1)
if __name__ =="__main__":
    a = [[0,0,0,0,0,0],[0,0,1,1,0,0],[0,1,0,1,1,1],[0,1,1,0,1,0],[0,0,1,1,0,1],[0,0,1,0,1,0]]
    n = len(a) - 1
    m = 3
    sum1 = 0
    colors = []
    x = [0 for i in range(n + 1)]
    Backtrack(1)
    for i in range(len(colors)):
        print(colors[i])
    print("共有:"+str(sum1)+"种着色方案")


#n皇后问题,满m叉树
def Ok(k):
    global x,place_answers
    for j in range(1,k):
        if (x[k] == x[j] or (abs(k-j) ==abs(x[k]-x[j]))):
            return False
    return True
def backtrack(t):
    global x,n,sum1
    if (t>n):
        sum1 += 1
        place_answers.append(x[:])
    else:
        for  i in range(1,n+1):
            x[t]=i
            if (Ok(t)):
                backtrack(t+1)
if __name__ =="__main__":
    n = 4
    place_answers = []
    sum1 = 0
    x = [0 for i in range(n+1)]
    backtrack(1)
    for i in range(len(place_answers)):
        print(place_answers [i])
    print("共有:"+str(sum1)+"种放置方案")

#n皇后问题,满m叉树
def Ok(k):
    global x,place_answers
    for j in range(1,k):
        if (abs(k-j) ==abs(x[k]-x[j])):
            return False
    return True
def backtrack(t):
    global x,n,sum1
    if (t>n):
        sum1 += 1
        place_answers.append(x[:])
    else:
        for  i in range(t,n+1):
            x[t],x[i]= x[i],x[t]
            if (Ok(t)):
                backtrack(t+1)
            x[t],x[i]= x[i],x[t]
if __name__ =="__main__":
    n = 4
    place_answers = []
    sum1 = 0
    x = [i for i in range(n+1)]
    backtrack(1)
    for i in range(len(place_answers)):
        print(place_answers [i])
    print("共有:"+str(sum1)+"种放置方案")
 

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值