回溯算法:
简介:用回溯方法设计的算法就是回溯算法,用回溯方法解决问题首先应该明确问题的解空间。
解空间
对于一个由若干个小的决策组成的复杂的问题,解决这个问题的所有可能的决策序列构成了该问题的解空间,解空间中满足约束条件的的决策序列称为可行解,使目标达到最优的可行解称为最优解。
示例:
对于如下的TSP问题画出其解空间树:
确定了解空间树,我们才能进行下一步的构思
回溯方法
我们的总任务是在解空间树中搜索出解向量,如上述的TSP问题的最优解向量就是{0,2,1,3}。所以回溯方法每一步的核心是在确定了解向量X的前t个分量X[0 … (t-1)]的值以后,如何确定分量X[t]的值,为了方便描述,引入下列两个函数。
-
T(X[0 … (t-1)])。表示在确定X[0 … (t-1)]以后,X[t]所有可能取值的集合。
-
B(X[0 … t])。表示X[0 … t]是否违背约束条件,其中,B(X[0 … t]) = true表示X[0 … t]没有违背约束条件,B(X[0 … t]) = false表示X[0 … t]违背了约束条件
回溯方法主要解决的问题可以分成两大类:- m-叉树的搜素:迷宫问题、子集和问题
- 排列数的搜索:皇后问题、旅行商问题
m-叉树的搜索
import java.util.Arrays;
public class M_treeSearch {
public static void main(String[] args) {
int m=3;
// m_叉树
int n=4;
// 几个步骤
int[] X=new int[n];
// 求解向量X的过程
A a= new A(m,n,X);
a.Mset(0);
}
}
class A {
int m;
int n;
int[] X;
public A(int m, int n, int[] x) {
this.m = m;
this.n = n;
X = x;
}
public void Mset(int t){
if (t>=n)
System.out.println(Arrays.toString(X));
else{
for (X[t]=0;X[t]<m;X[t]++){
Mset(t+1);
}
}
}
}
排列树的搜索
import java.util.Arrays;
public class Prem {
public static void main(String[] args) {
int[] X={1,2,3,4};
sorttree a=new sorttree(X);
a.sort(0);
}
}
class sorttree{
int[] X;
int len;
public sorttree(int[] X) {
this.X=X;
this.len=X.length;
}
public void sort( int t ){
if (t>=len)
System.out.println(Arrays.toString(X));
else{
for (int i=t;i<=len-1;i++)
{
swap(t,i);
sort(t+1);
swap(t,i);
}
}
}
public int[] swap(int i, int j){
int t =X[i];
X[i]=X[j];
X[j]=t;
return X;
}
}