Exemplo n.º 1
0
def fib_table(output=True, decimals=3):
    """Generate table showing reduced recursive invocations of fibonacci."""
    import math

    tbl = DataTable([8, 12, 12], ['N', 'FiRec', 'Model'],
                    output=output,
                    decimals=decimals)
    tbl.format('FiRec', 'd')

    def exp_model(n, a, b):
        """Formula for A*N^B ."""
        return a * math.pow(n, b)

    for n in range(3, 100):
        old = numRecursiveImproved[0]
        fib_with_lucas(n)
        model = exp_model(n, 0.28711343, 2.58031481)
        tbl.row([n, (numRecursiveImproved[0] - old), model])

    if numpy_error:
        pass
    else:
        import numpy as np
        from scipy.optimize import curve_fit

        x_arr = np.array(tbl.column(tbl.labels[0]))
        y_arr = np.array(tbl.column(tbl.labels[1]))

        def np_exp_model(n, a, b):
            """Formula for A*N^B ."""
            return a * np.power(n, b)

        if output:
            [exp_coeffs, _] = curve_fit(np_exp_model, x_arr, y_arr)
            print('A*N^B  = {:.12f}*N^{:f} '.format(exp_coeffs[0],
                                                    exp_coeffs[1]))

    return tbl
Exemplo n.º 2
0
    def test_table(self):
        tbl = DataTable([8, 8, 8], ['N', 'Another', 'SquareRoot'],
                        output=False,
                        decimals=4)
        tbl.format('Another', 'd')
        for n in range(2, 10):
            tbl.row([n, n, n**0.5])
        self.assertEqual(tbl.entry(3, 'Another'), 3)

        print('Testing that Table is print to console')
        tbl = DataTable([8, 8, 8], ['N', 'Another', 'SquareRoot'], decimals=4)
        tbl.format('Another', 'd')
        for n in range(2, 10):
            tbl.row([n, n, n**0.5])

        self.assertEqual(list(range(2, 10)), tbl.column('Another'))

        model = tbl.best_model('Another')[0]
        if numpy_error:
            pass
        else:
            self.assertEqual(model[0], Model.LINEAR)
            self.assertAlmostEqual(model[3], 1.0000, places=5)
Exemplo n.º 3
0
    def test_allpairs_sp(self):
        from ch07.all_pairs_sp import floyd_warshall, all_pairs_path_to
        G = nx.Graph()
        G.add_edge('a', 'b', weight=3)
        G.add_edge('a', 'c', weight=5)
        G.add_edge('b', 'c', weight=9)
        G.add_edge('b', 'd', weight=2)
        G.add_edge('d', 'c', weight=1)
        G.add_edge('e', 'f', weight=1)  # separate and disconnected edge...
        (dist_to, node_from) = floyd_warshall(G)
        path = all_pairs_path_to(node_from, 'b', 'c')
        self.assertEqual(3, dist_to['b']['c'])
        self.assertEqual(['b', 'd', 'c'], path)

        path = all_pairs_path_to(node_from, 'a', 'd')
        self.assertEqual(5, dist_to['a']['d'])
        self.assertEqual(['a', 'b', 'd'], path)

        with self.assertRaises(ValueError):
            all_pairs_path_to(node_from, 'a', 'e')

        tbl = DataTable([6, 6, 6, 6, 6], ['.', 'a', 'b', 'c', 'd'],
                        output=False)
        tbl.format('.', 's')
        for f in 'abcd':
            tbl.format(f, 's')
        for u in 'abcd':
            row = [u]
            for v in 'abcd':
                if node_from[u][v]:
                    row.append(node_from[u][v])
                else:
                    row.append(SKIP)
            tbl.row(row)

        self.assertEqual('d', tbl.entry('b', 'c'))
