Bio-Info 每日一题:Rosalind-04-Rabbits and Recurrence Relations

2024-06-08 23:44

本文主要是介绍Bio-Info 每日一题:Rosalind-04-Rabbits and Recurrence Relations,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

🎉 进入生物信息学的世界,与Rosalind一起探索吧!🧬
Rosalind是一个在线平台,专为学习和实践生物信息学而设计。该平台提供了一系列循序渐进的编程挑战,帮助用户从基础到高级掌握生物信息学知识。无论你是初学者还是专业人士,Rosalind都能为你提供适合的学习资源和实践机会。网址:https://rosalind.info
你是否想像专业人士一样分析DNA序列?这里有一个简单的任务来帮助你入门。
📝 任务说明:
请添加图片描述

斐波那契数列(Fibonacci sequence),又称黄金分割数列,因数学家莱昂纳多·斐波那契(Leonardo Fibonacci)以兔子繁殖为例子而引入,故又称“兔子数列”。其数值为:1、1、2、3、5、8、13、21、34……在数学上,这一数列以如下递推的方法定义:F(0)=0,F(1)=1, F(n)=F(n - 1)+F(n - 2)(n ≥ 2,n ∈ N*)。
假设每对兔子生育时只生下一对小兔子,生下的小兔子用一个月时间成熟,在生下来的第二个月长成大兔子,在第三个月又能够生一对小兔子。如此循环往复,且在这个过程中所有兔子不会死。
以上是简化的斐波那契数列,根据给出的求和公式我们可以较为轻松地写出代码:

def fibonacci_digui(month):if month == 1 or month == 2:return 1else:return fibonacci_digui(month - 1) + fibonacci_digui(month - 2)
# 迭代
def fibonacci_diedai(month):a, b = 0, 1for _ in range(month-1):a, b = b, a + breturn b

但是在这个问题中,给了两个参数 nkn 代表月份数,k 代表每对兔子每次生下的小兔子对数(k≤5)。要求计算在 n(n≤40)月之后的兔子对数。。

示例:

请添加图片描述

我们可以简单分析一下:第一个月是1对,第二月也是1对,第三个月是3对,第四个月是7对,第五个月是19对。为了方便表示后面我们就用 F(n) 表示对应月份的兔子数量。可以将兔子分成老兔子和新兔子,其中老兔子数量是上个月的数量,新兔子是成熟的兔子生的。

F(1)=1
F(2)=1
F(3)=1+(1*3)=F(2)+F(1)*3
F(4)=1*3+3=F(3)+F(2)*3
......
这样我们又能推导出一个公式,以此为依据写代码会方便不少

这样我们就能推导出一个公式,以此为依据写代码会方便不少。
因为兔子需要一个月的时间长大,所以这个月的兔子数量等于上个月数量加上 k 倍的前个月数量(前个月的兔子这个月可以生)。
请添加图片描述

解答:

def rabbit_born_digui(month, produce):if month == 1 or month == 2:return 1else:return (rabbit_born_digui(month - 1, produce)) + (rabbit_born_digui(month - 2, produce) * produce)def rabbit_born_diedai(month, produce):a, b = 0, 1for _ in range(month - 1):a, b = b * produce, a + breturn b

同时对于递归和迭代两种方法,迭代会更快,我们通过下面一段代码进行检验:

import time
def rabbit_born_digui(month, produce):if month == 1 or month == 2:return 1else:return (rabbit_born_digui(month - 1, produce)+ rabbit_born_digui(month - 2, produce) * produce)def rabbit_born_diedai(month, produce):a, b = 1, 1for _ in range(month - 2):a, b = b, a * produce + breturn bdef main():month = 30  # 可以调整这个值来测试较大的 monthproduce = 3# 测试递归实现的运行时间start_time = time.time()result_recursive = rabbit_born_digui(month, produce)end_time = time.time()print(f"递归实现:第{month}个月后共有 {result_recursive} 对兔子,运行时间:{end_time - start_time:.5f} 秒")# 测试迭代实现的运行时间start_time = time.time()result_iterative = rabbit_born_diedai(month, produce)end_time = time.time()print(f"迭代实现:第{month}个月后共有 {result_iterative} 对兔子,运行时间:{end_time - start_time:.5f} 秒")if __name__ == "__main__":main()

在这里插入图片描述
请添加图片描述

题外话

让GPT帮忙改了改代码,用记忆化递归和动态规划两种方法实现,之前的递归方法当月份设置到七八十的时候就已经很吃力了,结果这两种方法依旧是丝滑运行。

