Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can memoization be applied to this algorithm?
    primarykey
    data
    text
    <p>After finding the <code>difflib.SequenceMatcher</code> class in Python's standard library to be unsuitable for my needs, a generic "diff"-ing module was written to solve a problem space. After having several months to think more about what it is doing, the recursive algorithm appears to be searching more than in needs to by re-searching the same areas in a sequence that a separate "search thread" may have also examined.</p> <p>The purpose of the <code>diff</code> module is to compute the difference and similarities between a pair of sequences (list, tuple, string, bytes, bytearray, et cetera). The initial version was much slower than the code's current form, having seen a speed increase by a factor of ten. How can memoization be applied to the following code? What is the best way to rewrite the algorithm to further increase any possible speed?</p> <hr> <pre><code>class Slice: __slots__ = 'prefix', 'root', 'suffix' def __init__(self, prefix, root, suffix): self.prefix = prefix self.root = root self.suffix = suffix ################################################################################ class Match: __slots__ = 'a', 'b', 'prefix', 'suffix', 'value' def __init__(self, a, b, prefix, suffix, value): self.a = a self.b = b self.prefix = prefix self.suffix = suffix self.value = value ################################################################################ class Tree: __slots__ = 'nodes', 'index', 'value' def __init__(self, nodes, index, value): self.nodes = nodes self.index = index self.value = value ################################################################################ def search(a, b): # Initialize startup variables. nodes, index = [], [] a_size, b_size = len(a), len(b) # Begin to slice the sequences. for size in range(min(a_size, b_size), 0, -1): for a_addr in range(a_size - size + 1): # Slice "a" at address and end. a_term = a_addr + size a_root = a[a_addr:a_term] for b_addr in range(b_size - size + 1): # Slice "b" at address and end. b_term = b_addr + size b_root = b[b_addr:b_term] # Find out if slices are equal. if a_root == b_root: # Create prefix tree to search. a_pref, b_pref = a[:a_addr], b[:b_addr] p_tree = search(a_pref, b_pref) # Create suffix tree to search. a_suff, b_suff = a[a_term:], b[b_term:] s_tree = search(a_suff, b_suff) # Make completed slice objects. a_slic = Slice(a_pref, a_root, a_suff) b_slic = Slice(b_pref, b_root, b_suff) # Finish the match calculation. value = size + p_tree.value + s_tree.value match = Match(a_slic, b_slic, p_tree, s_tree, value) # Append results to tree lists. nodes.append(match) index.append(value) # Return largest matches found. if nodes: return Tree(nodes, index, max(index)) # Give caller null tree object. return Tree(nodes, index, 0) </code></pre> <hr> <p><strong>Reference:</strong> <a href="https://stackoverflow.com/questions/3220433">How to optimize a recursive algorithm to not repeat itself?</a></p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload