def generate_ch06(): """Generate Tables and Figures for chapter 06.""" chapter = 6 with FigureNum(1) as figure_number: description = 'Representing mathematical expressions using expression trees' label = caption(chapter, figure_number) mult7 = expression_tree() print(mult7, '=', mult7.eval()) print('in postfix:', ' '.join(str(k) for k in mult7.postfix())) print('{}. {}'.format(label, description)) print() with FigureNum(2) as figure_number: description = 'Visualizing recursive evaluation of ((1+5)*9)' label = caption(chapter, figure_number) mult2 = debug_expression() print(mult2, '=', mult2.eval()) print('{}. {}'.format(label, description)) print() with TableNum(1) as table_number: process( generate_list_table(), chapter, table_number, 'Comparing insert and remove performance of lists against binary search tree (time in ms)', yaxis="Time (in ms)") with FigureNum(3) as figure_number: description = 'Binary Search Tree containing seven values' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with TableNum(2) as table_number: description = 'Creating a binary search tree by inserting (in order) 19,14,15,53,58,3,26' speaking_tree() label = caption(chapter, table_number) print('{}. {}'.format(label, description)) print() with FigureNum(4) as figure_number: description = 'Insert 29 into the binary search tree example' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(5) as figure_number: description = 'Different binary search trees when same values are inserted in different order' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(6) as figure_number: description = 'Two possible binary search trees after removing 19 from Figure 6-4' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(7) as figure_number: description = 'Removing minimum value in a subtree' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with TableNum(3) as table_number: description = 'Demonstrating how node is removed from binary search tree' label = caption(chapter, table_number) print('{}. {}'.format(label, description)) print() with FigureNum(8) as figure_number: description = 'Iterating over the values in a binary search tree in ascending order' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(9) as figure_number: description = 'A complete binary tree stores the most values with the least height' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(10) as figure_number: description = 'Unbalanced tree after two insertions.' label = caption(chapter, figure_number) show_unbalanced_result() print('{}. {}'.format(label, description)) print() with FigureNum(11) as figure_number: description = 'Recursive invocation when inserting a value.' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(12) as figure_number: description = 'Rebalancing this binary search tree by rotating the root node to the right' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(13) as figure_number: description = 'Four different node rotations' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with TableNum(4) as table_number: description = 'Implementation of rotate left-right' label = caption(chapter, table_number) print('{}. {}'.format(label, description)) print() with FigureNum(14) as figure_number: description = 'Binary search tree as symbol table: keys are atomic numbers; values are element names' label = caption(chapter, figure_number) sample_binary_tree_as_symbol() print('{}. {}'.format(label, description)) print() with FigureNum(15) as figure_number: description = 'Binary search tree as priority queue: priorities are atomic numbers; values are element names' label = caption(chapter, figure_number) sample_binary_tree_as_pq() print('{}. {}'.format(label, description)) print() with FigureNum(16) as figure_number: description = 'A Fibonacci tree with twelve nodes' label = caption(chapter, figure_number) fibonacci_tree_sample() print('{}. {}'.format(label, description)) print()
def generate_ch04(): """Generate tables/figures for chapter 04.""" chapter = 4 with FigureNum(1) as figure_number: description = 'Waiting in a queue at a nightclub' label = caption(chapter, figure_number) print('Redrawn by artist') print('{}. {}'.format(label, description)) print() with FigureNum(2) as figure_number: description = 'modeling a nightclub queue with three nodes' label = caption(chapter, figure_number) print('Redrawn by artist') print('{}. {}'.format(label, description)) print() with FigureNum(3) as figure_number: description = 'Patrons can advance quicker with a purchased pass' label = caption(chapter, figure_number) print('Redrawn by artist') print('{}. {}'.format(label, description)) print() # For full book output, remove "max_n=16384". Added to reduce time to generate all. with TableNum(1) as table_number: process(average_performance(max_n=16384), chapter, table_number, 'Average operation performance (time in ns) on problem instances of size N', yaxis='Time (in nanoseconds)') with FigureNum(4) as figure_number: description = 'O(log N) behavior of Heap outperforms O(N) behavior for other approaches' label = caption(chapter, figure_number) print('Generated by Excel') print('{}. {}'.format(label, description)) print() with FigureNum(5) as figure_number: description = 'A sample max binary heap' label = caption(chapter, figure_number) heap = initial_heap() output_heap(heap) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(6) as figure_number: description = 'Determining levels needed for a binary heap with N entries' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(7) as figure_number: description = 'Which of these are valid binary max heaps?' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(8) as figure_number: description = 'The first step to inserting an entry is to place it in the next available position' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(9) as figure_number: description = 'The second step is to swim the entry up one level as needed' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(10) as figure_number: description = 'Third step swims the entry up one level as needed' label = caption(chapter, figure_number) heap2 = initial_heap() heap2.enqueue(12, 12) output_heap(heap2) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(11) as figure_number: description = 'Adding an entry with priority 16 swims up to the top' label = caption(chapter, figure_number) heap3 = initial_heap() heap3.enqueue(12, 12) heap3.enqueue(16, 16) output_heap(heap3) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(12) as figure_number: description = 'The first step is to remove bottommost entry' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(13) as figure_number: description = 'Broken heap resulting from swapping last entry with level 0' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(14) as figure_number: description = 'Swap top entry with its left child which had a higher priority' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(15) as figure_number: description = 'Sink down an additional level' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(16) as figure_number: description = 'Resulting heap after sinking entry to its proper location' label = caption(chapter, figure_number) heap4 = initial_heap() heap4.enqueue(12, 12) heap4.enqueue(16, 16) heap4.dequeue() output_heap(heap4) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(17) as figure_number: description = 'Storing a max binary heap in an array' label = caption(chapter, figure_number) heap4 = initial_heap() heap4.enqueue(12, 12) print(' -- |' + '|'.join([' {:>3} '.format(e.priority) for e in heap4.storage[1:heap4.N+1]])) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(18) as figure_number: description = 'Changes to storage after enqueue in Figure 4-8' label = caption(chapter, figure_number) heap_enqueue_animation() print('{}. {}'.format(label, description)) print() with FigureNum(19) as figure_number: description = 'Changes to storage after dequeue in Figure 4-11' label = caption(chapter, figure_number) heap_dequeue_animation() print('{}. {}'.format(label, description)) print() with FigureNum(20) as figure_number: description = 'Using an array as a circular queue' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print() with FigureNum(21) as figure_number: description = 'A novel factorial heap structure' label = caption(chapter, figure_number) print('Hand drawn') print('{}. {}'.format(label, description)) print()
def generate_ch05(): """Generate Tables and Figures for chapter 05.""" chapter = 5 with FigureNum(1) as figure_number: description = 'Sample array, A, to sort' label = caption(chapter, figure_number) A = [15, 21, 20, 2, 15, 24, 5, 19] print('|'.join([' {:>2} '.format(k) for k in A])) moves = [(0,3),(5,7),(1,6),None,(2,4),None,(4,5)] for m in moves: if m: A[m[0]],A[m[1]] = A[m[1]],A[m[0]] print('|'.join([' {:>2} '.format(k) for k in A])) print('{}. {}'.format(label, description)) print() with FigureNum(2) as figure_number: description = 'Sorting sample array using Selection Sort' label = caption(chapter, figure_number) A = [15, 21, 20, 2, 15, 24, 5, 19] print('|'.join([' {:>2} '.format(k) for k in A])) moves = [(0,3),(1,6),(2,3),(3,4),(4,7),(5,7),(6,6)] for m in moves: if m: A[m[0]],A[m[1]] = A[m[1]],A[m[0]] print('|'.join([' {:>2} '.format(k) for k in A])) print('{}. {}'.format(label, description)) print() with FigureNum(3) as figure_number: description = 'Visualizing the formula for triangle numbers: sum of 1 through 7 is 28' label = caption(chapter, figure_number) print('By hand') print('{}. {}'.format(label, description)) print() with FigureNum(4) as figure_number: description = 'Sorting sample array using Insertion Sort' label = caption(chapter, figure_number) A = [15, 21, 20, 2, 15, 24, 5, 19] print('|'.join([' {:>2} '.format(k) for k in A])) moves = [None,[(2,1)], [(3,2),(2,1),(1,0)], [(4,3),(3,2)], None, [(6,5),(5,4),(4,3),(3,2),(2,1)],[(7,6),(6,5),(5,4)]] for p in moves: if p: for m in p: A[m[0]],A[m[1]] = A[m[1]],A[m[0]] print('|'.join([' {:>2} '.format(k) for k in A])) print('{}. {}'.format(label, description)) print() with FigureNum(5) as figure_number: # for actual results from book, use max_k=18 as an argument, but it will take hours. timing_selection_insertion() description = 'Timing results of Insertion Sort and Selection Sort' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(6) as figure_number: description = 'Visualizing the recursive invocation of fact(3)' label = caption(chapter, figure_number) print('Fact(3) = ', fact(3)) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(7) as figure_number: description = 'Recursive invocation when calling rmax(0,3) on A=[15,21,20,2]' label = caption(chapter, figure_number) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(8) as figure_number: description = 'Complete recursive invocation of rmax(0,7)' label = caption(chapter, figure_number) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(9) as figure_number: description = 'Merging two stacks into one' label = caption(chapter, figure_number) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(10) as figure_number: description = 'Step by step merge sort of two sorted sub-arrays of size 4' label = caption(chapter, figure_number) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(11) as figure_number: show_partition() description = 'Results of partition(A,0,7,0) using A[0] as pivot' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(12) as figure_number: description = 'Full recursive invocation of Quicksort' label = caption(chapter, figure_number) print('Done by hand') print('{}. {}'.format(label, description)) print() with FigureNum(13) as figure_number: heapsort_intuition() description = 'Intuition behind how a max binary heap can be used for sorting' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(14) as figure_number: show_heapify() description = 'Converting array into a max binary heap' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with TableNum(1) as table_number: timing_nlogn_sorting() description = 'Runtime performance (in seconds) for different sorting algorithms' label = caption(chapter, table_number) print('{}. {}'.format(label, description)) print() with FigureNum(15) as figure_number: tim_sort_figure() description = 'Changes to array when applying Tim Sort with initial size of 4' label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print()
def generate_ch01(): """Generate Tables and Figures for chapter 01.""" chapter = 1 with FigureNum(1) as figure_number: pi1 = [13, 2, 18, 7, 50] pi2 = [-19, -236, -17, -204, -97, -20, -928, -454, -92, -19] pi3 = list(range(1, 1000001)) print(pi1, '->', max(pi1)) print(pi2, '->', max(pi2)) print(pi3[:5] + ['...'] + pi3[-3:], '->', max(pi3)) print(caption(chapter, figure_number), 'Three different problem instances processed by an algorithm') print() with TableNum(1) as table_number: process( run_init_trial(), chapter, table_number, 'Executing max() on two kinds of problem instances of size N (time in ms)', yaxis='Time (in ms)') with FigureNum(2) as figure_number: visualize_flawed([1, 5, 2, 9, 3, 4]) print(caption(chapter, figure_number), 'Visualizing the execution of flawed()') with FigureNum(3) as figure_number: visualize_alternate([1, 5, 2, 9, 3, 4]) print(caption(chapter, figure_number), 'Visualizing the execution of alternate()') with FigureNum(4) as figure_number: visualize_alternate([9, 5, 2, 1, 3, 4]) visualize_alternate([1, 2, 3, 4, 5, 9]) print( caption(chapter, figure_number), 'Visualizing the execution of alternate() on best and worst cases') # TODO: Option for secondary axis specification with TableNum(2) as table_number: process( run_largest_alternate(), chapter, table_number, 'Comparing largest() with alternate() on worst case problem instances' ) # Take results and plot #LessA on left-axis as line, and TimesA on right axis as column with FigureNum(5) as figure_number: print(caption(chapter, figure_number), 'Relationship between #Less-Than and runtime performance') with TableNum(3) as table_number: process(run_best_worst(), chapter, table_number, 'Performance of largest() and max() on best and worst cases') with TableNum(4) as table_number: process( performance_different_approaches(), chapter, table_number, 'Performance of different approached on 524,288 values in different orders', create_image=False) with FigureNum(6) as figure_number: print('by hand') print(caption(chapter, figure_number), 'A tournament with eight initial values') with FigureNum(7) as figure_number: print('by hand') print(caption(chapter, figure_number), 'A tournament with 32 values') with FigureNum(8) as figure_number: visualize_tournament_two([3, 1, 4, 1, 5, 9, 2, 6]) print(caption(chapter, figure_number), 'Step-by-step execution of tournament algorithm') with TableNum(5) as table_number: process(run_largest_two_trials(Order.SHUFFLED), chapter, table_number, 'Comparing runtime performance (in ms) of all four algorithms', yaxis='Time (in ms)') # Taken from table with FigureNum(9) as figure_number: print(caption(chapter, figure_number), 'Runtime performance comparison') with TableNum(6) as table_number: process(count_operations(), chapter, table_number, 'Counting operations in four different functions', yaxis='Number of times ct is incremented')
def generate_ch03(): """Generate Tables and Figures for chapter 03.""" chapter = 3 # Starts without a formal figure number from ch03.months import print_month print_month('February', 2024) with FigureNum(1) as figure_number: description = 'Array containing month lengths interspersed with unneeded -1 values' label = caption(chapter, figure_number) (_, day_array) = search_for_base() print('day_array =', day_array) print('{}. {}'.format(label, description)) print() with TableNum(1) as table_number: process(generate_hash(), chapter, table_number, 'Example hash() and hash code expressions for a table of size 15 (because of salting will be different from book)', create_image=False) with FigureNum(2) as figure_number: description = 'Structure of Hashtable storage after adding five (key, value) entries' label = caption(chapter, figure_number) sample_hashtable() print('{}. {}'.format(label, description)) print() with TableNum(2) as table_number: process(time_results_open_addressing(), chapter, table_number, 'Average performance to insert N keys into a Hashtable of size M (in milliseconds)', yaxis='Time (in microseconds)') with FigureNum(3) as figure_number: description = 'Structure of Hashtable linked list storage after adding five (key, value) pairs' label = caption(chapter, figure_number) sample_separate_chaining_hashtable() print('{}. {}'.format(label, description)) print() with FigureNum(4) as figure_number: description = 'Removing the first node in a linked list' label = caption(chapter, figure_number) print('hand-drawn image') print('{}. {}'.format(label, description)) print() with FigureNum(5) as figure_number: description = 'Removing any other node in a linked list' label = caption(chapter, figure_number) print('hand-drawn image') print('{}. {}'.format(label, description)) print() with TableNum(3) as table_number: process(count_collisions(), chapter, table_number, 'Average performance when inserting N=321,129 keys into a Hashtable of size M as M decreases in size') with FigureNum(6) as figure_number: description = 'For a fixed number of elements, N, the average and maximum chain length follow predictable paths' label = caption(chapter, figure_number) print('The result of plotting Table 3-3') print('{}. {}'.format(label, description)) print() with FigureNum(7) as figure_number: description = 'Some entries can get "lost" if they are simply copied when M increases' label = caption(chapter, figure_number) sample_hashtable() sample_separate_chaining_hashtable() print('The above are original before resize.') print('{}. {}'.format(label, description)) print() with FigureNum(8) as figure_number: description = 'Resulting Hashtable storage after successful resizing' label = caption(chapter, figure_number) sample_hashtable_resize() sample_separate_chaining_hashtable_resize() print('The above are original before resize.') print('{}. {}'.format(label, description)) print() print('The following table takes hours to generate. Remove arguments for full table shown in book.') with TableNum(4) as table_number: process(compare_dynamic_build_and_access_time(repeat=1, num=5), chapter, table_number, 'Comparing growing tables against fixed-size construction', yaxis = 'Time (in ms)') with TableNum(5) as table_number: process(count_hash(), chapter, table_number, 'Words whose addition causes a resize event, with total # of insertions and average number of times a word was inserted') print('Additional computations for perfect hashing for shakespeare example') perfect_shakespeare_trial('a') perfect_shakespeare_trial('by') print('Additional computations for perfect hashing') perfect_trial('by') perfect_trial('watered') perfect_trial('not-a-word') with TableNum(6) as table_number: process(iteration_order(), chapter, table_number, 'Order of words returned by hashtable iterators', create_image = False)
def generate_ch07(): """Generate Tables and Figures for chapter 07.""" chapter = 7 with FigureNum(23) as figure_number: description = 'Initialize dist_to[][] and node_from[][] based on G' label = caption(chapter, figure_number) DG_TABLE = nx.DiGraph() DG_TABLE.add_edge('a', 'b', weight=4) DG_TABLE.add_edge('b', 'a', weight=2) DG_TABLE.add_edge('a', 'c', weight=3) DG_TABLE.add_edge('b', 'd', weight=5) DG_TABLE.add_edge('c', 'b', weight=6) DG_TABLE.add_edge('d', 'b', weight=1) DG_TABLE.add_edge('d', 'c', weight=7) visualize_results_floyd_warshall_just_initialize(DG_TABLE) print('{}. {}'.format(label, description)) print() with FigureNum(24) as figure_number: description = 'Changes to node_from[][] and dist_to[][] after k processes a and b' label = caption(chapter, figure_number) DG_TABLE = nx.DiGraph() DG_TABLE.add_edge('a', 'b', weight=4) DG_TABLE.add_edge('b', 'a', weight=2) DG_TABLE.add_edge('a', 'c', weight=3) DG_TABLE.add_edge('b', 'd', weight=5) DG_TABLE.add_edge('c', 'b', weight=6) DG_TABLE.add_edge('d', 'b', weight=1) DG_TABLE.add_edge('d', 'c', weight=7) visualize_results_floyd_warshall_two_steps(DG_TABLE) print('{}. {}'.format(label, description)) print() with FigureNum(1) as figure_number: description = 'Modeling different problems using graphs' print('by hand') label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(2) as figure_number: description = 'An undirected graph of 12 vertices and 12 edges' make_sample_graph() label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(3) as figure_number: description = 'A graph modeling a rectangular maze' label = caption(chapter, figure_number) from ch07.viewer import Viewer random.seed(15) m = Maze(3, 5) g = to_networkx(m) postscript_output = '{}-graph.ps'.format(label) if tkinter_error: print('unable to generate {}'.format(postscript_output)) else: root = tkinter.Tk() canvas = Viewer(m, 50).view(root) tkinter_register_snapshot(root, canvas, postscript_output) root.mainloop() # For obscure reasons, this must come AFTER root.mainloop() if plt_error: pass else: import matplotlib.pyplot as plt pos = nx.get_node_attributes(g, 'pos') nx.draw(g, pos, with_labels=True, node_color='w', font_size=8) output_file = image_file('{}-graph.svg'.format(label)) plt.savefig(output_file, format="svg") print('created {}'.format(output_file)) print('{}. {}'.format(label, description)) print() with FigureNum(4) as figure_number: description = 'Hitting a dead end while exploring a maze' print('Hand drawn overlay to Figure 7-2.') label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(5) as figure_number: from ch07.search import dfs_search, draw_solution description = 'Depth First Search locates target if reachable from source' label = caption(chapter, figure_number) random.seed(15) m = Maze(3, 5) graph = to_networkx(m) if plt_error: print('unable to draw graph') else: draw_solution(graph, dfs_search(graph, m.start()), m.start(), m.end()) output_file = image_file('{}-graph.svg'.format(label)) plt.savefig(output_file, format="svg") print('created {}'.format(output_file)) print('{}. {}'.format(label, description)) print() with FigureNum(6) as figure_number: description = 'Breadth First Search will locate shortest path to target, if reachable from source' print('Hand drawn overlay to Figure 7-2.') label = caption(chapter, figure_number) print('{}. {}'.format(label, description)) print() with FigureNum(7) as figure_number: description = 'Breadth First Search finds shortest path to each node' label = caption(chapter, figure_number) random.seed(15) m = Maze(3, 5) graph = to_networkx(m) if plt_error: print('unable to draw graph') else: draw_solution(graph, bfs_search(graph, m.start()), m.start(), m.end()) output_file = image_file('{}-graph.svg'.format(label)) plt.savefig(output_file, format="svg") print('created {}'.format(output_file)) print('{}. {}'.format(label, description)) print() with FigureNum(8) as figure_number: description = 'Comparing Depth First Search, Breadth First Search, and Guided Search' label = caption(chapter, figure_number) from ch07.solver_bfs import BreadthFirstSearchSolver from ch07.solver_dfs import DepthFirstSearchSolver from ch07.solver_guided import GuidedSearchSolver random.seed(15) m = Maze(13, 13) if tkinter_error: print('unable to generate {}'.format(postscript_output)) else: root = tkinter.Tk() bfs = BreadthFirstSearchSolver(root, m, 15, refresh_rate=0, stop_end=True) tkinter_register_snapshot(root, bfs.canvas, '{}-BFS.ps'.format(label)) root.mainloop() root = tkinter.Tk() dfs = DepthFirstSearchSolver(root, m, 15, refresh_rate=0, stop_end=True) tkinter_register_snapshot(root, dfs.canvas, '{}-DFS.ps'.format(label)) root.mainloop() root = tkinter.Tk() sfs = GuidedSearchSolver(root, m, 15, refresh_rate=0, stop_end=True) tkinter_register_snapshot(root, sfs.canvas, '{}-Guided.ps'.format(label)) root.mainloop() print( 'Generated BFS, DFS and Guided Postscript files for {}'.format( label)) print('{}. {}'.format(label, description)) print() with FigureNum(9) as figure_number: description = 'Adjacency Matrix vs. Adjacency List representation' label = caption(chapter, figure_number) output_adjacency_matrix() output_adjacency_list() print('{}. {}'.format(label, description)) print() with FigureNum(10) as figure_number: description = 'Sample directed graph with 12 nodes and 14 edges.' label = caption(chapter, figure_number) make_sample_directed_graph() print('{}. {}'.format(label, description)) print() with FigureNum(11) as figure_number: description = 'Sample spreadsheet with underlying directed graph.' label = caption(chapter, figure_number) print('Screen shots from Excel, together with graph from Figure 7-9') print('{}. {}'.format(label, description)) print() with FigureNum(12) as figure_number: description = 'Visualizing execution of Depth First Search for Cycle Detection.' label = caption(chapter, figure_number) print('Done by hand.') print('{}. {}'.format(label, description)) print() # In-text linear ordering print_sample_linear_ordering() print('Linear ordering of spreadsheet cells after Figure 12.') print() with FigureNum(13) as figure_number: description = 'Visualizing execution of Depth First Search for Topological Sort.' label = caption(chapter, figure_number) print('Done by hand.') print('{}. {}'.format(label, description)) print() with FigureNum(14) as figure_number: description = 'Modeling highway infrastructure in Massachusetts.' label = caption(chapter, figure_number) (_, mapPositions, _) = tmg_load(highway_map()) (_, EAST, _, WEST) = bounding_ids(mapPositions) output_file = generate_bfs_and_dijkstra_figure(WEST, EAST) print('Generated {}'.format(output_file)) print('Augmented by hand in SVG') print('{}. {}'.format(label, description)) print() with FigureNum(15) as figure_number: description = 'Modeling highway infrastructure in Massachusetts.' label = caption(chapter, figure_number) (_, mapPositions, _) = tmg_load(highway_map()) (_, EAST, _, WEST) = bounding_ids(mapPositions) output_file = generate_dfs_figure(WEST, EAST) print('Generated {}'.format(output_file)) print('Augmented by hand in SVG') print('{}. {}'.format(label, description)) print() with FigureNum(16) as figure_number: description = 'The shortest path from a to c has accumulated total of 8' label = caption(chapter, figure_number) print('Done by hand.') print('{}. {}'.format(label, description)) print() with FigureNum(17) as figure_number: description = "Executing Dijkstra's algorithm on small graph" label = caption(chapter, figure_number) DG_GOOD = nx.DiGraph() DG_GOOD.add_edge('a', 'b', weight=3) DG_GOOD.add_edge('a', 'c', weight=9) DG_GOOD.add_edge('b', 'c', weight=4) DG_GOOD.add_edge('b', 'd', weight=2) DG_GOOD.add_edge('d', 'c', weight=1) visualize_dijkstra_small_graph(DG_GOOD) print('{}. {}'.format(label, description)) print() with FigureNum(18) as figure_number: description = "A negative edge weight in the wrong place breaks Dijkstra's algorithm" label = caption(chapter, figure_number) DG_GOOD = nx.DiGraph() DG_GOOD.add_edge('a', 'b', weight=3) DG_GOOD.add_edge('a', 'c', weight=1) DG_GOOD.add_edge('b', 'd', weight=-2) # THIS BREAKS IT DG_GOOD.add_edge('c', 'd', weight=1) try: visualize_dijkstra_small_graph(DG_GOOD) print('WARNING: ValueError should have occurred! WARNING WARNING!') except ValueError: print('Unable to relax from final "b" node') print('{}. {}'.format(label, description)) print() with FigureNum(19) as figure_number: description = 'Two graphs with negative edge weights, but only one has a negative cycle' label = caption(chapter, figure_number) DG_GOOD = nx.DiGraph() DG_GOOD.add_edge('a', 'b', weight=1) DG_GOOD.add_edge('b', 'd', weight=-3) DG_GOOD.add_edge('d', 'c', weight=5) DG_GOOD.add_edge('c', 'b', weight=-1) (dist_to, _) = bellman_ford(DG_GOOD, 'a') print('Good Graph: shortest distance from a to b is {}'.format( dist_to['b'])) DG_BAD = nx.DiGraph() DG_BAD.add_edge('a', 'b', weight=1) DG_BAD.add_edge('b', 'd', weight=-3) DG_BAD.add_edge('d', 'c', weight=5) DG_BAD.add_edge('c', 'b', weight=-4) try: (dist_to, _) = bellman_ford(DG_BAD, 'a') print( 'WARNING: RuntimeError should have occurred! WARNING WARNING!') except RuntimeError: print('Bad Graph: Negative cycle exists in the graph.') print('Done by hand.') print('{}. {}'.format(label, description)) print() with FigureNum(20) as figure_number: description = 'Example for all-pairs shortest path problem' label = caption(chapter, figure_number) DG_AP = nx.DiGraph() DG_AP.add_edge('a', 'b', weight=4) DG_AP.add_edge('b', 'a', weight=2) DG_AP.add_edge('a', 'c', weight=3) DG_AP.add_edge('b', 'd', weight=5) DG_AP.add_edge('c', 'b', weight=6) DG_AP.add_edge('d', 'b', weight=1) DG_AP.add_edge('d', 'c', weight=7) print(DG_AP.nodes()) print(DG_AP.edges(data=True)) print('Done by hand.') print('{}. {}'.format(label, description)) print() with FigureNum(21) as figure_number: description = 'Intuition behind the all-pairs shortest path problem' label = caption(chapter, figure_number) print('by hand') print('{}. {}'.format(label, description)) print() with FigureNum(22) as figure_number: description = 'dist_to, node_from, and actual shortest paths for graph in Figure 7-20' label = caption(chapter, figure_number) DG_TABLE = nx.DiGraph() DG_TABLE.add_edge('a', 'b', weight=4) DG_TABLE.add_edge('b', 'a', weight=2) DG_TABLE.add_edge('a', 'c', weight=3) DG_TABLE.add_edge('b', 'd', weight=5) DG_TABLE.add_edge('c', 'b', weight=6) DG_TABLE.add_edge('d', 'b', weight=1) DG_TABLE.add_edge('d', 'c', weight=7) visualize_results_floyd_warshall(DG_TABLE) print('{}. {}'.format(label, description)) print() with FigureNum(23) as figure_number: description = 'Initialize dist_to[][] and node_from[][] based on G' label = caption(chapter, figure_number) DG_TABLE = nx.DiGraph() DG_TABLE.add_edge('a', 'b', weight=4) DG_TABLE.add_edge('b', 'a', weight=2) DG_TABLE.add_edge('a', 'c', weight=3) DG_TABLE.add_edge('b', 'd', weight=5) DG_TABLE.add_edge('c', 'b', weight=6) DG_TABLE.add_edge('d', 'b', weight=1) DG_TABLE.add_edge('d', 'c', weight=7) visualize_results_floyd_warshall_just_initialize(DG_TABLE) print('{}. {}'.format(label, description)) print() with FigureNum(24) as figure_number: description = 'Changes to node_from[][] and dist_to[][] after k processes a and b' label = caption(chapter, figure_number) DG_TABLE = nx.DiGraph() DG_TABLE.add_edge('a', 'b', weight=4) DG_TABLE.add_edge('b', 'a', weight=2) DG_TABLE.add_edge('a', 'c', weight=3) DG_TABLE.add_edge('b', 'd', weight=5) DG_TABLE.add_edge('c', 'b', weight=6) DG_TABLE.add_edge('d', 'b', weight=1) DG_TABLE.add_edge('d', 'c', weight=7) visualize_results_floyd_warshall_two_steps(DG_TABLE) print('{}. {}'.format(label, description)) print() with FigureNum(25) as figure_number: description = 'Sample Maze to defeat Guided Search' label = caption(chapter, figure_number) print('Done by hand.') print('{}. {}'.format(label, description)) print() with FigureNum(26) as figure_number: description = 'Sample directed, acyclic graph for single-source, shortest path optimization' label = caption(chapter, figure_number) print('Done by hand.') print('{}. {}'.format(label, description)) print()
def generate_ch02(): """Generate tables/figures for chapter 02.""" chapter = 2 with TableNum(1) as table_number: process(actual_table(), chapter, table_number, 'Prototype runtime performance') with TableNum(2) as table_number: process( prototype_table(), chapter, table_number, 'Comparing different mathematical models against actual performance' ) with TableNum(3) as table_number: process(large_multiplication(), chapter, table_number, 'Multiplying two n-digit integers') with FigureNum(1) as figure_number: print('Excel plot') print(caption(chapter, figure_number), 'Compare models against performance') with FigureNum(2) as figure_number: algorithms_x_y() print(caption(chapter, figure_number), 'Performance of algorithms X and Y on different computers') with FigureNum(3) as figure_number: print('Excel plots') print(caption(chapter, figure_number), 'Visualizing the numbers from Figure 2-2') with TableNum(4) as table_number: process(growth_table(), chapter, table_number, 'Growth of different computations') with FigureNum(4) as figure_number: print('by hand') print(caption(chapter, figure_number), 'Doors of destiny!') with FigureNum(5) as figure_number: print('by hand') print(caption(chapter, figure_number), 'Searching for 53 in a sorted array that contains the value.') with FigureNum(6) as figure_number: print('by hand') print( caption(chapter, figure_number), 'Searching for 17 in a sorted array that does not contain the value.' ) with FigureNum(7) as figure_number: print('by hand') print(caption(chapter, figure_number), 'All complexity classes are arranged in dominance hierarchy') with FigureNum(8) as figure_number: print( caption(chapter, figure_number), 'Runtime performance plotted against problem instance size for complexity classes' )