Exemplo n.º 4
0
def time_results_open_addressing(num_rows=0, output=True, decimals=3):
    """Average time to insert a key in growing hashtable_open (in microseconds)."""
    sizes = [8192, 16384, 32768, 65536, 131072, 262144, 524288, 1048576]
    headers = [comma(s) for s in sizes]
    headers.insert(0,'N')
    tbl = DataTable([8,8,8,8,8,8,8,8,10], headers, output=output, decimals=decimals)

    # Now start with M words to be added into a table of size N.
    # Start at 1000 and work up to 2000
    for num_to_add in [32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768]:
        all_words = english_words()[:num_to_add]

        line = [len(all_words)]
        for size in sizes:
            try:
                tbl.format(comma(size), '.3f')
                timing = min(timeit.repeat(stmt='''
table = Hashtable({})
for word in all_words:
    table.put(word, 99)'''.format(size), setup='''
from ch03.hashtable_open import Hashtable
from resources.english import english_words
all_words=english_words()[:{}]'''.format(num_to_add),repeat=1,number=100))
                timing = (100000.0 * timing) / size
            except RuntimeError:
                timing = SKIP

            line.append(timing)
        num_rows -= 1
        tbl.row(line)

        # Provide effective way to terminate early for testing.
        if num_rows == 0:
            break

    return tbl
Exemplo n.º 5
0
def generate_hash():
    """Results are different each time since Python salts hash values."""

    s = 'a rose by any other name would smell as sweet'
    tbl = DataTable([8,20,20], ['key', 'hash(key)', 'hash(key) % 15'])
    tbl.format('key', 's')
    tbl.format('hash(key)', 'd')
    tbl.format('hash(key) % 15', 'd')
    for w in s.split():
        tbl.row([w, hash(w), hash(w) % 15])
    return tbl
Exemplo n.º 6
0
def growth_table(output=True):
    """Generate table for growth of different computations."""
    labels = ['N', 'log N', 'Linear', 'N log N', 'N^2', 'N^3', '2^N', 'N!']
    tbl = DataTable([15, 15, 15, 15, 15, 15, 15, 15], labels, output=output)
    for hdr in labels:
        tbl.format(hdr, ',d')

    def fact(n):
        try:
            return int(math.factorial(n))
        except ValueError:
            return float('inf')

    for n in [2**k for k in range(2, 12)]:
        fact_value = fact(n)
        if fact_value == float('inf'):
            fact_value = SKIP
        elif fact_value > 1e100:
            fact_value = SKIP
        elif fact_value > 1e8:
            tbl.format('N!', '.2e')

        exp_value = pow(2, n)
        if exp_value > 1e8:
            tbl.format('2^N', '.2e')
        if exp_value > 1e100:
            exp_value = SKIP

        cubic_value = n * n * n
        if cubic_value > 1e8:
            tbl.format('N^3', '.2e')

        tbl.row([
            n,
            int(math.log(n) / math.log(2)), n,
            int(n * math.log(n) / math.log(2)), n * n, cubic_value, exp_value,
            fact_value
        ])
    return tbl
Exemplo n.º 7
0
def count_hash(output=True, decimals=2):
    """
    For all English words, starting with a hashtable of size 1,024 and
    a load factor of 0.75, count how many times the hash code (i.e., %)
    is invoked.
    """
    from ch03.hashtable_linked import DynamicHashtable

    ht = DynamicHashtable(1023)
    tbl = DataTable([20,10,10,10,10],['Word', 'M', 'N', '#insert', 'average'],
                    output=output, decimals=decimals)
    tbl.format('Word', 's')
    tbl.format('N', ',d')
    tbl.format('M', ',d')
    tbl.format('#insert', ',d')

    last_word = None
    for w in english_words():
        last_word = w
        last_m = ht.M
        last = CountableHash.hash_count
        ht.put(CountableHash(w), w)
        if CountableHash.hash_count != last + 1:
            tbl.row([w, last_m, ht.N, CountableHash.hash_count, CountableHash.hash_count/ht.N])

    tbl.row([last_word, last_m, ht.N, CountableHash.hash_count, CountableHash.hash_count/ht.N])

    # determine when next resize event would occur...
    for i in range(1, 200000):
        last = CountableHash.hash_count
        last_m = ht.M
        ht.put(CountableHash(last_word + str(i)), last_word)
        if CountableHash.hash_count != last + 1:
            tbl.row([last_word + str(i), last_m, ht.N,
                     CountableHash.hash_count, CountableHash.hash_count/ht.N])
            break

    return tbl
