回溯法解决n后问题
回溯法的核心:
1、确定问题的解空间
子集树问题:装载问题、符号三角形问题、0-1背包问题、最大团问题
排列树问题:批处理作业调度、n后问题、旅行售货员问题、圆排列问题、电路板排列问题
其他:图的m着色问题
2、找出适当的剪枝函数
约束函数
限界函数
3、以深度优先的方式搜索解空间
递归回溯
迭代回溯
n后问题代码:
1 public class Queens { 2 3 public static List<List<Queen>> queens(int n) { 4 return placeQueens(n, n); 5 6 } 7 8 public static List<List<Queen>> placeQueens(int n, int r) { 9 List<List<Queen>> queenList = new ArrayList(); 10 if (r == 0) 11 queenList.add(new ArrayList<Queen>()); 12 else { 13 // 利用 回溯法深度优先搜索 14 //queenList是不同的解向量 15 for (List<Queen> queens : placeQueens(n, r - 1)) { 16 for (int column = 1; column <= n; column++) { 17 Queen queen = new Queen(r, column); 18 if (isSafe(queen, queens)) { 19 List<Queen> qs = new ArrayList<Queen>(); 20 //将上一层回溯的解向量和当前解组合成一个list 21 qs.addAll(queens); 22 qs.add(queen); 23 //将组合好的list放入queenList当中 24 queenList.add(qs); 25 } 26 } 27 } 28 } 29 return queenList; 30 31 } 32 33 public static boolean isSafe(Queen queen, List<Queen> queens) { 34 for (Queen q : queens) { 35 if (inCheek(q, queen)) 36 return false; 37 } 38 return true; 39 } 40 41 public static boolean inCheek(Queen Queen, Queen queen2) { 42 return Queen.x == queen2.x 43 || Queen.y == queen2.y 44 || Math.abs(Queen.x - Queen.y) == Math 45 .abs((queen2.x - queen2.y)); 46 } 47 48 public static void main(String args[]) { 49 50 for (List<Queen> queens : new Queens().queens(8)) { 51 for (Queen queen : queens) { 52 System.out.print(String.format("(%d, %d)", queen.x, queen.y)); 53 } 54 System.out.println(); 55 } 56 57 } 58 }
浙公网安备 33010602011771号