算法随笔:动态规划算法实现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

 

猜你喜欢

转载自blog.csdn.net/whandwho/article/details/80824548
今日推荐