Exemplo n.º 8
0
def iteration_order(output=True):
    """Generate iteration orders for multiple hashtable types."""

    s = 'a rose by any other name would smell as sweet'
    from ch03.hashtable_open import Hashtable as Open_Hashtable
    from ch03.hashtable_linked import Hashtable as Linked_Hashtable
    from ch03.hashtable_open_perfect import Hashtable as Perfect_Hashtable
    ht_oa = Open_Hashtable(13)
    ht_ll = Linked_Hashtable(13)
    ht_ph = Perfect_Hashtable()

    for w in s.split():
        ht_oa.put(w, w)
        ht_ll.put(w, w)
        ht_ph.put(w, w)

    tbl = DataTable([8,8,8], ['Open Addressing', 'Separate Chaining', 'Perfect Hash'],
                    output=output)
    tbl.format('Open Addressing', 's')
    tbl.format('Separate Chaining', 's')
    tbl.format('Perfect Hash', 's')
    for p_oa,p_ll,p_ph in zip(ht_oa, ht_ll, ht_ph):
        tbl.row([p_oa[0], p_ll[0], p_ph[0]])
    return tbl
Exemplo n.º 9
0
def measure_performance_resize(max_d=50, output=True):
    """Generate table of statistics for table resizing up to (but not including maxd=50)."""
    from ch03.hashtable_linked import DynamicHashtable

    try:
        # Added in Python 3.7
        from time import time_ns
        timing = time_ns
    except ImportError:
        from time import time
        timing = time

    if output:
        print('Dynamic Resizing Hashtable')
    tbl = DataTable([8, 15, 15, 10, 10],
                    ['idx', 'word', 'time', 'old-size', 'new-size'],
                    output=output,
                    decimals=2)
    tbl.format('idx', 'd')
    tbl.format('word', 's')
    tbl.format('old-size', ',d')
    tbl.format('new-size', ',d')

    ht = DynamicHashtable(1023)
    idx = 1
    last = None
    average = 0
    words = english_words()
    for w in words:
        before = timing()
        old_size = len(ht.table)
        ht.put(w, w)
        new_size = len(ht.table)
        after = timing()
        average += (after - before)
        if last:
            if after - before > last:
                last = after - before
                tbl.row([idx, w, last, old_size, new_size])
        else:
            last = after - before
        idx += 1

    average /= len(words)
    ht = None
    if output:
        print('Average was ', average)
        print('Incremental Resizing Hashtable')

    tbl_ir = DataTable([8, 15, 15, 10, 10],
                       ['idx', 'word', 'time', 'old-size', 'new-size'],
                       output=output,
                       decimals=2)
    tbl_ir.format('idx', 'd')
    tbl_ir.format('word', 's')
    tbl_ir.format('old-size', ',d')
    tbl_ir.format('new-size', ',d')
    ht = DynamicHashtableIncrementalResizing(1023, 10)
    idx = 1
    last = None
    average = 0
    words = english_words()
    for w in words:
        before = timing()
        old_size = len(ht.table)
        ht.put(w, w)
        new_size = len(ht.table)
        after = timing()
        average += (after - before)
        if last:
            if after - before > last:
                last = after - before
                tbl_ir.row([idx, w, last, old_size, new_size])
        else:
            last = after - before
        idx += 1

    ht = None

    average /= len(words)
    if output:
        print('Average was ', average)
        print('Incremental Resizing dependent on Delta')
        print()

    tbl_d = DataTable([8, 10], ['Delta', 'Average'], output=output)
    tbl_d.format('Delta', 'd')
    for delta in range(1, max_d):
        ht = DynamicHashtableIncrementalResizing(1023, delta)
        average = 0
        words = english_words()
        for w in words:
            before = timing()
            ht.put(w, w)
            after = timing()
            average += (after - before)

        average /= len(words)
        tbl_d.row([delta, average])

    return (tbl, tbl_ir, tbl_d)
