演算法隨筆:動態規劃演算法實現DNA序列對齊
阿新 • • 發佈:2019-02-01
背景:專業寫作課的實驗專案
專案背景:利用動態規劃演算法的思想實現DNA的序列最優對齊
演算法思路:暫時略
註明:兩小時寫兩小時調程式碼,請尊重博主原創。同一課程的看到了是不是應該加個關注,hhh。
轉載請註明出處:https://blog.csdn.net/whandwho/article/details/80824548
還使用了 分治演算法得到花費時間。
可直接執行專案見:點選開啟連結
完整的專案,Java環境下直接複製進入專案可執行。
-------------------------------------------------------------
下面的程式碼是完整的專案:可直接執行
原始碼:
package alignment; import java.util.ArrayList; import java.util.List; public class Sequence { public Sequence() { } // 儲存類的list static final private List<Record> list = new ArrayList<Record>(); private int k = 0; // 計算代價值的矩陣表示 public int[][] getArray(String rowString, String colString) { // 行數 int rowLength = rowString.length(); // 列數 int colLength = colString.length(); int[][] arr = new int[rowLength + 1][colLength + 1]; // 最底層資料計算 for (int i = colLength; i >= 0; i--) { arr[rowLength][i] = 2 * (colLength - i); } // 最右側資料計算 for (int j = rowLength; j >= 0; j--) { arr[j][colLength] = 2 * (rowLength - j); } int penalty = 0; for (int i = rowLength - 1; i >= 0; i--) { for (int j = colLength - 1; j >= 0; j--) { if (rowString.charAt(i) == colString.charAt(j)) {// 計算cost penalty = 0; } else { penalty = 1; } // 最小的那個 arr[i][j] = Math.min(arr[i + 1][j + 1] + penalty, Math.min(arr[i + 1][j] + 2, arr[i][j + 1] + 2)); } } ////////////////////////////////////////////////////// for (int i = 0; i <= rowLength; i++) { for (int j = 0; j <= colLength; j++) { System.out.format("%3d", arr[i][j]); } System.out.println(); } ////////////////////////////////////////////////////// return arr; } private int rowDefalut = 0; private int colDefalut = 0; // 回溯 尋找一條路徑即可 public List<Record> getBackTrack(int arr[][], String rowString, String colString, int tag) { // 每次遞迴 : 第一個記錄為左上方第一個 if (tag == 0) { System.out.println("起始:" + rowDefalut); System.out.println(colDefalut); list.add(new Record(0, 0)); } else if (tag == 1) { rowDefalut++; colDefalut++; System.out.println("起始:" + rowDefalut); System.out.println(colDefalut); list.add(new Record(rowDefalut, colDefalut)); } else if (tag == 2) { rowDefalut++; System.out.println("起始:" + rowDefalut); System.out.println(colDefalut); list.add(new Record(rowDefalut, colDefalut)); } else if (tag == 3) { colDefalut++; System.out.println("起始:" + rowDefalut); System.out.println(colDefalut); list.add(new Record(rowDefalut, colDefalut)); } ////////////////////////////////////////////////////// k++; System.out.println("第 " + k + " 次遞迴!"); ////////////////////////////////////////////////////// // 遞迴釋放條件 if (arr.length > 1 && arr[0].length > 1) { int temp = arr[0][0];// 中間值 int penalty = 0;// 代價 if (rowString.charAt(0) == colString.charAt(0)) { penalty = 0; } else { penalty = 1; } // 判斷是由右邊 下邊 右下邊 哪一個得到 // if else if 只會執行一個 if (temp == arr[0 + 1][0 + 1] + penalty) { // list.add(new Record(0 + 1, 0 + 1)); String SubRowString = rowString.substring(1); String SubColString = colString.substring(1); // 遞迴 getBackTrack(getSubArray(arr, SubRowString, SubColString, 1, 1), SubRowString, SubColString, 1); } else if (temp == arr[0][0 + 1] + 2) { // list.add(new Record(0, 0 + 1)); String SubRowString = rowString.substring(0); String SubColString = colString.substring(1); // 遞迴 getBackTrack(getSubArray(arr, SubRowString, SubColString, 0, 1), SubRowString, SubColString, 2); } else if (temp == arr[0 + 1][0] + 2) { // list.add(new Record(0 + 1, 0)); String SubRowString = rowString.substring(1); String SubColString = colString.substring(0); // 遞迴 getBackTrack(getSubArray(arr, SubRowString, SubColString, 1, 0), SubRowString, SubColString, 3); } } return list; } // 一個求解子矩陣的方法 public int[][] getSubArray(int arr[][], String rowSubString, String colSubString, int rowStart, int colStart) { // 子序列數 int SubrowLength = rowSubString.length(); // 子串列數 int SubcolLength = colSubString.length(); System.out.println(rowSubString); System.out.println(colSubString); // System.out.println(rowStart); // System.out.println(colStart); int[][] subArr = new int[SubrowLength + 1][SubcolLength + 1]; for (int i = 0; i <= SubrowLength; i++) { for (int j = 0; j <= SubcolLength; j++) { // 相對座標 // System.out.println(i); // System.out.println(j); // System.out.println(arr[rowStart + i][colStart + j]); // System.out.println("......"); subArr[i][j] = arr[rowStart + i][colStart + j]; } } /////////////////////////////////////////// System.out.println("子矩陣:"); for (int i = 0; i <= SubrowLength; i++) { for (int j = 0; j <= SubcolLength; j++) { System.out.format("%3d", subArr[i][j]); } System.out.println(); } /////////////////////////////////////////// return subArr; } // 獲得對齊序列 public char[][] getAlignmentSequence(String rowString, String colString, List<Record> list) { int length = Math.max(rowString.length(), colString.length()); char[][] sequArr = new char[2][length+1]; // 第一個記錄的 橫縱座標值 int ifirst = list.get(0).getRow(); int jfirst = list.get(0).getCol(); // 第一行放 rowString // 第二行放 colString sequArr[0][0] = rowString.charAt(ifirst); sequArr[1][0] = colString.charAt(jfirst); // 第一個之後的記錄 for (int i = 1; i < list.size()-1; i++) { System.out.println("list的size:"+list.size()); int iIn = list.get(i).getRow(); int jIn = list.get(i).getCol(); System.out.println(iIn); System.out.println(jIn); // 判斷加gap的情況 if ((iIn != list.get(i - 1).getRow()) && (jIn != list.get(i - 1).getCol())) { // 對角線 sequArr[0][i] = rowString.charAt(jIn); sequArr[1][i] = colString.charAt(iIn); } else if ((iIn == list.get(i - 1).getRow()) && (jIn != list.get(i - 1).getCol())) { // 下方 sequArr[0][i] = rowString.charAt(jIn); sequArr[1][i] = '#';// 加gap } else if ((iIn != list.get(i - 1).getRow()) && (jIn == list.get(i - 1).getCol())) { // 右邊 sequArr[0][i] = '#';// 加gap sequArr[1][i] = colString.charAt(iIn); } } /////////////////////////////////////////////////////////////////////// for (int i = 0; i < 2; i++) { for (int j = 0; j < length; j++) { System.out.print(sequArr[i][j] + " "); } System.out.println(); } /////////////////////////////////////////////////////////////////////// return sequArr; } public static void main(String[] args) { String String1 = "AACAGTTACC"; String String2 = "TAAGGTCA"; Sequence sequence = new Sequence(); int[][] costArray = sequence.getArray(String1, String2); List<Record> list = sequence.getBackTrack(costArray, String1, String2, 0); char[][] sequArr = sequence.getAlignmentSequence(String1, String2, list); System.out.println("對齊序列為:\n" + sequArr); } // 回溯的時候新建這個類,然後將類存在指定的資料結構 ArrayList 中 class Record { int row; int col; public Record(int row, int col) { this.row = row; this.col = col; } public int getRow() { return row; } public int getCol() { return col; } } }
轉載請註明出處:https://blog.csdn.net/whandwho/article/details/80824548