Rosalind编程问题之计算随机序列出现概率的公共对数。
这道题让小编想起了被GRE支配的恐惧,能看懂你就会做。
Problem:
GC-content offers us natural symbol frequencies for constructing random DNA strings. If the GC-content is x, then we set the symbol frequencies of C and G equal to x2 and the symbol frequencies of A and T equal to 1−x2. For example, if the GC-content is 40%, then as we construct the string, the next symbol is ‘G’/‘C’ with probability 0.2, and the next symbol is ‘A’/‘T’ with probability 0.3.
In practice, many probabilities wind up being very small. In order to work with small probabilities, we may plug them into a function that “blows them up” for the sake of comparison. Specifically, the common logarithm of x (defined for x>0 and denoted log10(x)) is the exponent to which we must raise 10 to obtain x.
Given: A DNA string s of length at most 100 bp and an array A containing at most 20 numbers between 0 and 1.
Sample input:
ACGATACAA
0.129 0.287 0.423 0.476 0.641 0.742 0.783
Return: An array B having the same length as A in which B[k] represents the common logarithm of the probability that a random string constructed with the GC-content found in A[k] will match s exactly.
Sample output:
-5.737 -5.217 -5.263 -5.360 -5.958 -6.628 -7.009
发生概率是一个处于0-1之间的值。在生物领域经常会用到公共对数进行概率转化,目的是将0-1之间的数放大得更明显。本题给出了一条碱基序列,同时还有一组数值。后者代表着GC在某一序列中比例。题目设问:假设有一条未知序列,该序列与题目给出的序列拥有相同的长度。但是其GC比例遵循着给出的数组,需要我们计算不同GC比例下,未知序列等于给出序列的概率,并进行公共对数转化。
未知序列等于给出序列的概率的计算是本题的核心。需要我们统计给出序列的GC个数和AT个数,G或C出现的概率是给出数的一半,相应A或T的概率就是1减去给出数,整体再除以二。那么此时两条序列相等的概率就是G或C出现概率的GC个数次方 * A或T出现概率的AT个数次方。 当然最后再进行个log10转化。也可以参考下面的图(以ACGTA序列, GC含量0.129为例):
解题思路如下:
1.读取文本文件,分别获取碱基序列(第一行)和GC比例(第二行)作为输入。
2.统计给出序列的GC数和AT数,根据GC比例计算G/C以及A/T出现的概率。
3.结合第二步,计算给出序列与未知序列相同的概率。
4.将概率进行公共对数转化。
代码如下:
public class Introduction_to_Random_Strings {
public static void main(String[] args) {
//1.读取文本文件作为输入
List RandomString = ReaderString("C:/Users/Administrator/Desktop/rosalind_long.txt");
String seq = (String) RandomString.get(0);//保存第一行的序列到seq变量
String[] prob = RandomString.get(1).split(" ");//保存第二行的概率数组为字符串类型,输入文件是以空格分隔,故而由此拆分成数组。
//2.概率计算
List log10list = commonlogarithm(seq, prob);
for (Double integer : log10list) {
System.out.print((float) (Math.round(integer * 1000)) / 1000 + " ");//最终结果四舍五入
}
}
//method1.读取文本文件作为输入
public static List ReaderString(String path) {
BufferedReader reader;
List tag = new ArrayList<>();
try {
reader = new BufferedReader(new FileReader(path));
String line = reader.readLine();
while (line != null) {
tag.add(line);
// read next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return tag;
}
//method2.计算给定序列的GC含量
public static int GCcontent(String seq) {
int GC = 0;
for (int i = 0; i < seq.length(); i++) {
if (seq.charAt(i) == 'G' || seq.charAt(i) == 'C') {
GC++;
}
}
return GC;
}
//method3.计算概率的公共对数函数
public static List commonlogarithm(String seq, String[] prob) {
List log10list = new ArrayList<>();
for (int i = 0; i < prob.length; i++) {
double GCprob = Double.parseDouble(prob[i]);
double finalprob = Math.log(Math.pow(GCprob / 2, GCcontent(seq)) * Math.pow((1 - GCprob) / 2, seq.length() - GCcontent(seq))) / Math.log(10);
log10list.add(finalprob);
}
return log10list;
}
}
很有意思的题,既锻炼了英语阅读,又锻炼了数学思维,还锻炼了编程代码。
暑期编程PK赛 得CSDN机械键盘等精美礼品!


