回溯算法的经典算法,如素数环问题、哈密顿回路、N皇后问题等。
回溯
经典算法
素数环问题
将正整数1~n填入环中,满足如下条件:
每个数字只能用一次
相邻两个数字之和是素数,最后一个元素与第一个元素之和也为素数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 public static void PrimeCircle (int n) { int i, k; int [] circle = new int [n]; for (i = 0 ; i < n; i++) { circle[i] = 0 ; } circle[0 ] = 1 ; k = 1 ; while (k >= 1 ) { circle[k]++; while (circle[k] <= n) { if (Check(circle, k)) break ; else circle[k]++; } if (circle[k] <= n && k == n - 1 ) { for (int item : circle) { System.out.println(item); } return ; } else if (circle[k] <= n && k < n - 1 ) k++; else { circle[k--] = 0 ; } } }public static boolean Check (int [] circle, int k) { boolean flag; for (int i = 0 ; i < k; i++) { if (circle[i] == circle[k]) return false ; } flag = Prime(circle[k] + circle[k - 1 ]); if (flag && k == circle.length - 1 ) { flag = Prime(circle[k] + circle[0 ]); } return flag; }public static boolean Prime (int x) { int i, n; n = (int ) Math.sqrt(x); for (i = 2 ; i <= n; i++) { if (x % i == 0 ) return false ; } return true ; }
图着色问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public static void GraphColor (int [][] arc, int m) { int i, k = 0 ; int n = arc.length; int [] color = new int [n]; for (i = 0 ; i < n; i++) { color[i] = 0 ; } while (k >= 0 ) { color[k]++; while (color[k] <= m) { if (Ok(arc, color, k)) break ; else color[k]++; } if (color[k] <= m && k == n - 1 ) { for (int item : color) { System.out.println(item); } return ; } else if (color[k] <= m && k < n - 1 ) k++; else color[k--] = 0 ; } }public static boolean Ok (int [][] arc, int [] color, int k) { for (int i = 0 ; i < k; i++) if (arc[k][i] == 1 && color[i] == color[k]) return false ; return true ; }
哈密顿回路
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 public static void Hamiton (int [][] arc) { int i, k; int n = arc.length; int [] visited = new int [n]; int [] x = new int [n]; for (i = 0 ; i < n; i++) { x[i] = 0 ; visited[i] = 0 ; } x[0 ] = 0 ; visited[0 ] = 1 ; k = 1 ; while (k >= 1 ) { x[k]++; while (x[k] < n) { if (visited[x[k]] == 0 && arc[x[k - 1 ]][x[k]] == 1 ) break ; else x[k]++; } if (x[k] < n && k == n - 1 && arc[x[k]][0 ] == 1 ) { for (k = 0 ; k < n; k++) System.out.println(x[k] + 1 ); return ; } else if (x[k] < n && k < n - 1 ) { visited[x[k]] = 1 ; k++; } else { visited[x[k]] = 0 ; x[k] = 0 ; k--; visited[x[k]] = 0 ; } } }
N皇后问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public static void Queen (int n) { int k = 0 ; int [] x = new int [n]; for (int i = 0 ; i < n; i++) x[i] = -1 ; while (k >= 0 ) { x[k]++; while (x[k] < n && Place(x, k)) { x[k]++; } if (x[k] < n && k == n - 1 ) { for (int i = 0 ; i < n; i++) { System.out.println(x[i] + 1 ); } return ; } else if (x[k] < n && k < n - 1 ) { k++; } else { x[k--] = -1 ; } } System.out.println("无解" ); }public static boolean Place (int [] x, int k) { for (int i = 0 ; i < k; i++) { if (x[i] == x[k] || Math.abs(i - k) == Math.abs(x[i] - x[k])) { return true ; } } return false ; }
批处理作业调度问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 public static int BatchJob (int [] a, int [] b) { int i, k; int n = a.length; int [] x = new int [n + 1 ]; int [] sum1 = new int [n + 1 ]; int [] sum2 = new int [n + 1 ]; int bestTime = 10000 ; for (i = 1 ; i <= n; i++) { x[i] = -1 ; sum1[i] = 0 ; sum2[i] = 0 ; } sum1[0 ] = 0 ; sum2[0 ] = 0 ; k = 1 ; while (k >= 1 ) { x[k]++; while (x[k] < n) { for (i = 1 ; i < k; i++) { if (x[i] == x[k]) { break ; } } if (i == k) { sum1[k] = sum1[k - 1 ] + a[x[k]]; sum2[k] = Math.max(sum1[k], sum2[k - 1 ]) + b[x[k]]; if (sum2[k] <= bestTime) break ; else x[k]++; } else x[k]++; } if (x[k] < n && k < n) { k++; } else { if (x[k] < n && k == n) { if (bestTime >= sum2[k]) { bestTime = sum2[k]; System.out.println("目前最短作业安排是:" ); for (int j = 1 ; j <= n; j++) System.out.println(x[j] + 1 ); System.out.println("最短时间是:" + bestTime); } }else x[k--] = -1 ; } } return bestTime; }