import java.util.TreeMap; /** * Determine the maximum folding of an RNA sequence using * dynamic programming. * * @author Zach Souser * @version Spring 2013 */ public class DynamicRNAFolding extends RNAFolding { /** * The memoized array of folding values */ public int[][] memo; /** * The trace table of possible TreeMaps */ public TreeMap<Integer,Integer>[][] trace; /** * Find the secondary structure using dynamic programming * * @param inputSequence the sequence in consideration * @return the TreeMap of the secondary structure */ public TreeMap<Integer,Integer> secondaryStructure(String inputSequence) { memo = new int[inputSequence.length()][inputSequence.length()]; // Unsafe operation here, but it still compiles. trace = new TreeMap[inputSequence.length()][inputSequence.length()]; for (int i = 0; i < trace.length; i++) { for (int j = 0; j < trace.length; j++) { trace[i][j] = new TreeMap<Integer,Integer>(); } } for (int k = 4; k < inputSequence.length(); k++) { for (int i = 0; i < inputSequence.length() - k; i++) { int j = i + k; memo[i][j] = memo[i][j-1]; trace[i][j] = trace[i][j-1]; int value = 0; for (int t = i; t < j - 5; t++) { if (isMatch(inputSequence,t,j)) { TreeMap<Integer,Integer> map = new TreeMap<Integer,Integer>(); if (t == 0) { map.put(t,j); map.putAll(trace[t+1][j-1]); value = 1+memo[t+1][j-1]; } else { map.put(t,j); map.putAll(trace[i][t-1]); map.putAll(trace[t+1][j-1]); value = 1 + memo[i][t-1] + memo[t+1][j-1]; } if (value > memo[i][j]) { memo[i][j] = value; trace[i][j] = map; } } } } } return trace[0][inputSequence.length()-1]; } /** * Is the character in position i a match for the character in position j? * * Returns true of A-U or C-G match is found * * @param inputSequence the string in consideration * @param i the ith position * @param j the jth position * @return true if there is a match, false otherwise */ private boolean isMatch(String inputSequence, int i, int j) { return ((inputSequence.charAt(i) == 'U' && inputSequence.charAt(j) == 'A' || inputSequence.charAt(i) == 'C' && inputSequence.charAt(j) == 'G' || inputSequence.charAt(j) == 'U' && inputSequence.charAt(i) == 'A' || inputSequence.charAt(j) == 'C' && inputSequence.charAt(i) == 'G')); } }