一道算法题求解答

jrjdr19830726 2009-08-11 05:09:36
一个字符串,长度为5,字符串的每个位置上只能出现A T G C四个字符中的一个,每个位置上的四种字符出现的概率不同,要求计算出生成概率最大的前50个字符串,不使用穷举,

例如
位置 1 2 3 4 5

A 0.2 0.3 0.1 0.55 0.25

T 0.3 0.5 0.6 0.25 0.25

G 0.1 0.05 0.2 0.2 0.25

C 0.4 0.15 0.1 0 0.25

则出现概率最大的前4个字符分别是:
CTTAA CTTAT CTTAG CTTAC
它们的概率皆为:P(x)=0.4 * 0.5 * 0.6 * 0.55 * 0.25
...全文
270 点赞 收藏 18
写回复
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
zsxcn 2009-08-24
mark
回复
青蛙果果 2009-08-23
等待高人
回复
arczee 2009-08-23
有一种方法,其时间复杂度为O(n*X), 先给出根据概率选取的从大到小排列的概率组合序列如下,要注意的是,P(1)表示某列中的最大概率,而从左到右的顺序是所有P(1)从大到小排列的。即先选所有组的最大概率中的最大的,标记此列,再选剩下列中最大概率的最大值,以此类推。
P(1)*P(1)*P(1)*P(1)*P(1) //都能看出来的最大概率组合

P(1)-P(1)-P(1)-P(1)-P(2) //***第一轮: P(2)是某列中的第二大概率字母的概率
P(1)-P(1)-P(1)-P(2)-P(1)
P(1)-P(1)-P(2)-P(1)-P(1) //P(2)从右到左的顺序保证了其下面的所有概率组合的
P(1)-P(2)-P(1)-P(1)-P(1) //概率和都比它小。
P(2)-P(1)-P(1)-P(1)-P(1)


P(1)-P(1)-P(1)-P(2)--P(2) //***第二轮 固定最后一个为P(2),再将前面选择的四列
P(1)-P(1)-P(2)-P(1)--P(2) //重复第一轮类似的过程
P(1)-P(2)-P(1)-P(1)--P(2)
P(2)-P(1)-P(1)-P(1)--P(2)

P(1)-P(1)-P(2)--P(2)-P(2) //***第三轮 固定最后两个选择列为P(2),再重复
P(1)-P(2)-P(1)--P(2)-P(2)
P(2)-P(1)-P(1)--P(2)-P(2)

P(1)-P(2)--P(2)-P(2)-P(2)
P(2)-P(1)--P(2)-P(2)-P(2)

P(2)-P(2)-P(2)-P(2)-P(2) //到此,含P(1)的组合都抽出来了,并排了序。

P(2)-P(2)-P(2)-P(2)-P(3)
P(2)-P(2)-P(2)-P(3)-P(2)
P(2)-P(2)-P(3)-P(2)-P(2)
P(2)-P(3)-P(2)-P(2)-P(2)
P(3)-P(2)-P(2)-P(2)-P(2)
。。。

这只是一个思想,但是容易转化为程序,因为有规律可循, 对于长度N很大时很有效率,每次的代码花费在从所有列中取出P(i),并进行排序。记代价为O(X),根据方法不同而不同。
回复
arczee 2009-08-23
直接用贪心法肯定不行的,贪心法只能得出最优的,而无法得出次优的,另想吧
回复
whg01 2009-08-20
[Quote=引用 4 楼 qq675927952 的回复:]
贪心吧,每一个位置都取这个位置上概率最大的字符
[/Quote]

正解。
回复
showjim 2009-08-12
应该是很多个"最大50"两两归并
回复
showjim 2009-08-12
[Quote=引用 10 楼 sbwwkmyd 的回复:]
引用 8 楼 fire_woods 的回复:
楼上的方法不错.支持.

