• 序列比对之动态规划


    序列比对

    问题描述
    输入:两个序列A和B,其长度分别为m和n
    输出:A和B的一种比对形式,其满足惩罚函数f(A,B)值最小。
    (1) 对A和B之间的每一个空隙匹配,计惩罚分2分;
    (2)对A和B之间的每一个错配,计惩罚分3分;
    (3)成功配对不计惩罚分
    最后求解得到最小的罚分值:

    问题分析
    1、分析问题的最优子结构性质
    假设两个序列S1和S2,求他们的最长公共子序列,则:
    1)S1[i] = S2[j],那么这两个数匹配
    2)S1[i] != S2[j],S1[i-1] = S2[j],那么S1[i]匹配空
    3)S1[i] != S2[j],S1[i] = S2[j-1],那么S2[j]匹配空
    也就是说,当有相邻两个数据相等的时候,优先选择匹配相等的数据,将一个置空

    2、建立递推公式
    dp[i][j] 表示:S1的前 i 个字符和S2的前 j 个字符的匹配最小结果
    1)dp[i][0] == 2i,此时都是空隙匹配
    2)dp[0][j] == 2
    j,此时都是空隙匹配
    3)每次循环S1[i]与S2[j]匹配
    如果相等那么不变dp[i][j]=dp[i-1][j-1]
    如果不相等:dp[i][j]=min(dp[i-1][j-1]+3,dp[i-1][j]+2,dp[i][j-1]+2)

    3、自底向上求解

    4、根据计算最优值得到的信息,构造最优解

    代码演示

    #include <iostream>
    using namespace std;
    
    const int N=100;
    string s1="aabcdefgaa";
    string s2="abcdefglll";
    int dp[N][N];
    int main()
    {
        /*
           a a b c d e f g a a _
           _ a b c d e f g l l l
        */
    
        int n=s1.size(),m=s2.size();//n行m列
        for(int i=0;i<=m;i++){
            dp[0][i]=2*i;
        }
        for(int i=0;i<=n;i++){
            dp[i][0]=2*i;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(s1[i-1]==s2[j-1])
                    dp[i][j]=min(min(dp[i-1][j-1],dp[i-1][j]+2),dp[i][j-1]+2);
                else
                    dp[i][j]=min(min(dp[i-1][j-1]+3,dp[i-1][j]+2),dp[i][j-1]+2);
            }
        }
    
        cout<<"min="<<dp[n][m]<<endl;
        return 0;
    }
    
    
  • 相关阅读:
    Exp8-Web综合
    Exp7-网络欺诈防范
    Exp6-MSF应用基础
    加密API学习
    Exp5 信息搜集与漏洞扫描
    Exp4-恶意代码分析
    Exp3-免杀原理
    Exp2-后门原理与实践
    leetcode 22括号生成 暴力法
    413 等差数列划分
  • 原文地址:https://www.cnblogs.com/Indomite/p/14195226.html
Copyright © 2020-2023  润新知