Ejemplo n.º 1
0
def can_be_interwoven(s, t, u):
    '''Return True if and only if the motifs t and u can be interwoven into the string s.'''
    nt, nu = len(t), len(u)
    # Allocation + initial condition at i=0. First and last column correspond to the empty motifs.
    # At step i in the outer loop (x=s[i]), m[j,k] = (s[0..i] ENDS with an interweaving of
    # t[0..j], u[0..k] can be interwoven); m_old holds m[i-1, :, :]. 
    m, m_old = ro.zeros_bool_array(nt + 1, nu + 1), ro.zeros_bool_array(nt + 1, nu + 1)
    m[0][0] = -1;  # m_max = m[-1][-1]
    # Dynamic programming - prefixes of s
    for x in s:
        ra.copy_list(m, m_old)
        # Initial condition - first row (j=0)
        for k, uk in enumerate(u, 1):
            m[0][k] = m_old[0][k - 1] if x == uk else 0
        # Initial condition - first column (k=0)
        for j, tj in enumerate(t, 1):
            m[j][0] = m_old[j - 1][0] if x == tj else 0
            # Dynamic programming - prefixes of t,u in s[0..i] vs. in s[0..i-1].
            for j, tj in enumerate(t, 1):
                for k, uk in enumerate(u, 1):
                    mjk = 0
                    if x == tj: mjk |= m_old[j - 1][ k]
                    if x == uk: mjk |= m_old[j][k - 1]
                    m[j][k] = mjk
        # Shortcut: since it's a boolean result and we are OR-ing, once it's True it
        # must stay True, so no need to complete the entire outer loop over s. Had we
        # needed an integer result, we'd have to do the maximization over all s prefixes
        if m[-1][-1]: return True
        #m_max |= m[-1][-1]
    #return m_max
    return False
Ejemplo n.º 2
0
def itwv_matrix(s, t):
    '''Return the boolean matrix M.'''
    # By symmetry, we only need to call can_be_interwoven() for M's upper triangular part
    n = len(t)
    m = ro.zeros_bool_array(n, n)
    for i, ti in enumerate(t):
        for j in xrange(i, n):
            m[i][j] = can_be_interwoven(s, ti, t[j])
            m[j][i] = m[i][j]
    return m