演算法與分析設計期末重點複習
阿新 • • 發佈:2021-06-27
1 //@author 軟工.林 2 3 演算法 完蛋! 4 填空題把書裡第一章,其他演算法章節在寫程式碼之前的字看完 20分 5 計算題三大道(估摸就能知道考什麼 除非考重複知識點)30分 6 完善演算法 估計下面出 20分 7 綜合分析不知道 不會啊 估計數學歸納法證明貪心? 30分 8 9 10 主定理法解遞迴表示式的時間複雜度 必考 11 Tn = O(1) n = 1 12 aT(n/b) + f(n) n > 1 13 14 解得:Tn = O(n^k) a < b^k 15 = O((n^k) * logb n) a = b^k16 = O(n^logba) a > b^k 17 18 0-1揹包(估計考填表) 19 最優二叉搜尋樹 20 21 C為揹包容量 22 w(weight) v(value) m[i][j]揹包容量為j,可選擇物品為i,i + 1, ... n時 0-1揹包的最優值 23 //count the best answer 24 public static void knapsack(int[] v, int[] w, int c, int[][] m){ 25 int jMax = Math.min(w[n] - 1, c); 26 for(int j = 0; j <= jMax; j ++){ 27 m[n][j] = 0; 28 } 29 30 for(int j = w[n]; j <= c; j ++){ 31 m[n][j] = v[n]; 32 } 33 //**************key 34 for(int i = n - 1; i > 1; i --){ 35 jMax = Math.min(w[i] - 1, c); 36 for(int j = 0; j <= jMax; j ++){37 m[i][j] = m[i + 1][j]; 38 for(int j = w[i]; j <= c; j ++){ 39 m[i][j] = Math.max(m[i + 1][j], m[i + 1][j - w[i]] + v[i]); 40 } 41 } 42 } 43 //**************key 44 m[1][c] = m[2][c]; 45 if(c >= w[1]) m[1][c] = Math.max(m[1][c], m[2][c - w[1]] + v[1]); 46 } 47 48 //get the best answer 49 public static void traceback(int[][] m, int[] w, int c, int[] x){ 50 for(int i = 1;i < n; i ++){ 51 if(m[i][c] == m[i + 1][c]) x[i] = 0; 52 else{ 53 x[i] = 1; 54 c-=w[i]; 55 } 56 x[n] = (m[n][c] > 0)?1:0; 57 } 58 } 59 60 //bst 61 public static void optimalBinarySearchTree(float[] a, float[] b, float[][] m, int[][] s, float[][] w){ 62 for(int i = 0; i <= n; i ++){ 63 w[i + 1][i] = a[i]; 64 m[i + 1][i] = 0; 65 } 66 67 for(int r = 0; r < n; r ++){ 68 for(int i = 1; i <= n - r; i ++){ 69 int j = i + r; 70 w[i][j] = w[i][j - 1] + a[j] + b[j]; //=> 71 w[i][j] = m[i][i - 1] + m[i + 1][j]; //=>min{m[i][k - 1],m[k + 1][j]} 72 s[i][j] = i; //=> 73 for(int k = i + 1; k <= j; k ++){ 74 float t = m[i][k - 1] + m[k + 1][j]; 75 if(t < m[i][j]){ 76 m[i][j] = t; 77 s[i][j] = k; 78 } 79 m[i][j] += w[i][j]; 80 } 81 } 82 83 } 84 } 85 86 87 貪心演算法總是做區域性最優選擇 88 當一個問題既具有貪心選擇性質又具有最優子結構性質時,必能用貪心演算法得到整體最優解。 89 Dij(可能考計算把我覺得) 90 public static Bintree huffmanTree(float[] f){ 91 int n = f.length; 92 Huffman[] w = new Huffman[n + 1]; 93 Bintree zero = new Bintree(); 94 for(int i = 0; i < n; i ++){ 95 Bintree x = new Bintree(); 96 x.makeTree(new MyInteger(i), zero, zero); 97 w[i + 1] = new Huffman(x, f[i]); 98 } 99 MinHeap H = new MinHeap(); 100 H.initialize(w, n); 101 for(int i = 1; i < n; i ++){ 102 Huffman x = (Huffman).H.removemin(); 103 Huffman y = (Huffman).H.removemin(); 104 Bintree z = new Bintree(); 105 z.makeTree(null,x.tree,y.tree); 106 Huffman t = new Huffman(z,x.weight+y.weight); 107 H.put(t); 108 } 109 110 return ((Huffman)H.removemin()).tree; 111 } 112 public static void dijkstra(int v,float[][] a, float[] dist, int[] prev){ 113 if(v < 1 || v > n) return; 114 boolean[] s = new boolean[n + 1]; 115 for(int i = 1; i < n; i ++){ 116 dist[i] = a[v][i]; 117 s[i] = false; 118 if(dist[i] = Float.MAX_VALUE) prev[i] = 0; 119 else prev[i] = v; 120 } 121 dist[v] = 0; s[v] = true; 122 for(int i = 1; i < n; i ++){ 123 float temp = Float.MAX_VALUE; 124 int u = v; 125 for(int j = 1; j <= n; j ++){ 126 if(!s[j] && (dist[j] < temp)){ 127 u = j; 128 temp = dist[j]; 129 } 130 s[u] = true; 131 for(int j = 1; j <= n; j ++){ 132 if(!s[j] && (a[u][j] < Float.MAX_VALUE)){ 133 float newdist = dist[u] + a[u][j]; 134 if(newdist < dist[j]){ 135 dist[j] = newdist; 136 prev[j] = u; 137 } 138 } 139 } 140 } 141 } 142 } 143 144 批處理作業排程 145 /* 146 n個作業 J1...Jn 147 注意:時間均為從機器x啟動到該作業完成的時間 148 f1,i表示Ji在第一臺機器的處理時間 149 f2,i表示Ji在第二臺機器的處理時間 150 規定第一個任務必須在第一臺機器處理完成之後才能在第二臺機器處理 151 152 找問題方案x->為作業的處理順序 如x = [3,1,2]為作業3->作業2->作業1 153 154 解決方法:搜尋 搜尋大法好! 155 */ 156 class FlowShop{ 157 //n 作業數 f 時間和 f1 機器1完成時間 f2 機器2完成時間 bestf當前最優值 158 static int n, f1, f, bestf; 159 static int[][] m;//各作業所需的處理時間 160 static int[] x; //當前作業排程方案 161 static int[] bestx; //當前最優作業排程 162 static int[] f2; //機器2完成處理時間 163 public static void backtrack(int i){ 164 if(i > n){ 165 for(int j = 1; j <= n; j ++){ 166 bestx[j] = x[j]; 167 } 168 bestf = f; 169 } 170 else{ 171 for(int j = i; j <= n; j ++){ 172 f1 += m[x[j]][1]; 173 f2[i] = ((f2[i - 1] > f1)? f2[i - 1]: f1) + m[x[j]][2]; 174 f+=f2[i]; 175 176 if(f < bestf){ 177 swap(i, j); 178 backtrack(i + 1); 179 swap(i, j); 180 } 181 f1 -= m[x[j]][1]; 182 f -= f2[i]; 183 } 184 } 185 } 186 } 187 188 圖的著色問題 就一個結點一個結點搜尋下去就完事了 不行就回溯就這樣 189 190 class Coloring{ 191 //圖的點數 192 static int n; 193 194 //可用顏色數 195 static int m; 196 197 //圖的鄰接矩陣 198 static boolean [][]a; 199 200 //當前解 201 static int[] x; 202 203 //當前已找到的m可著色方案數 204 static long num; 205 206 public static long mColoring(int mm){ 207 m = mm; 208 sum = 0; 209 backtrack(1); 210 return sum; 211 } 212 213 private static void backtrack(int t){ 214 if(t > n){ 215 sum ++; 216 for(int i = 1; i <= n; i ++){ 217 System.out.print(x[i] + ' '); 218 System.out.println(); 219 } 220 } 221 else{ 222 for(int i = 1; i <= m; i ++){ 223 x[t] = i; 224 //ok函式保證相鄰兩點的顏色不一樣 225 if(ok(t)) backtrack(t + 1); 226 x[t] = 0; 227 } 228 } 229 } 230 231 private static boolean ok(int k){ 232 for(int j = 1; j <= n; j ++){ 233 //估計考這個條件填空 234 if(a[k][j] && (x[j] == x[k])){ 235 return false; 236 } 237 return true; 238 } 239 } 240 }