对的,把数据分成两部分64*n;n那边取最大值,64这边取前50,这样不可能有其它给合比这50大了.
[/Quote]
错了,不对,n这边第二大数乘以64那边最大数 是可能大于 n这边最大数乘以64那边最小数的;
明天再想想.
回复
showjim 2009-08-12
[Quote=引用 8 楼 fire_woods 的回复:]
楼上的方法不错.支持.
[/Quote]
对的,把数据分成两部分64*n;n那边取最大值,64这边取前50,这样不可能有其它给合比这50大了.
回复
mathwj 2009-08-12
我觉得可能是这样的:
(1)对五个位置,各自建立一个队列并进行从大到小的排序
(2)第一个字符串肯定五个位置中各自的队头字符,这五个元素出队列组成该字符串。
(3)在五个队列的队头中找出最大值,并代替字符串中最小值。
(4)循环(3),就此输出三十个字符串。
回复
jrjdr19830726 2009-08-12

7楼是不是这个意思?

类动态规划

维护一个包含有50个字符串的最高概率的list。 list <string>的容量为50
比如
计算含有第一个字符并概率最高的前50个子串
有 4 个 string 分别为 A T C G
计算含有第一,第二个字符并概率最高的前50个子串
有 16 个 string
计算含有第一,第二,第三个字符并概率最高的前50个子串
有 64 个 string (只取 有最高概率的前50)加入list

计算含有第一,第二,第三,第四个字符并概率最高的前50个子串

将原list中50个长度为三的string(x1,x2,x3)每一个都使用穷举扩展成长度
为四的string :
(x1,x2,x3,A),(x1,x2,x3,T),(x1,x2,x3,G),(x1,x2,x3,C)

则原50个string可形成50*4=200个四字符的字符串string,对这200个string进行排序
将五十个概率最高的字符串加入list

计算含有第一,第二,第三,第四,第五个字符并概率最高的50个字符串
。。。。。。。。
由于最大概率字符串必然包含最大概率子串,则都只取有最高概率的前50个string
最后留下来的自然是概率最大的50个string;
回复
fire_woods 2009-08-12
楼上的方法不错.支持.
回复
类动态规划

维护一个包含有50个字符串的最高概率的list。 list<string>string的容量为50
比如
对于进入第一个字符
有 4 个 string 分别为 A T C G
对于进入第二个字符
有 16 个 string
对于进入第三个字符
有 64 个 string (只取 有最高概率的前50)

对于以后的……
都只取有最高概率的前50最后留下来的自然是前50;


[Quote=引用楼主 jrjdr19830726 的回复:]
一个字符串,长度为5,字符串的每个位置上只能出现A T G C四个字符中的一个,每个位置上的四种字符出现的概率不同,要求计算出生成概率最大的前50个字符串,不使用穷举,

例如
位置    1    2    3    4    5

A      0.2  0.3  0.1  0.55 0.25

T      0.3  0.5  0.6  0.25 0.25

G      0.1  0.05 0.2  0.2  0.25

C      0.4  0.15 0.1  0    0.25

则出现概率最大的前4个字符分别是:
CTTAA CTTAT CTTAG CTTAC
它们的概率皆为:P(x)=0.4 * 0.5 * 0.6 * 0.55 * 0.25
[/Quote]
回复
linren 2009-08-11
例如
位置 1 2 3 4 5

A 0.2 0.3 0.1 0.55 0.25

T 0.3 0.5 0.6 0.25 0.25

G 0.1 0.05 0.2 0.2 0.25

C 0.4 0.15 0.1 0 0.25

因为可以重复选择
所以直接选取每个位置上概率最大的字母就可以了……

如果有一个50位的表
第1个数选择第1位上概率最大的字母
第2个数选择第2位上概率最大的字母
……
第50个数选择第50位上概率最大的字母……
回复
jrjdr19830726 2009-08-11
实际运用中基因碱基序列的字符串长度通常是20到100,如果使用穷举,太耗时(最少是4的20次方)
回复
qq675927952 2009-08-11
贪心吧,每一个位置都取这个位置上概率最大的字符
回复
CCC_YQ 2009-08-11
帮你顶!
回复
fire_woods 2009-08-11
吐血推荐穷举.
回复
tinghaiou 2009-08-11
什么算法,看都能看的出来
回复
发动态
发帖子
数据结构与算法
创建于2007-08-27

3.2w+

社区成员

数据结构与算法相关内容讨论专区
申请成为版主
社区公告
暂无公告