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)+"种放置方案")