1. 程式人生 > >演算法隨筆:動態規劃演算法實現DNA序列對齊

演算法隨筆:動態規劃演算法實現DNA序列對齊

背景:專業寫作課的實驗專案

專案背景:利用動態規劃演算法的思想實現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