Exemplo n.º 10
0
def compare_removes(output=True):
    """Run trials that create a Hashtable and then remove all entries."""
    build_time_oa = min(
        timeit.repeat(stmt='''
ht = HashtableOpenAddressingRemove(8)
for w in words:
    ht.put(w,w)''',
                      setup='''
from ch03.challenge import HashtableOpenAddressingRemove
from resources.english import english_words
words = english_words()[:20000]''',
                      repeat=5,
                      number=2)) / 2

    build_time_sc = min(
        timeit.repeat(stmt='''
ht = Hashtable(8)
for w in words:
    ht.put(w,w)''',
                      setup='''
from ch03.hashtable_linked import Hashtable
from resources.english import english_words
words = english_words()[:20000]''',
                      repeat=5,
                      number=2)) / 2

    delete_time_oa = min(
        timeit.repeat(stmt='''
for w in to_remove:
    ht.remove(w)
if ht.N != 0:
    raise RuntimeError("should have emptied")''',
                      setup='''
import random
from ch03.challenge import HashtableOpenAddressingRemove
from resources.english import english_words
words = english_words()[:20000]
ht = HashtableOpenAddressingRemove(8)
for w in words:
    ht.put(w,w)
to_remove = list(words)
random.shuffle(to_remove)''',
                      repeat=5,
                      number=2)) / 2

    delete_time_sc = min(
        timeit.repeat(stmt='''
for w in to_remove:
    ht.remove(w)
if ht.N != 0:
    raise RuntimeError("should have emptied")''',
                      setup='''
import random
from ch03.hashtable_linked import Hashtable
from resources.english import english_words
words = english_words()[:20000]
ht = Hashtable(8)
for w in words:
    ht.put(w,w)
to_remove = list(words)
random.shuffle(to_remove)''',
                      repeat=5,
                      number=2)) / 2

    tbl = DataTable([20, 8, 8], ['Hashtable Type', 'Build', 'Remove All'],
                    output=output)
    tbl.format('Hashtable Type', 's')
    tbl.row(['Open Addressing:', build_time_oa, delete_time_oa])
    tbl.row(['Separate Chaining:', build_time_sc, delete_time_sc])
    return tbl