import time
def rabbit_born_digui_memo(month, produce, memo=None):if memo is None:memo = {}if month in memo:return memo[month]if month == 1 or month == 2:result = 1else:result = rabbit_born_digui_memo(month - 1, produce, memo) + rabbit_born_digui_memo(month - 2, produce, memo) * producememo[month] = resultreturn resultdef rabbit_born_diedai(month, produce):if month == 1 or month == 2:return 1dp = [0] * (month + 1)dp[1], dp[2] = 1, 1for i in range(3, month + 1):dp[i] = dp[i - 1] + dp[i - 2] * producereturn dp[month]def main():month = 78  # 可以调整这个值来测试较大的 monthproduce = 3# 测试记忆化递归实现的运行时间start_time = time.time()result_recursive_memo = rabbit_born_digui_memo(month, produce)end_time = time.time()print(f"记忆化递归实现:第{month}个月后共有 {result_recursive_memo} 对兔子,运行时间:{end_time - start_time:.5f} 秒")# 测试动态规划实现的运行时间start_time = time.time()result_iterative = rabbit_born_diedai(month, produce)end_time = time.time()print(f"动态规划实现:第{month}个月后共有 {result_iterative} 对兔子,运行时间:{end_time - start_time:.5f} 秒")if __name__ == "__main__":main()

![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/831767a7ee8f4ecca69403a0d01642d6.png

加入Rosalind,开始你的生物信息学探索之旅吧!
纸上得来终觉浅,绝知此事要躬行。
公众号:BIoYfan,之后会坚持同步更新生信方面内容
与君共勉💪

这篇关于Bio-Info 每日一题:Rosalind-04-Rabbits and Recurrence Relations的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1043646

相关文章

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

取得 Git 仓库 —— Git 学习笔记 04

取得 Git 仓库 —— Git 学习笔记 04 我认为, Git 的学习分为两大块:一是工作区、索引、本地版本库之间的交互;二是本地版本库和远程版本库之间的交互。第一块是基础,第二块是难点。 下面,我们就围绕着第一部分内容来学习,先不考虑远程仓库,只考虑本地仓库。 怎样取得项目的 Git 仓库? 有两种取得 Git 项目仓库的方法。第一种是在本地创建一个新的仓库,第二种是把其他地方的某个

每日一题|牛客竞赛|四舍五入|字符串+贪心+模拟

每日一题|四舍五入 四舍五入 心有猛虎,细嗅蔷薇。你好朋友,这里是锅巴的C\C++学习笔记,常言道,不积跬步无以至千里,希望有朝一日我们积累的滴水可以击穿顽石。 四舍五入 题目: 牛牛发明了一种新的四舍五入应用于整数,对个位四舍五入,规则如下 12345->12350 12399->12400 输入描述: 输入一个整数n(0<=n<=109 ) 输出描述: 输出一个整数

springboot体会BIO(阻塞式IO)

使用springboot体会阻塞式IO 大致的思路为: 创建一个socket服务端,监听socket通道,并打印出socket通道中的内容。 创建两个socket客户端,向socket服务端写入消息。 1.创建服务端 public class RedisServer {public static void main(String[] args) throws IOException {

每日一练7:简写单词(含链接)

1.链接 简写单词_牛客题霸_牛客网 2.题目 3.代码1(错误经验) #include <iostream>#include <string>using namespace std;int main() {string s;string ret;int count = 0;while(cin >> s)for(auto a : s){if(count == 0){if( a <=

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

Yii框架relations的使用

通过在 relations() 中声明这些相关对象,我们就可以利用强大的 Relational ActiveRecord (RAR) 功能来访问资讯的相关对象,例如它的作者和评论。不需要自己写复杂的 SQL JOIN 语句。 前提条件 在组织数据库时,需要使用主键与外键约束才能使用ActiveReocrd的关系操作; 场景 申明关系 两张表之间的关系无非三种:一对多;一对一;多对多; 在

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

还不懂BIO,NIO,AIO吗

BIO(Blocking I/O)、NIO(Non-blocking I/O)和 AIO(Asynchronous I/O)是 Java 中三种不同的 I/O 模型,主要用于处理输入 / 输出操作。 一、BIO(Blocking I/O) 定义与工作原理: BIO 即阻塞式 I/O(同步阻塞,传统IO)。在这种模型下,当一个线程发起一个 I/O 操作(如读取文件或网络数据)时,此线

读软件设计的要素04概念的关系

1. 概念的关系 1.1. 概念是独立的,彼此间无须相互依赖 1.1.1. 一个概念是应该独立地被理解、设计和实现的 1.1.2. 独立性是概念的简单性和可重用性的关键 1.2. 软件存在依赖性 1.2.1. 不是说一个概念需要依赖另一个概念才能正确运行 1.2.2. 只有当一个概念存在时,包含另一个概念才有意义 1.3. 概念依赖关系图简要概括了软件的概念和概念存在的理