Exemplo n.º 11
0
def compare_dynamic_build_and_access_time(repeat=10, num=5, max_m=640000, output=True):
    """Generate tables for build and access times for M up to (but not equal to) 640,000."""

    # sufficient to allow 321,129 and to spare (divide by 0.75 to get 428,172).
    SUFF=428172

    # When 'ht = HTLL(...) is inside the STMT, it measures BUILD TIME.
    # When it is included in the setup, we are measuring ACCESS TIME.
    ll_build = min(timeit.repeat(stmt='''
ht = HTLL({})
for w in words:
    ht.put(w,w)'''.format(SUFF), setup='''
from ch03.hashtable_linked import Hashtable as HTLL
from resources.english import english_words
words = english_words()''', repeat=repeat, number=num))/num

    ll_access = min(timeit.repeat(stmt='''
for w in words:
    ht.get(w)''', setup='''
from ch03.hashtable_linked import Hashtable as HTLL
from resources.english import english_words
ht = HTLL({})
words = english_words()
for w in words:
    ht.put(w,w)'''.format(SUFF), repeat=repeat, number=num))/num

    oa_build = min(timeit.repeat(stmt='''
ht = HTOA({})
for w in words:
    ht.put(w,w)'''.format(SUFF), setup='''
from ch03.hashtable_open import Hashtable as HTOA
from resources.english import english_words
words = english_words()''', repeat=repeat, number=num))/num

    oa_access = min(timeit.repeat(stmt='''
for w in words:
    ht.get(w)''', setup='''
from ch03.hashtable_open import Hashtable as HTOA
from resources.english import english_words
ht = HTOA({})
words = english_words()
for w in words:
    ht.put(w,w)'''.format(SUFF), repeat=repeat, number=num))/num

    tbl = DataTable([8,10,10,10,10],['M', 'BuildLL', 'AccessLL', 'BuildOA', 'AccessOA'],
                    output=output, decimals=3)

    M = 625
    while M <= max_m:
        t1_build = min(timeit.repeat(stmt='''
ht = DHL({})
for w in words:
    ht.put(w,w)'''.format(M), setup='''
from ch03.hashtable_linked import DynamicHashtable as DHL
from resources.english import english_words
words = english_words()''', repeat=repeat, number=num))/num

        t1_access = min(timeit.repeat(stmt='''
for w in words:
    ht.get(w)''', setup='''
from ch03.hashtable_linked import DynamicHashtable as DHL
from resources.english import english_words
ht = DHL({})
words = english_words()
for w in words:
    ht.put(w,w)'''.format(M), repeat=repeat, number=num))/num

        t2_build = min(timeit.repeat(stmt='''
ht = DHL({})
for w in words:
    ht.put(w,w)'''.format(M), setup='''
from ch03.hashtable_open import DynamicHashtable as DHL
from resources.english import english_words
words = english_words()''', repeat=repeat, number=num))/num

        t2_access = min(timeit.repeat(stmt='''
for w in words:
    ht.get(w)''', setup='''
from ch03.hashtable_open import DynamicHashtable as DHL
from resources.english import english_words
ht = DHL({})
words = english_words()
for w in words:
    ht.put(w,w)'''.format(M), repeat=repeat, number=num))/num

        tbl.row([M, t1_build, t1_access, t2_build, t2_access])
        M = M * 2

    tbl.format('M', 's')
    tbl.row(['Fixed', ll_build, ll_access, oa_build, oa_access])
    return tbl
Exemplo n.º 12
0
def trial_multiple_rotations(output=True, num_attempts=10000):
    """Some trial and error went into these ranges."""
    from ch05.challenge import fib
    tbl = DataTable([6, 6, 6, 6], ['NumRot', 'Height', 'N', 'Random Tree'],
                    output=output)
    tbl.format('Random Tree', 's')
    tbl.format('NumRot', 'd')
    tbl.format('Height', 'd')
    tbl.format('N', 'd')

    for extra in range(3):
        (structure, _) = find_multiple_rotations(extra,
                                                 lo=4,
                                                 hi=40,
                                                 num_attempts=num_attempts,
                                                 output=False)
        n = recreate_tree(structure)

        def count_nodes(n):
            if n is None: return 0
            return 1 + count_nodes(n.left) + count_nodes(n.right)

        tbl.row([extra + 1, n.height, count_nodes(n), structure])

    # Now use Fibonacci Trees to accomplish the same result.
    if output:
        print()
    tbl = DataTable([6, 6, 6, 13], ['NumRot', 'Height', 'N', 'Fib AVL Trees'],
                    output=output)
    tbl.format('Fib AVL Trees', 's')
    tbl.format('NumRot', 'd')
    tbl.format('Height', 'd')
    tbl.format('N', 'd')
    for n in range(6, 14, 2):
        root = fibonacci_avl(n)
        root.compute_height()
        check_avl_property(root)  # double-check
        structure = tree_structure(root)
        bt = ObservableBinaryTree()
        height = root.height
        bt.root = root
        count = count_nodes(root)

        num_rotations = rotations[0]
        to_delete = fib(n + 1) - 1
        bt.remove(to_delete)
        check_avl_property(bt.root)
        num_rotations = rotations[0] - num_rotations

        tbl.row([num_rotations, height, count, structure])

    return tbl