From f00335327d42fe4bdb380b8b02a56398d5b49664 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 19 May 2018 19:23:29 +0800 Subject: [PATCH 01/49] debug --- test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test.sh b/test.sh index 8de1f72..09612dd 100644 --- a/test.sh +++ b/test.sh @@ -1 +1 @@ -for f in $(ls *test.py | cut -d '.' -f1); do ipython -m unittest $f;done +for f in $(ls *test.py | cut -d '.' -f1); do python3 -m unittest $f;done From 4caf7cfc2028a4d2b8ad03b909330ae9209a0168 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 20 May 2018 01:51:40 +0800 Subject: [PATCH 02/49] Since python2 is outdated, the original python2.7 code is moved to py2.7 branch. The master branch now supports python3 only. --- Bellman_Ford_matrix.py | 26 +- Bellman_Ford_matrix_test.py | 20 +- Johnson.py | 46 +- Johnson_test.py | 13 +- README.md | 5 + activity_selection.py | 31 +- all_pairs_shortest_paths.py | 130 ++-- all_pairs_shortest_paths_test.py | 43 +- any_disks_intersect.py | 51 +- any_segments_intersect.py | 8 +- automaton_string_match.py | 9 +- b_tree.py | 72 +- b_tree_test.py | 16 +- bh_tree.py | 10 +- bh_tree_test.py | 18 +- binary_counter.py | 7 +- common-matrix-multiply-Strassen.py | 78 +-- common-matrix-multiply-recursive.py | 51 +- comparable.py | 14 +- constraints.py | 45 +- constraints_test.py | 69 +- contains.py | 13 +- contains_test.py | 6 +- counting_sort_test.py | 7 +- cut_rod.py | 32 +- cut_rod_test.py | 18 +- depth_tree.py | 13 +- depth_tree_test.py | 18 +- disjoint_sets_forest.py | 16 +- disjoint_sets_forest_test.py | 18 +- disjoint_sets_test.py | 7 +- extended_bottom_up_cut_rod.py | 7 +- fibonacci_heap.py | 41 +- graph.py | 217 +++--- graph_test.py | 646 ++++++++++-------- hamiltonian_path_test.py | 23 +- hash.py | 15 +- heap.py | 50 +- heap_test.py | 25 +- huffman.py | 64 +- interpolation.py | 12 +- interval_tree.py | 21 +- interval_tree_test.py | 41 +- inversion_tree.py | 4 +- k_way_merge.py | 4 +- k_way_merge_test.py | 18 +- knapsack_0_1.py | 19 +- kth-Quantiles.py | 41 +- linked_list.py | 17 +- linked_list_test.py | 13 +- longest_common_subsequence.py | 10 +- longest_common_subsequence_test.py | 20 +- ...notonically_increasing_subsequence_test.py | 6 +- longest_palindrome_subsequence.py | 15 +- main.c | 28 - matrix_chain_order.py | 22 +- min_gap_tree.py | 2 +- min_gap_tree_test.py | 22 +- min_heap_with_linked_list.py | 21 +- min_heap_with_linked_list_test.py | 18 +- min_priority_queue_using_rb_tree_test.py | 47 +- most_reliable_path_test.py | 19 +- optimal_binary_search_tree.py | 19 +- os_tree.py | 17 +- os_tree_test.py | 144 ++-- partition.py | 16 +- partition_test.py | 10 +- pointer_tree.py | 12 +- pointer_tree_test.py | 26 +- polynomial_multiply.py | 15 +- pow.c | 7 +- priority_queue_test.py | 58 +- queue.py | 14 +- quicksort_test.py | 28 +- randomized_select.py | 2 +- randomized_select_test.py | 10 +- rank_tree.py | 15 +- rank_tree_test.py | 58 +- rb_tree.py | 14 +- rb_tree_test.py | 54 +- segment_intersect.py | 5 + simplex.py | 50 +- single_edge.py | 65 +- ...n.py => square_matrix_multiply_Strassen.py | 73 +- stack.py | 10 +- synthetic_division.py | 1 + three_points_colinear.py | 18 +- tree.py | 141 ++-- universal_sink.py | 12 +- universal_sink_test.py | 37 +- vEB_tree.py | 34 +- vEB_tree_test.py | 11 +- 92 files changed, 2058 insertions(+), 1336 deletions(-) delete mode 100644 main.c rename square-matrix-multiply-Strassen.py => square_matrix_multiply_Strassen.py (50%) diff --git a/Bellman_Ford_matrix.py b/Bellman_Ford_matrix.py index 76739f2..5dec80c 100644 --- a/Bellman_Ford_matrix.py +++ b/Bellman_Ford_matrix.py @@ -1,5 +1,6 @@ import numpy as np + def Bellman_Ford_matrix(W, s): n = W.shape[0] d = [float("Inf")] * n @@ -11,10 +12,11 @@ def Bellman_Ford_matrix(W, s): if d[j - 1] > d[i - 1] + W[i - 1, j - 1]: d[j - 1] = d[i - 1] + W[i - 1, j - 1] p[j - 1] = i - print d - print p + print(d) + print(p) return d, p + def extend_shortest_paths(L, W): n = W.shape[0] LW = [float("Inf")] * n @@ -23,6 +25,7 @@ def extend_shortest_paths(L, W): LW[j] = min(LW[j], L[k] + W[k, j]) return LW + def slow_all_pairs_shortest_paths(W, s): n = W.shape[0] L = [0] * n @@ -31,16 +34,17 @@ def slow_all_pairs_shortest_paths(W, s): L[i] = 0 else: L[i] = float("Inf") - print L + print(L) for m in range(1, n): L = extend_shortest_paths(L, W) - print L + print(L) return L + def extend_shortest_paths_with_predecessor_subgraph(s, L, P, W): n = W.shape[0] LW = [float("Inf")] * n - PP = [None] * n + PP = [None] * n for j in range(0, n): for k in range(0, n): if LW[j] > L[k] + W[k, j]: @@ -50,6 +54,7 @@ def extend_shortest_paths_with_predecessor_subgraph(s, L, P, W): PP[j] = P[j] return LW, PP + def slow_all_pairs_shortest_paths_with_predecessor_subgraph(W, s): n = W.shape[0] L = [float("Inf")] * n @@ -57,10 +62,11 @@ def slow_all_pairs_shortest_paths_with_predecessor_subgraph(W, s): P = [None] * n for m in range(1, n): L, P = extend_shortest_paths_with_predecessor_subgraph(s, L, P, W) - print L - print P + print(L) + print(P) return L, P + def faster_all_pairs_shortest_paths(W): n = W.shape[0] L = W @@ -68,8 +74,6 @@ def faster_all_pairs_shortest_paths(W): while m < n - 1: L = extend_shortest_paths(L, L) m = 2 * m - print m - print L + print(m) + print(L) return Ld, p - - diff --git a/Bellman_Ford_matrix_test.py b/Bellman_Ford_matrix_test.py index 3e4dbdd..0f2d12b 100644 --- a/Bellman_Ford_matrix_test.py +++ b/Bellman_Ford_matrix_test.py @@ -1,14 +1,22 @@ from Bellman_Ford_matrix import Bellman_Ford_matrix, slow_all_pairs_shortest_paths import unittest import numpy + + class TestBellmanFordMatrix(unittest.TestCase): def test_Bellman_Ford_matrix(self): - W = numpy.array([[ float("Inf"), 6., 7., float("Inf"), float("Inf")], [ float("Inf"), float("Inf"), 8., 5., -4.], [ float("Inf"), float("Inf"), float("Inf"), -3., 9.], [ float("Inf"), -2., float("Inf"), float("Inf"), float("Inf")], [ 2., float("Inf"), float("Inf"), 7., float("Inf")]]) + W = numpy.array([[float("Inf"), 6., 7., float("Inf"), float("Inf")], [float("Inf"), float("Inf"), 8., 5., -4.], + [float("Inf"), float("Inf"), float("Inf"), -3., 9.], + [float("Inf"), -2., float("Inf"), float("Inf"), float("Inf")], + [2., float("Inf"), float("Inf"), 7., float("Inf")]]) d, p = Bellman_Ford_matrix(W, 1) - self.assertEquals(d, [0, 2.0, 7.0, 4.0, -2.0]) - self.assertEquals(p, [None, 4, 1, 3, 2]) + self.assertEqual(d, [0, 2.0, 7.0, 4.0, -2.0]) + self.assertEqual(p, [None, 4, 1, 3, 2]) + def test_slow_all_pairs_shortest_paths(self): - W = numpy.array([[ 0, 6., 7., float("Inf"), float("Inf")], [ float("Inf"), 0, 8., 5., -4.], [ float("Inf"), float("Inf"), 0, -3., 9.], [ float("Inf"), -2., float("Inf"), 0, float("Inf")], [ 2., float("Inf"), float("Inf"), 7., 0]]) + W = numpy.array([[0, 6., 7., float("Inf"), float("Inf")], [float("Inf"), 0, 8., 5., -4.], + [float("Inf"), float("Inf"), 0, -3., 9.], [float("Inf"), -2., float("Inf"), 0, float("Inf")], + [2., float("Inf"), float("Inf"), 7., 0]]) L = slow_all_pairs_shortest_paths(W, 1) - print L - self.assertEquals(L, [0, 2.0, 7.0, 4.0, -2.0]) + print(L) + self.assertEqual(L, [0, 2.0, 7.0, 4.0, -2.0]) diff --git a/Johnson.py b/Johnson.py index c4fa24b..8108827 100644 --- a/Johnson.py +++ b/Johnson.py @@ -1,34 +1,46 @@ from graph import min_priority_queue, Vertex, Graph import numpy as np + def Bellman_Ford(self, w, s): - ''' + """ The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative. - If there is a negative-weight cycle that is reachable from + If there is a negative-weight cycle that is reachable from the source s, this function returns False and indicates that no solution exists. If there is no such cycle, this function returns True and produces the shortest paths and their weights. - ''' + + :param self: + :param w: + :param s: + :return: + """ initialize_signle_source(self, s) for i in range(1, len(self.vertices)): - for u,v in self.edges: + for u, v in self.edges: relax(self, u, v, w) - for u,v in self.edges: + for u, v in self.edges: if v.d > u.d + w[(u, v)]: return False return True + + def initialize_signle_source(self, s): - for v in self.vertices: - v.d = float("Inf") - v.p = None - s.d = 0 + for v in self.vertices: + v.d = float("Inf") + v.p = None + s.d = 0 + + def relax(self, u, v, w): if v.d > u.d + w[u, v]: v.d = u.d + w[u, v] v.p = u + + def Dijkstra(self, w, s): ''' Dijkstra's algorithm solves the single-source shortest-paths problem @@ -46,26 +58,28 @@ def Dijkstra(self, w, s): v.d = u.d + w[u, v] v.p = u Q.heap_decrease_key(v.index, u.d + w[u, v]) + + def Johnson(self, w): G = self n = len(G.vertices) s = Vertex("s") - GG = Graph(G.vertices.union({s}), G.edges + [(s, v) for v in G.vertices]) + GG = Graph(G.vertices.union({s}), G.edges | set((s, v) for v in G.vertices)) for v in G.vertices: w[(s, v)] = 0 - if Bellman_Ford(GG, w, s) == False: - print "the input graph contains a negative-weight cycle" + if not Bellman_Ford(GG, w, s): + print("the input graph contains a negative-weight cycle") else: h = dict() for v in GG.vertices: h[v] = v.d - #for key,value in h.iteritems(): - # print "h({}) = {}".format(key, value) + # for key,value in h.iteritems(): + # print(( "h({}) = {}".format(key, value))) ww = dict() for u, v in GG.edges: ww[(u, v)] = w[(u, v)] + h[u] - h[v] - #for key,value in ww.iteritems(): - # print "ww({}) = {}".format(key, value) + # for key,value in ww.iteritems(): + # print(( "ww({}) = {}".format(key, value))) D = np.empty((n, n)) for u in G.vertices: Dijkstra(G, ww, u) diff --git a/Johnson_test.py b/Johnson_test.py index 5352e58..7e68875 100644 --- a/Johnson_test.py +++ b/Johnson_test.py @@ -2,6 +2,7 @@ from graph import Vertex, Graph import unittest + class TestJohnson(unittest.TestCase): def testJohnson(self): a1 = Vertex(1) @@ -14,10 +15,10 @@ def testJohnson(self): g = Graph(vertices, edges) weight = [3, 8, -4, 1, 7, 4, 2, -5, 6] w = dict() - for i,j in zip(edges, weight): - w[i] = j + for i, j in zip(edges, weight): + w[i] = j D = Johnson(g, w) - print D + print(D) a1 = Vertex(1) a2 = Vertex(2) a3 = Vertex(3) @@ -29,7 +30,7 @@ def testJohnson(self): g = Graph(vertices, edges) weight = [-1, 1, 2, 2, -8, -4, 3, 7, 5, 10] w = dict() - for i,j in zip(edges, weight): - w[i] = j + for i, j in zip(edges, weight): + w[i] = j D = Johnson(g, w) - print D + print(D) diff --git a/README.md b/README.md index c4adc91..3f2d8c0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,9 @@ # algorithm implementation of algorithms in CLRS +## note +Since python2 is outdated, the original python2.7 code is moved to python2.7 branch. +The master branch support python3 only. + +## test test.sh is the shell script to run all the testcases diff --git a/activity_selection.py b/activity_selection.py index 95c248a..233b323 100644 --- a/activity_selection.py +++ b/activity_selection.py @@ -1,5 +1,6 @@ from numpy import zeros + def activity_selection(s, f, n): c = zeros((n + 2, n + 2)) activities = zeros((n + 2, n + 2)) @@ -8,18 +9,20 @@ def activity_selection(s, f, n): for l in range(3, n + 3): for i in range(0, n + 3 - l): j = i + l - 1 - print "i = {}, j = {}".format(i, j) + print("i = {}, j = {}".format(i, j)) for k in range(i + 1, j): - print "k = {}".format(k) - print "s[{}] = {}, f[{}] = {}".format(k, s[k], k, f[k]) - print "s[{}] = {}, f[{}] = {}".format(j, s[j], i, f[i]) + print("k = {}".format(k)) + print("s[{}] = {}, f[{}] = {}".format(k, s[k], k, f[k])) + print("s[{}] = {}, f[{}] = {}".format(j, s[j], i, f[i])) if f[i] <= s[k] and f[k] <= s[j]: t = c[i, k] + c[k, j] + 1 - print "t = {}, c[{}, {}] = {}".format(t, i, j, c[i, j]) + print("t = {}, c[{}, {}] = {}".format(t, i, j, c[i, j])) if t > c[i, j]: c[i, j] = t activities[i, j] = k - return c,activities + return c, activities + + def activity_selection_with_weight(s, f, v, n): '''This is a modification to the activity-selection problem in which each activity has, in addition to a start and finish time, a value v. Now the object is to maximize @@ -37,10 +40,14 @@ def activity_selection_with_weight(s, f, v, n): if t > c[i, j]: c[i, j] = t activities[i, j] = k - return c,activities + return c, activities + + def recursive_activity_selector(s, f, n): f = [float("-Inf")] + f return recursive_activity_selector_aux(s, f, 0, n) + + def recursive_activity_selector_aux(s, f, k, n): m = k + 1 while m <= n and s[m - 1] < f[k]: @@ -49,6 +56,8 @@ def recursive_activity_selector_aux(s, f, k, n): return {m}.union(recursive_activity_selector_aux(s, f, m, n)) else: return {} + + def greedy_activity_selector(s, f): n = len(s) A = {1} @@ -58,6 +67,8 @@ def greedy_activity_selector(s, f): A = A.union({m}) k = m return A + + def greedy_activity_selector_last(s, f): '''Instead of always selecting the first activity to finish, select the last activity to start that is compatible with all @@ -70,14 +81,18 @@ def greedy_activity_selector_last(s, f): A = A.union({m}) k = m return A + + def print_activity(activities): m = activities.shape[0] - 1 n = activities.shape[1] - 1 print_activity_aux(activities, 0, n) + + def print_activity_aux(activities, m, n): a = activities[m, n] if a == 0: return print_activity_aux(activities, m, a) - print int(a) + print(int(a)) print_activity_aux(activities, a, n) diff --git a/all_pairs_shortest_paths.py b/all_pairs_shortest_paths.py index 323a572..d6115b3 100644 --- a/all_pairs_shortest_paths.py +++ b/all_pairs_shortest_paths.py @@ -1,21 +1,23 @@ import numpy as np + def extend_shortest_paths(L, W): n = L.shape[0] - LW = np.empty((n, n)) - for i in range(0, n): - for j in range(0, n): + LW = np.empty((n, n)) + for i in range(n): + for j in range(n): LW[i, j] = float("Inf") - for k in range(0, n): + for k in range(n): LW[i, j] = min(LW[i, j], L[i, k] + W[k, j]) return LW + def slow_all_pairs_shortest_paths(W): n = W.shape[0] L = [None] * n L[0] = np.empty((n, n)) - for i in range(0, n): - for j in range(0, n): + for i in range(n): + for j in range(n): if i == j: L[0][i, j] = 0 else: @@ -25,34 +27,36 @@ def slow_all_pairs_shortest_paths(W): L[m] = extend_shortest_paths(L[m - 1], W) return L[m] + def extend_shortest_paths_with_predecessor_subgraph(L, P, W): n = W.shape[0] LW = np.empty((n, n)) PP = np.empty((n, n)) - for i in range(0, n): - for j in range(0, n): + for i in range(n): + for j in range(n): LW[i, j] = float("Inf") PP[i, j] = None - for k in range(0, n): + for k in range(n): if LW[i, j] > L[i, k] + W[k, j]: LW[i, j] = L[i, k] + W[k, j] PP[i, j] = k + 1 if LW[i, j] == L[i, j]: PP[i, j] = P[i, j] -# if j == i: -# PP[i, j] = None -# elif j != k: -# PP[i, j] = k + 1 -# else: -# PP[i, j] = P[i, j] + # if j == i: + # PP[i, j] = None + # elif j != k: + # PP[i, j] = k + 1 + # else: + # PP[i, j] = P[i, j] return LW, PP + def slow_all_pairs_shortest_paths_with_predecessor_subgraph(W): n = W.shape[0] L = np.empty((n, n)) P = np.empty((n, n)) - for i in range(0, n): - for j in range(0, n): + for i in range(n): + for j in range(n): if j == i: L[i, j] = 0 else: @@ -60,40 +64,43 @@ def slow_all_pairs_shortest_paths_with_predecessor_subgraph(W): P[i, j] = None for m in range(1, n): L, P = extend_shortest_paths_with_predecessor_subgraph(L, P, W) - print L - print P + print(L) + print(P) return L, P + def predecessor(W, L): n = W.shape[0] P = np.empty((n, n)) - COMPLETED = np.empty((n, n), dtype = bool) + COMPLETED = np.empty((n, n), dtype=bool) DEPTH = np.empty((n, n)) - for i in range(0, n): - for j in range(0, n): + for i in range(n): + for j in range(n): COMPLETED[i, j] = False DEPTH[i, j] = None P[i, j] = None - for i in range(0, n): + for i in range(n): P[i, i] = None COMPLETED[i, i] = True DEPTH[i, i] = 0 for m in range(1, n): - for i in range(0, n): - for j in range(0, n): + for i in range(n): + for j in range(n): if i == 0: - print m - print COMPLETED[i, j] - print L[m][i] - print L[n - 1][j] + print(m) + print(COMPLETED[i, j]) + print(L[m][i]) + print(L[n - 1][j]) if COMPLETED[i, j] == False and L[m][i, j] == L[n - 1][i, j]: - for k in range(0, n): - if DEPTH[i, k] == m - 1 and L[m][i, j] == L[m -1][i, k] + W[k, j]: + for k in range(n): + if DEPTH[i, k] == m - 1 and L[m][i, j] == L[m - 1][i, k] + W[k, j]: DEPTH[i, j] = m P[i, j] = k + 1 COMPLETED[i, j] = True break return P + + def faster_all_pairs_shortest_paths(W): n = W.shape[0] L = W @@ -101,42 +108,48 @@ def faster_all_pairs_shortest_paths(W): while m < n - 1: L = extend_shortest_paths(L, L) m = 2 * m - print m - print L + print(m) + print(L) return L + def negative_weight_cycle(W): L = faster_all_pairs_shortest_paths(W) n = W.shape[0] status = True - for i in range(0, n): - for j in range(0, n): - for k in range(0, n): + for i in range(n): + for j in range(n): + for k in range(n): if L[i, j] > L[i, k] + W[k, j]: - print "source {} contains a negative-weight cycle".format(i + 1) + print("source {} contains a negative-weight cycle".format(i + 1)) status = False return status + + def negative_weight_cycle_another(W): L = faster_all_pairs_shortest_paths(W) L = extend_shortest_paths(L, W) - print L + print(L) status = True n = W.shape[0] - for i in range(0, n): + for i in range(n): if L[i, i] < 0: status = False return status + + def minimum_negative_weight_cycle_edges_number(W): n = W.shape[0] L = W for m in range(2, n + 1): L = extend_shortest_paths(L, W) - for i in range(0, n): + for i in range(n): if L[i, i] < 0: - print "minimum negative weight cycle edges number is {}".format(m) + print("minimum negative weight cycle edges number is {}".format(m)) return False return True + def Floyd_Warshall(W): n = W.shape[0] D = [None] * (n + 1) @@ -154,52 +167,57 @@ def Floyd_Warshall(W): P[k] = np.empty((n, n)) for i in range(n): for j in range(n): - D[k][i,j] = min(D[k - 1][i, j], D[k - 1][i, k - 1] + D[k - 1][k - 1, j]) + D[k][i, j] = min(D[k - 1][i, j], D[k - 1][i, k - 1] + D[k - 1][k - 1, j]) if D[k - 1][i, j] > D[k - 1][i, k - 1] + D[k - 1][k - 1, j]: P[k][i, j] = P[k - 1][k - 1, j] else: P[k][i, j] = P[k - 1][i, j] return D[n], P[n] + + def Floyd_Warshall_WITH_LI(W): n = W.shape[0] D = [None] * (n + 1) D[0] = W LI = [None] * (n + 1) - LI[0] = np.empty((n, n), dtype = np.int32) + LI[0] = np.empty((n, n), dtype=np.int32) for i in range(1, n + 1): for j in range(1, n + 1): - LI[0][i - 1, j - 1] = 0 + LI[0][i - 1, j - 1] = 0 for k in range(1, n + 1): D[k] = np.empty((n, n)) - LI[k] = np.empty((n, n), dtype = np.int32) + LI[k] = np.empty((n, n), dtype=np.int32) for i in range(n): for j in range(n): - D[k][i,j] = min(D[k - 1][i, j], D[k - 1][i, k - 1] + D[k - 1][k - 1, j]) + D[k][i, j] = min(D[k - 1][i, j], D[k - 1][i, k - 1] + D[k - 1][k - 1, j]) if D[k - 1][i, j] > D[k - 1][i, k - 1] + D[k - 1][k - 1, j]: LI[k][i, j] = k else: LI[k][i, j] = LI[k - 1][i, j] - print LI[k] - print D[k] + print(LI[k]) + print(D[k]) return D[n], LI[n] + def print_all_pairs_shortest_path(LI, i, j): global status status = [False] * LI.shape[0] print_all_pairs_shortest_path_aux(LI, i, j) + + def print_all_pairs_shortest_path_aux(LI, i, j): global status - # print "www: {}, {}, status: {}".format(i, j, status) + # print( "www: {}, {}, status: {}".format(i, j, status)) if LI[i - 1, j - 1] == 0: - if status[i - 1] == False: + if not status[i - 1]: status[i - 1] = True - print i - if status[j - 1] == False: + print(i) + if not status[j - 1]: status[j - 1] = True - print j + print(j) else: print_all_pairs_shortest_path_aux(LI, i, LI[i - 1, j - 1]) - if status[LI[i - 1, j - 1] - 1] == False: - print LI[i - 1, j - 1] - status[LI[i - 1, j - 1] - 1] = True + if not status[LI[i - 1, j - 1] - 1]: + print(LI[i - 1, j - 1]) + status[LI[i - 1, j - 1] - 1] = True print_all_pairs_shortest_path_aux(LI, LI[i - 1, j - 1], j) diff --git a/all_pairs_shortest_paths_test.py b/all_pairs_shortest_paths_test.py index 6819906..e311d0d 100644 --- a/all_pairs_shortest_paths_test.py +++ b/all_pairs_shortest_paths_test.py @@ -1,23 +1,44 @@ -from all_pairs_shortest_paths import extend_shortest_paths, slow_all_pairs_shortest_paths, faster_all_pairs_shortest_paths +from all_pairs_shortest_paths import extend_shortest_paths, slow_all_pairs_shortest_paths, \ + faster_all_pairs_shortest_paths import unittest import numpy as np + class TestAllPairsShortestPaths(unittest.TestCase): def test_slow_all_pairs_shortest_paths(self): - W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7], [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")], [float("Inf"), float("Inf"), float("Inf"), 6, 0]]) + W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7], + [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")], + [float("Inf"), float("Inf"), float("Inf"), 6, 0]]) R = slow_all_pairs_shortest_paths(W) L = np.array([[0, 1, -3, 2, -4], [3, 0, -4, 1, -1], [7, 4, 0, 5, 3], [2, -1, -5, 0, -2], [8, 5, 1, 6, 0]]) - self.assertEquals((R == L).all(), True) - W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")], [1, 0, float("Inf"), 2, float("Inf"), float("Inf")], [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8], [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")], [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")], [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]]) + self.assertEqual((R == L).all(), True) + W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")], + [1, 0, float("Inf"), 2, float("Inf"), float("Inf")], + [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8], + [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")], + [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")], + [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]]) R = slow_all_pairs_shortest_paths(W) - L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")], [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")], [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]]) - self.assertEquals((R == L).all(), True) + L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")], + [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")], + [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]]) + self.assertEqual((R == L).all(), True) + def test_faster_all_pairs_shortest_paths(self): - W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7], [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")], [float("Inf"), float("Inf"), float("Inf"), 6, 0]]) + W = np.array([[0, 3, 8, float("Inf"), -4], [float("Inf"), 0, float("Inf"), 1, 7], + [float("Inf"), 4, 0, float("Inf"), float("Inf")], [2, float("Inf"), -5, 0, float("Inf")], + [float("Inf"), float("Inf"), float("Inf"), 6, 0]]) R = faster_all_pairs_shortest_paths(W) L = np.array([[0, 1, -3, 2, -4], [3, 0, -4, 1, -1], [7, 4, 0, 5, 3], [2, -1, -5, 0, -2], [8, 5, 1, 6, 0]]) - self.assertEquals((R == L).all(), True) - W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")], [1, 0, float("Inf"), 2, float("Inf"), float("Inf")], [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8], [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")], [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")], [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]]) + self.assertEqual((R == L).all(), True) + W = np.array([[0, float("Inf"), float("Inf"), float("Inf"), -1, float("Inf")], + [1, 0, float("Inf"), 2, float("Inf"), float("Inf")], + [float("Inf"), 2, 0, float("Inf"), float("Inf"), -8], + [-4, float("Inf"), float("Inf"), 0, 3, float("Inf")], + [float("Inf"), 7, float("Inf"), float("Inf"), 0, float("Inf")], + [float("Inf"), 5, 10, float("Inf"), float("Inf"), 0]]) R = faster_all_pairs_shortest_paths(W) - L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")], [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")], [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]]) - self.assertEquals((R == L).all(), True) + L = np.array([[0, 6, float("Inf"), 8, -1, float("Inf")], [-2, 0, float("Inf"), 2, -3, float("Inf")], + [-5, -3, 0, -1, -6, -8], [-4, 2, float("Inf"), 0, -5, float("Inf")], + [5, 7, float("Inf"), 9, 0, float("Inf")], [3, 5, 10, 7, 2, 0]]) + self.assertEqual((R == L).all(), True) diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 1bbd33d..3e35ad3 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -5,6 +5,7 @@ from tree import Node, Tree from heap import max_heap + def comparable(a, b): '''Given two disks a and b that are comparable at x, determine whether a is above b or not.''' a_y = a[0][1] @@ -13,20 +14,27 @@ def comparable(a, b): return True else: return False + + class disk(tuple): def __init__(self, d): super(disk, self).__init__(d) self.pointer = None + + class point(list): def __init__(self, info, disk): super(point, self).__init__(info) self.disk = disk + + class rb_node(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color if key != None: key.pointer = self + def minimum(self, nil): x = self y = x @@ -34,16 +42,21 @@ def minimum(self, nil): y = x x = x.left return y + def maximum(self, nil): x = self while x.right != nil: x = x.right return x + + class rb_tree(Tree): nil = rb_node(None, None, None, None, 1) root = nil + def __init__(self): pass + def above(self, s): x = s.pointer if x.right != self.nil: @@ -52,6 +65,7 @@ def above(self, s): while x.p != self.nil and x.p.right == x: x = x.p return x.p.key + def below(self, s): x = s.pointer if x.left != self.nil: @@ -60,10 +74,13 @@ def below(self, s): while x.p != self.nil and x.p.left == x: x = x.p return x.p.key + def minimum(self): return self.root.minimum(self.nil) + def __getitem__(self, key): return self.iterative_tree_search(key) + def left_rotate(self, x): y = x.right x.right = y.left @@ -78,6 +95,7 @@ def left_rotate(self, x): x.p.right = y y.left = x x.p = y + def right_rotate(self, y): x = y.left y.left = x.right @@ -92,6 +110,7 @@ def right_rotate(self, y): y.p.left = x x.right = y y.p = x + def insert(self, z): ''' the disk z will only be inserted when the left endpoint of z is being processed''' # this is the x_coordinate of the left endpoint of z @@ -114,8 +133,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def insert_fixed(self, z): while z.p.color == 0: if z.p.p.left == z.p: @@ -149,6 +169,7 @@ def insert_fixed(self, z): z.color = 0 z.p.color = 1 self.root.color = 1 + def transplant(self, u, v): if u.p == self.nil: self.root = v @@ -157,6 +178,7 @@ def transplant(self, u, v): else: u.p.right = v v.p = u.p + def delete(self, z): z = z.pointer y = z @@ -183,6 +205,7 @@ def delete(self, z): y.color = z.color if y_original_color == 1: self.delete_fixup(x) + def delete_fixup(self, x): while x != self.root and x.color == 1: if x == x.p.left: @@ -228,8 +251,14 @@ def delete_fixup(self, x): self.right_rotate(x.p) x = self.root x.color = 1 + + def any_disks_intersect(S): - '''This algorithm takes as input a set S of n disks represented by its center point and radius, returning the boolean value TRUE if any pair of disks in S intersects, and FALSE otherwise.''' + """ + This algorithm takes as input a set S of n disks represented by its center point and radius, returning the boolean value TRUE if any pair of disks in S intersects, and FALSE otherwise. + :param S: + :return: + """ T = rb_tree() point_list = [] disk_list = [] @@ -244,35 +273,37 @@ def any_disks_intersect(S): point_list.append(point([x + radius, 1, y], s)) heap_point = max_heap(point_list) heap_point.heapsort() - print heap_point + print(heap_point) for p in heap_point: if p[1] == 0: s = p.disk T.insert(s) a = T.above(s) b = T.below(s) - print "insert: ", a, b - if (a != None and disks_intersect(a, s)) or (b != None and disks_intersect(b, s)): + print("insert: ", a, b) + if (a is not None and disks_intersect(a, s)) or (b is not None and disks_intersect(b, s)): return True if p[1] == 1: s = p.disk a = T.above(s) b = T.below(s) - if a != None and b != None and disks_intersect(a, b): + if a is not None and b is not None and disks_intersect(a, b): return True T.delete(s) return False + + def disks_intersect(a, b): - print a - print b + print(a) + print(b) a_x = a[0][0] a_y = a[0][1] a_r = a[1] b_x = b[0][0] b_y = b[0][1] b_r = b[1] - print (a_x - b_x) ** 2 + (a_y - b_y) ** 2 - print (a_r + b_r) ** 2 + print((a_x - b_x) ** 2 + (a_y - b_y) ** 2) + print((a_r + b_r) ** 2) if ((a_x - b_x) ** 2 + (a_y - b_y) ** 2) <= ((a_r + b_r) ** 2): return True else: diff --git a/any_segments_intersect.py b/any_segments_intersect.py index 4fc0d57..0c77e08 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -290,10 +290,10 @@ def any_segments_intersect(S): s = p.segment a = T.above(s) b = T.below(s) -# print a -# print b -# print type(a) -# print type(b) +# print( a) +# print( b) +# print( type(a)) +# print( type(b)) if a != None and b != None and segments_intersect(a[0], a[1], b[0], b[1]): return True T.delete(s) diff --git a/automaton_string_match.py b/automaton_string_match.py index 08c0d38..1fc2118 100644 --- a/automaton_string_match.py +++ b/automaton_string_match.py @@ -1,22 +1,27 @@ #!/usr/bin/env ipython + def finite_automaton_matcher(T, s, m): n = len(T) q = 0 for i in range(1, n + 1): q = s[(q, T[i - 1])] if q == m: - print "Pattern occurs with shift {}".format(i - m) + print("Pattern occurs with shift {}".format(i - m)) + + def compute_transition_function(P, domain): m = len(P) s = dict() for a in domain: - for q in range(0, m + 1): + for q in range(m + 1): k = min(q + 1, m) while not (P[0:q] + a).endswith(P[0:k]): k = k - 1 s[(q, a)] = k return s + + def automaton_string_match(P, T, domain): s = compute_transition_function(P, domain) m = len(P) diff --git a/b_tree.py b/b_tree.py index e181b40..7909ed8 100644 --- a/b_tree.py +++ b/b_tree.py @@ -7,6 +7,7 @@ def __init__(self, t, leaf, n): self.t = t self.key = [0] * (2 * t - 1) self.c = [0] * (2 * t) + def split_child(self, i): y = self.c[i - 1] t = y.t @@ -21,9 +22,10 @@ def split_child(self, i): self.c[j] = self.c[j - 1] self.c[i] = z for j in range(self.n, i - 1, -1): - self.key[j] = self.key[j -1] + self.key[j] = self.key[j - 1] self.key[i - 1] = y.key[t - 1] self.n = self.n + 1 + def insert_nonfull(self, k): i = self.n t = self.t @@ -42,6 +44,7 @@ def insert_nonfull(self, k): if k > self.key[i - 1]: i = i + 1 self.c[i - 1].insert_nonfull(k) + def search(self, k): i = 1 while i <= self.n and k > self.key[i - 1]: @@ -52,21 +55,24 @@ def search(self, k): return None else: return self.c[i - 1].search(k) + def print_inorder(self): if self.leaf: for i in range(1, self.n + 1): - print self.key[i - 1], + print(self.key[i - 1], ) else: for i in range(1, self.n + 1): self.c[i - 1].print_inorder() - print self.key[i - 1], + print(self.key[i - 1], ) self.c[self.n].print_inorder() + def print_child_first(self): if not self.leaf: for i in range(1, self.n + 2): self.c[i - 1].print_child_first() for i in range(1, self.n + 1): - print self.key[i - 1], + print(self.key[i - 1], ) + def delete(self, tree, k): t = self.t i = 1 @@ -133,7 +139,8 @@ def delete(self, tree, k): self.merge(tree, i - 1) self.c[i - 2].delete(tree, k) else: - self.c[i - 1].delete(tree, k) + self.c[i - 1].delete(tree, k) + def merge(self, tree, i): y = self.c[i - 1] z = self.c[i] @@ -154,10 +161,13 @@ def merge(self, tree, i): self.n = self.n - 1 if tree.root == self and self.n == 0: tree.root = y + + class b_tree(object): def __init__(self, t): self.t = t self.root = b_tree_node(t, True, 0) + def insert(self, k): r = self.root t = self.t @@ -169,34 +179,36 @@ def insert(self, k): s.insert_nonfull(k) else: r.insert_nonfull(k) + def print_b_tree(self): r = self.root r.print_inorder() -# def predecessor(self, k): -# m = [] -# x = self.root -# while not x.leaf: -# i = 1 -# while i <= x.n and k > x.key[i - 1]: -# i = i + 1 -# if i <= x.n and k == x.key[i - 1]: -# x = x.c[i - 1] -# while not x.leaf: -# x = x.c[x.n] -# return x.key[x.n - 1] -# else: -# x = x.c[i - 1] -# if i > 1: -# m.append(x.key[i - 1]) -# i = 1 -# while i <= x.n and k != x.key[i - 1]: -# i = i + 1 -# if i > x.n or len(m) == 0: -# return None -# elif i > 1: -# return x.key[i - 2] -# else: -# return max(m) + + # def predecessor(self, k): + # m = [] + # x = self.root + # while not x.leaf: + # i = 1 + # while i <= x.n and k > x.key[i - 1]: + # i = i + 1 + # if i <= x.n and k == x.key[i - 1]: + # x = x.c[i - 1] + # while not x.leaf: + # x = x.c[x.n] + # return x.key[x.n - 1] + # else: + # x = x.c[i - 1] + # if i > 1: + # m.append(x.key[i - 1]) + # i = 1 + # while i <= x.n and k != x.key[i - 1]: + # i = i + 1 + # if i > x.n or len(m) == 0: + # return None + # elif i > 1: + # return x.key[i - 2] + # else: + # return max(m) def predecessor(self, k): s = [] x = self.root diff --git a/b_tree_test.py b/b_tree_test.py index 92f321a..f271526 100755 --- a/b_tree_test.py +++ b/b_tree_test.py @@ -48,25 +48,25 @@ t.root.leaf = False t.root.delete(t, 'F') t.root.print_child_first() -print +print() t.root.delete(t, 'M') t.root.print_child_first() -print +print() t.root.delete(t, 'G') t.root.print_child_first() -print +print() t.root.delete(t, 'D') t.root.print_child_first() -print +print() t.root.delete(t, 'B') t.root.print_child_first() -print +print() t.root.delete(t, 'C') t.root.print_child_first() -print +print() t.root.delete(t, 'P') t.root.print_child_first() -print +print() t.root.delete(t, 'V') t.root.print_child_first() -print +print() diff --git a/bh_tree.py b/bh_tree.py index 75f5ac2..6685618 100644 --- a/bh_tree.py +++ b/bh_tree.py @@ -1,21 +1,26 @@ # A variant of red black tree that has black_height attribute -#!/usr/bin/env ipython +# !/usr/bin/env ipython from rb_tree import rb_node, rb_tree + class bh_node(rb_node): def __init__(self, key, p, left, right, color, bh): rb_node.__init__(self, key, p, left, right, color) self.bh = bh + + class bh_tree(rb_tree): nil = bh_node(None, None, None, None, 1, 0) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(bh_node(i, None, None, None, 0, 1)) else: - print "Not invalid argument" + print("Not invalid argument") + def insert_fixed(self, z): while z.p.color == 0: if z.p.p.left == z.p: @@ -51,6 +56,7 @@ def insert_fixed(self, z): z.color = 0 z.p.color = 1 self.root.color = 1 + def delete_fixup(self, x): while x != self.root and x.color == 1: if x == x.p.left: diff --git a/bh_tree_test.py b/bh_tree_test.py index 4979b1f..a7c44d4 100755 --- a/bh_tree_test.py +++ b/bh_tree_test.py @@ -7,21 +7,25 @@ class TestRbtree(unittest.TestCase): def test_insert_one(self): T = bh_tree([41]) self.wrap(T, 41, 1) + def test_insert_two(self): T = bh_tree([41, 38]) self.wrap(T, 41, 1) self.wrap(T, 38, 1) + def test_insert_three(self): T = bh_tree([41, 38, 31]) self.wrap(T, 38, 1) self.wrap(T, 31, 1) self.wrap(T, 41, 1) + def test_insert_four(self): T = bh_tree([41, 38, 31, 12]) self.wrap(T, 38, 2) self.wrap(T, 31, 1) self.wrap(T, 41, 1) self.wrap(T, 12, 1) + def test_insert_five(self): T = bh_tree([41, 38, 31, 12, 19]) self.wrap(T, 38, 2) @@ -29,6 +33,7 @@ def test_insert_five(self): self.wrap(T, 41, 1) self.wrap(T, 12, 1) self.wrap(T, 31, 1) + def test_insert_six(self): T = bh_tree([41, 38, 31, 12, 19, 9]) self.wrap(T, 38, 2) @@ -37,6 +42,7 @@ def test_insert_six(self): self.wrap(T, 12, 1) self.wrap(T, 31, 1) self.wrap(T, 9, 1) + def test_delete_one(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -45,6 +51,7 @@ def test_delete_one(self): self.wrap(T, 41, 1) self.wrap(T, 12, 1) self.wrap(T, 31, 1) + def test_delete_two(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -53,6 +60,7 @@ def test_delete_two(self): self.wrap(T, 19, 1) self.wrap(T, 41, 1) self.wrap(T, 31, 1) + def test_delete_three(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -61,6 +69,7 @@ def test_delete_three(self): self.wrap(T, 38, 2) self.wrap(T, 31, 1) self.wrap(T, 41, 1) + def test_delete_four(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -69,6 +78,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, 1) self.wrap(T, 41, 1) + def test_delete_five(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -77,6 +87,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 41, 1) + def test_delete_six(self): T = bh_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -85,8 +96,11 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.root, T.nil) + self.assertEqual(T.root, T.nil) + def wrap(self, tree, node, bh): - self.assertEquals(tree.iterative_tree_search(node).bh, bh) + self.assertEqual(tree.iterative_tree_search(node).bh, bh) + + if __name__ == '__main__': unittest.main() diff --git a/binary_counter.py b/binary_counter.py index b729ccf..f2a334f 100644 --- a/binary_counter.py +++ b/binary_counter.py @@ -1,7 +1,8 @@ class binary_counter(list): def __init__(self, size): self.leftmost_1 = -1 - list.__init__(self, [0] * size) + list.__init__(self, [0] * size) + def increment(self): i = 0 while i < len(self) and self[i] == 1: @@ -13,9 +14,11 @@ def increment(self): self.leftmost_1 = i else: self.leftmost_1 = -1 + def reset(self): for i in range(0, self.leftmost_1 + 1): self[i] = 0 self.leftmost_1 = -1 + def print_bits(self): - print self[::-1] + print(self[::-1]) diff --git a/common-matrix-multiply-Strassen.py b/common-matrix-multiply-Strassen.py index 74effb5..f71fc02 100644 --- a/common-matrix-multiply-Strassen.py +++ b/common-matrix-multiply-Strassen.py @@ -6,15 +6,17 @@ # EMAIL: cntqrxj@gmail.com from numpy import * +from square_matrix_multiply_Strassen import square_matrix_multiply + def common_matrix_multiply(A, B): if (A.shape[1] != B.shape[0]): - print "The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed" + print("The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed") return shape = (A.shape[0], B.shape[1]) - #shape = A.shape - #length = shape[0] - #half = length / 2 + # shape = A.shape + length = shape[0] + half = length / 2 A_width = A.shape[1] B_width = B.shape[1] A_height = A.shape[0] @@ -23,32 +25,32 @@ def common_matrix_multiply(A, B): half_A_height = A_height / 2 half_B_width = B_width / 2 half_B_height = B_height / 2 - - C = zeros(shape, dtype = int64) + + C = zeros(shape, dtype=int64) if A_height == 1 or B_width == 1: - C = dot(A, B) - #if length == 1: + C = dot(A, B) + # if length == 1: # C[0, 0] = A[0, 0] * B[0, 0] # return C - - S1 = zeros((half, half), dtype = int64) - S2 = zeros((half, half), dtype = int64) - S3 = zeros((half, half), dtype = int64) - S4 = zeros((half, half), dtype = int64) - S5 = zeros((half, half), dtype = int64) - S6 = zeros((half, half), dtype = int64) - S7 = zeros((half, half), dtype = int64) - S8 = zeros((half, half), dtype = int64) - S9 = zeros((half, half), dtype = int64) - S10 = zeros((half, half), dtype = int64) - P1 = zeros((half, half), dtype = int64) - P2 = zeros((half, half), dtype = int64) - P3 = zeros((half, half), dtype = int64) - P4 = zeros((half, half), dtype = int64) - P5 = zeros((half, half), dtype = int64) - P6 = zeros((half, half), dtype = int64) - P7 = zeros((half, half), dtype = int64) + S1 = zeros((half, half), dtype=int64) + S2 = zeros((half, half), dtype=int64) + S3 = zeros((half, half), dtype=int64) + S4 = zeros((half, half), dtype=int64) + S5 = zeros((half, half), dtype=int64) + S6 = zeros((half, half), dtype=int64) + S7 = zeros((half, half), dtype=int64) + S8 = zeros((half, half), dtype=int64) + S9 = zeros((half, half), dtype=int64) + S10 = zeros((half, half), dtype=int64) + + P1 = zeros((half, half), dtype=int64) + P2 = zeros((half, half), dtype=int64) + P3 = zeros((half, half), dtype=int64) + P4 = zeros((half, half), dtype=int64) + P5 = zeros((half, half), dtype=int64) + P6 = zeros((half, half), dtype=int64) + P7 = zeros((half, half), dtype=int64) S1 = B[0:half, half:length] - B[half:length, half:length] S2 = A[0:half, 0:half] + A[0:half, half:length] @@ -68,22 +70,22 @@ def common_matrix_multiply(A, B): P5 = square_matrix_multiply(S5, S6) P6 = square_matrix_multiply(S7, S8) P7 = square_matrix_multiply(S9, S10) - + C[0:half, 0:half] = P5 + P4 - P2 + P6 C[0:half, half:length] = P1 + P2 C[half:length, 0:half] = P3 + P4 C[half:length, half:length] = P5 + P1 - P3 - P7 - - return C -#A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) -#B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) -#A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -#B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + return C + + +# A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) +# B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) +# A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) A = array([[1, 3], [7, 5]]) B = array([[6, 8], [4, 2]]) -#A = array([[1, 2, 3], [4, 5, 6]]) -#B = array([[1, 2], [4, 5]]) -print square_matrix_multiply(A, B) -#print dot(A, B) - +# A = array([[1, 2, 3], [4, 5, 6]]) +# B = array([[1, 2], [4, 5]]) +print(square_matrix_multiply(A, B)) +# print( dot(A, B)) diff --git a/common-matrix-multiply-recursive.py b/common-matrix-multiply-recursive.py index 11ea7f6..534e534 100755 --- a/common-matrix-multiply-recursive.py +++ b/common-matrix-multiply-recursive.py @@ -1,18 +1,14 @@ #! /usr/bin/python2.7 -# AUTHOR: WangQiang -# CREATE DATE: 20140528 -# LAST UPDATE DATE: 20140603 -# EMAIL: cntqrxj@gmail.com - from numpy import * + def common_matrix_multiply(A, B): - if (A.shape[1] != B.shape[0]): - print "The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed" + if A.shape[1] != B.shape[0]: + print("The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed") return shape = (A.shape[0], B.shape[1]) - C = zeros(shape, dtype = int64) + C = zeros(shape, dtype=int64) A_width = A.shape[1] B_width = B.shape[1] A_height = A.shape[0] @@ -22,20 +18,33 @@ def common_matrix_multiply(A, B): half_B_width = B_width / 2 half_B_height = B_height / 2 if A_height == 1 or B_width == 1: - C = dot(A, B) -# else if + C = dot(A, B) + # else if else: - C[0:half_A_height, 0:half_B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width], B[0:half_B_height, 0:half_B_width]) + common_matrix_multiply(A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width]) - C[0:half_A_height, half_B_width:B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width], B[0:half_B_height, half_B_width:B_width]) + common_matrix_multiply(A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width]) - C[half_A_height:A_height, 0:half_B_width] = common_matrix_multiply(A[half_A_height:A_height, 0:half_A_width], B[0:half_B_height, 0:half_B_width]) + common_matrix_multiply(A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width]) - C[half_A_height:A_height, half_B_width:B_width] = common_matrix_multiply(A[half_A_height:A_height, 0:half_A_width], B[0:half_B_height,half_B_width:B_width]) + common_matrix_multiply(A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width]) + C[0:half_A_height, 0:half_B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width], + B[0:half_B_height, + 0:half_B_width]) + common_matrix_multiply( + A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width]) + C[0:half_A_height, half_B_width:B_width] = common_matrix_multiply(A[0:half_A_height, 0:half_A_width], + B[0:half_B_height, + half_B_width:B_width]) + common_matrix_multiply( + A[0:half_A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width]) + C[half_A_height:A_height, 0:half_B_width] = common_matrix_multiply(A[half_A_height:A_height, 0:half_A_width], + B[0:half_B_height, + 0:half_B_width]) + common_matrix_multiply( + A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, 0:half_B_width]) + C[half_A_height:A_height, half_B_width:B_width] = common_matrix_multiply( + A[half_A_height:A_height, 0:half_A_width], + B[0:half_B_height, half_B_width:B_width]) + common_matrix_multiply( + A[half_A_height:A_height, half_A_width:A_width], B[half_B_height:B_height, half_B_width:B_width]) return C - + + A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) -#A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -#B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -#A = array([[1, 2, 3], [4, 5, 6]]) -#B = array([[1, 2], [4, 5]]) -print common_matrix_multiply(A, B) -#print dot(A, B) +# A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# A = array([[1, 2, 3], [4, 5, 6]]) +# B = array([[1, 2], [4, 5]]) +print(common_matrix_multiply(A, B)) +# print( dot(A, B)) diff --git a/comparable.py b/comparable.py index 85998b8..31f1461 100644 --- a/comparable.py +++ b/comparable.py @@ -1,7 +1,9 @@ #!/usr/bin/env ipython def comparable(a, b, x): - '''Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical ''' + """ + Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical + """ p1 = a[0] p2 = a[1] @@ -10,11 +12,13 @@ def comparable(a, b, x): x4 = p4[0] x3 = p3[0] v1 = (p2[0] - p1[0], p2[1] - p1[1]) - v2 = ((x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]), (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1])) + v2 = ( + (x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]), + (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1])) result = v1[0] * v2[1] - v2[0] * v1[1] if result == 0: - print "a intersects b at the vertical line" + print("a intersects b at the vertical line") elif result > 0: - print "a is above b" + print("a is above b") else: - print "b is above a" + print("b is above a") diff --git a/constraints.py b/constraints.py index 631dd6e..ff4a443 100644 --- a/constraints.py +++ b/constraints.py @@ -1,6 +1,7 @@ from graph import Vertex, Graph from random import sample + def Bellman_Ford(G, w, s): '''A variant to the original Bellman_Ford algorithm that we use to solve a system of difference constraints @@ -13,21 +14,25 @@ def Bellman_Ford(G, w, s): j = 1 for i in range(1, len(G.vertices)): if j == 1: - for u,v in G.edges: + for u, v in G.edges: G.relax(u, v, w) else: - for u,v in edges: + for u, v in edges: G.relax(u, v, w) j = j + 1 - for u,v in G.edges: + for u, v in G.edges: if v.d > u.d + w(u, v): return False return True + + def initialize_signle_source(self, s): for v in self.vertices: v.d = float("Inf") v.p = None s.d = 0 + + def difference_constraints(A, b): '''A algorithm to solve a system of difference constraints Ax <= b by solving a single-source shortest-paths problem using Bellman-Ford @@ -51,8 +56,8 @@ def difference_constraints(A, b): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = 0 for i in range(0, row): - u = A[i].index(-1) + 1 - v = A[i].index(1) + 1 + u = A[i].index(-1) + 1 + v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) weights[(vertices[u], vertices[v])] = b[i] G = Graph(vertices, edges) @@ -60,6 +65,8 @@ def difference_constraints(A, b): return [v.d for v in vertices[1:]] else: return None + + def difference_constraints_with_arbitrary_weight(A, b): ''' An variant to the above difference constraints function that the weight of the edge from the auxiliary vertex to any @@ -71,15 +78,15 @@ def difference_constraints_with_arbitrary_weight(A, b): vertices = [] edges = [] weights = dict() - distribute = sample(xrange(-10, 10), vertices_num) + distribute = sample(range(-10, 10), vertices_num) for i in range(0, vertices_num + 1): vertices.append(Vertex(i)) for i in range(1, vertices_num + 1): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = distribute[i - 1] for i in range(0, row): - u = A[i].index(-1) + 1 - v = A[i].index(1) + 1 + u = A[i].index(-1) + 1 + v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) weights[(vertices[u], vertices[v])] = b[i] G = Graph(vertices, edges) @@ -87,6 +94,8 @@ def difference_constraints_with_arbitrary_weight(A, b): return [v.d for v in vertices[1:]] else: return None + + def equality_constraints(A, b): row = len(A) col = len(A[0]) @@ -100,8 +109,8 @@ def equality_constraints(A, b): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = 0 for i in range(0, row): - u = A[i].index(-1) + 1 - v = A[i].index(1) + 1 + u = A[i].index(-1) + 1 + v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) weights[(vertices[u], vertices[v])] = b[i] edges.append((vertices[v], vertices[u])) @@ -111,6 +120,8 @@ def equality_constraints(A, b): return [v.d for v in vertices[1:]] else: return None + + def difference_constraints_without_aux_vertex(A, b): row = len(A) col = len(A[0]) @@ -121,8 +132,8 @@ def difference_constraints_without_aux_vertex(A, b): for i in range(vertices_num): vertices.append(Vertex(i + 1)) for i in range(0, row): - u = A[i].index(-1) - v = A[i].index(1) + u = A[i].index(-1) + v = A[i].index(1) edges.append((vertices[u], vertices[v])) weights[(vertices[u], vertices[v])] = b[i] G = Graph(vertices, edges) @@ -130,19 +141,25 @@ def difference_constraints_without_aux_vertex(A, b): return [v.d for v in vertices] else: return None + + def Bellman_Ford_without_aux_vertex(G, w): initialize_signle_source_without_aux_vertex(G) for i in range(1, len(G.vertices)): - for u,v in G.edges: + for u, v in G.edges: G.relax(u, v, w) - for u,v in G.edges: + for u, v in G.edges: if v.d > u.d + w(u, v): return False return True + + def initialize_signle_source_without_aux_vertex(G): for v in G.vertices: v.d = 0 v.p = None + + def single_variable_constraints(A, b): row = len(A) col = len(A[0]) diff --git a/constraints_test.py b/constraints_test.py index 7a129a2..8fca7d0 100644 --- a/constraints_test.py +++ b/constraints_test.py @@ -1,61 +1,74 @@ -from constraints import difference_constraints, equality_constraints, difference_constraints_without_aux_vertex, single_variable_constraints, difference_constraints_with_arbitrary_weight +from constraints import difference_constraints, equality_constraints, difference_constraints_without_aux_vertex, \ + single_variable_constraints, difference_constraints_with_arbitrary_weight import unittest from math import floor + class TestConstraints(unittest.TestCase): def test_difference_constraints(self): - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [0, -1, 1, 5, 4, -1, -3, -3] - self.assertEquals(difference_constraints(A, b), [-5, -3, 0, -1, -4]) - A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] + self.assertEqual(difference_constraints(A, b), [-5, -3, 0, -1, -4]) + A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], + [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] b = [1, -4, 2, 7, 5, 10, 2, -1, 3, -8] - self.assertEquals(difference_constraints(A, b), [-5, -3, 0, -1, -6, -8]) - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + self.assertEqual(difference_constraints(A, b), [-5, -3, 0, -1, -6, -8]) + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [4, 5, -6, 1, 3, 5, 10, -4, 8] - self.assertEquals(difference_constraints(A, b), None) - A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] + self.assertEqual(difference_constraints(A, b), None) + A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], + [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] b = [1, -4, 2, 7.3, 5, 10.1, 2.9, -1.11, 3, -8.6] c = [int(floor(i)) for i in b] - print difference_constraints(A, c) + print(difference_constraints(A, c)) def test_equality_constraints(self): - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [0, -1, 1, 5, 4, -1, -3, -3] - self.assertEquals(equality_constraints(A, b), None) - A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] + self.assertEqual(equality_constraints(A, b), None) + A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], + [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] b = [1, -4, 2, 7, 5, 10, 2, -1, 3, -8] - self.assertEquals(equality_constraints(A, b), None) - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + self.assertEqual(equality_constraints(A, b), None) + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [4, 5, -6, 1, 3, 5, 10, -4, 8] - self.assertEquals(equality_constraints(A, b), None) + self.assertEqual(equality_constraints(A, b), None) A = [[-1, 1, 0], [0, -1, 1], [-1, 0, 1]] b = [1, 1, 2] - self.assertEquals(equality_constraints(A, b), [-2, -1, 0]) + self.assertEqual(equality_constraints(A, b), [-2, -1, 0]) + def test_difference_constraints_without_aux_vertex(self): - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [0, -1, 1, 5, 4, -1, -3, -3] - self.assertEquals(difference_constraints_without_aux_vertex(A, b), [-5, -3, 0, -1, -4]) - A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] + self.assertEqual(difference_constraints_without_aux_vertex(A, b), [-5, -3, 0, -1, -4]) + A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], + [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] b = [1, -4, 2, 7, 5, 10, 2, -1, 3, -8] - self.assertEquals(difference_constraints_without_aux_vertex(A, b), [-5, -3, 0, -1, -6, -8]) - A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] + self.assertEqual(difference_constraints_without_aux_vertex(A, b), [-5, -3, 0, -1, -6, -8]) + A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], + [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] b = [4, 5, -6, 1, 3, 5, 10, -4, 8] - self.assertEquals(difference_constraints_without_aux_vertex(A, b), None) + self.assertEqual(difference_constraints_without_aux_vertex(A, b), None) + def test_single_variable_constraints(self): A = [[1, 0], [0, 1], [-1, 0], [0, -1], [1, 0]] b = [3, 1, 5, -1, 2] - self.assertEquals(single_variable_constraints(A, b), [2, 1]) + self.assertEqual(single_variable_constraints(A, b), [2, 1]) A = [[1, 0], [0, 1], [-1, 0], [0, -1], [1, 0]] b = [3, -1, 5, -1, 2] - self.assertEquals(single_variable_constraints(A, b), None) + self.assertEqual(single_variable_constraints(A, b), None) # def test_difference_constraints_with_arbitrary_weight(self): # A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, 0, -1], [-1, 0, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] # b = [0, -1, 1, 5, 4, -1, -3, -3] -# self.assertEquals(difference_constraints_with_arbitrary_weight(A, b), [-5, -3, 0, -1, -4]) +# self.assertEqual(difference_constraints_with_arbitrary_weight(A, b), [-5, -3, 0, -1, -4]) # A = [[1, -1, 0, 0, 0, 0], [1, 0, 0, -1, 0, 0], [0, 1, -1, 0, 0, 0], [0, 1, 0, 0, -1, 0], [0, 1, 0, 0, 0, -1], [0, 0, 1, 0, 0, -1], [0, -1, 0, 1, 0, 0], [-1, 0, 0, 0, 1, 0], [0, 0, 0, -1, 1, 0], [0, 0, -1, 0, 0, 1]] # b = [1, -4, 2, 7, 5, 10, 2, -1, 3, -8] -# self.assertEquals(difference_constraints_with_arbitrary_weight(A, b), [-5, -3, 0, -1, -6, -8]) +# self.assertEqual(difference_constraints_with_arbitrary_weight(A, b), [-5, -3, 0, -1, -6, -8]) # A = [[1, -1, 0, 0, 0], [1, 0, 0, 0, -1], [0, 1, 0, -1, 0], [0, -1, 1, 0, 0], [-1, 0, 0, 1, 0], [0, 0, -1, 1, 0], [0, 0, 0, 1, -1], [0, 0, -1, 0, 1], [0, 0, 0, -1, 1]] # b = [4, 5, -6, 1, 3, 5, 10, -4, 8] -# self.assertEquals(difference_constraints_with_arbitrary_weight(A, b), None) - +# self.assertEqual(difference_constraints_with_arbitrary_weight(A, b), None) diff --git a/contains.py b/contains.py index 816e910..c65d90c 100644 --- a/contains.py +++ b/contains.py @@ -1,12 +1,17 @@ #!/usr/bin/env ipython def contains(x, n): - '''CLRS Exercise 16.2-5 + """ + CLRS Exercise 16.2-5 An algorithm that, given a set {x1, x2, ... ,xn} of points on the real line, determines the smallest set of unit-length closed intervals that contains - all of the given points.''' + all of the given points. + :param x: + :param n: + :return: + """ x.sort() - print x + print(x) i = 0 a = float("-Inf") S = set() @@ -15,5 +20,5 @@ def contains(x, n): S = S.union({(x[i], x[i] + 1)}) a = x[i] + 1 i = i + 1 - print S + print(S) return S diff --git a/contains_test.py b/contains_test.py index 55d405f..1647566 100644 --- a/contains_test.py +++ b/contains_test.py @@ -3,10 +3,10 @@ import unittest from contains import contains + class TestContains(unittest.TestCase): def test_contains(self): x = [1, 1.5, 3.5, 2.3, 10.01] - self.assertEquals(contains(x, 5), {(1, 2), (2.3, 3.3), (3.5, 4.5), (10.01, 11.01)}) + self.assertEqual(contains(x, 5), {(1, 2), (2.3, 3.3), (3.5, 4.5), (10.01, 11.01)}) x = [3.5, 5.2, -1.1, -4, -12, -11.33] - self.assertEquals(contains(x, 6), {(-12, -11), (-4, -3), (-1.1, -0.10000000000000009), (3.5, 4.5), (5.2, 6.2)}) - + self.assertEqual(contains(x, 6), {(-12, -11), (-4, -3), (-1.1, -0.10000000000000009), (3.5, 4.5), (5.2, 6.2)}) diff --git a/counting_sort_test.py b/counting_sort_test.py index ace37b9..5eee259 100644 --- a/counting_sort_test.py +++ b/counting_sort_test.py @@ -1,12 +1,13 @@ import unittest from counting_sort import counting_sort + class TestHeap(unittest.TestCase): def test_counting_sort(self): - A = [2,5,3,0,2,3,0,3] + A = [2, 5, 3, 0, 2, 3, 0, 3] B = [] for i in range(0, len(A)): B.append(0) counting_sort(A, B, 5) - self.assertEquals(B, [0,0,2,2,3,3,3,5]) - self.assertEquals(A, [2,5,3,0,2,3,0,3]) + self.assertEqual(B, [0, 0, 2, 2, 3, 3, 3, 5]) + self.assertEqual(A, [2, 5, 3, 0, 2, 3, 0, 3]) diff --git a/cut_rod.py b/cut_rod.py index 1c7473f..2689136 100644 --- a/cut_rod.py +++ b/cut_rod.py @@ -5,7 +5,9 @@ def bottom_up_cut_rod(p, n): for i in range(1, j + 1): q = max(q, p[i - 1] + r[j - i]) r[j] = q - return r[n] + return r[n] + + def bottom_up_cut_rod_two_subproblem(p, n): r = [0] * (n + 1) for i in range(1, n + 1): @@ -15,10 +17,14 @@ def bottom_up_cut_rod_two_subproblem(p, n): for i in range(1, j + 1): q = max(q, r[i] + r[j - i]) r[j] = q - return r[n] + return r[n] + + def memoized_cut_rod(p, n): r = [float("-Inf")] * n return memoized_cut_rod_aux(p, n, r) + + def memoized_cut_rod_aux(p, n, r): if n == 0: return 0 @@ -29,6 +35,8 @@ def memoized_cut_rod_aux(p, n, r): q = max(q, p[i - 1] + memoized_cut_rod_aux(p, n - i, r)) r[n - 1] = q return q + + def extended_bottom_up_cut_rod(p, n): r = [0] * (n + 1) s = [0] * (n + 1) @@ -39,12 +47,16 @@ def extended_bottom_up_cut_rod(p, n): q = p[i - 1] + r[j - i] s[j] = i r[j] = q - return r,s + return r, s + + def print_cut_rod_solution(p, n, cut): - r,s = cut(p, n) + r, s = cut(p, n) while n != 0: - print s[n] + print(s[n]) n = n - s[n] + + def bottom_up_cut_rod_with_fixed_cut_cost(p, n, c): r = [0] * (n + 1) for j in range(1, n + 1): @@ -53,12 +65,16 @@ def bottom_up_cut_rod_with_fixed_cut_cost(p, n, c): q = max(q, r[i] + r[j - i] - c) q = max(q, p[j - 1]) r[j] = q - return r[n] + return r[n] + + def extended_memoized_cut_rod(p, n): r = [float("-Inf")] * n s = [0] * (n + 1) extended_memoized_cut_rod_aux(p, n, r, s) - return r,s + return r, s + + def extended_memoized_cut_rod_aux(p, n, r, s): if n == 0: return 0 @@ -66,7 +82,7 @@ def extended_memoized_cut_rod_aux(p, n, r, s): return r[n - 1] q = float("-Inf") for i in range(1, n + 1): - value = p[i - 1] + extended_memoized_cut_rod_aux(p, n -i, r, s) + value = p[i - 1] + extended_memoized_cut_rod_aux(p, n - i, r, s) if q < value: q = value s[n] = i diff --git a/cut_rod_test.py b/cut_rod_test.py index 13a9d6a..1ddff11 100755 --- a/cut_rod_test.py +++ b/cut_rod_test.py @@ -1,32 +1,38 @@ #!/usr/bin/env ipython import unittest -from cut_rod import bottom_up_cut_rod, bottom_up_cut_rod_two_subproblem, memoized_cut_rod, print_cut_rod_solution, bottom_up_cut_rod_with_fixed_cut_cost, extended_memoized_cut_rod +from cut_rod import bottom_up_cut_rod, bottom_up_cut_rod_two_subproblem, memoized_cut_rod, print_cut_rod_solution, \ + bottom_up_cut_rod_with_fixed_cut_cost, extended_memoized_cut_rod + class TestCutRod(unittest.TestCase): def test_bottom_up_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): - self.assertEquals(bottom_up_cut_rod(p, values[i]), values[i + 1]) + self.assertEqual(bottom_up_cut_rod(p, values[i]), values[i + 1]) + def test_bottom_up_cut_rod_two_subproblem(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): - self.assertEquals(bottom_up_cut_rod_two_subproblem(p, values[i]), values[i + 1]) + self.assertEqual(bottom_up_cut_rod_two_subproblem(p, values[i]), values[i + 1]) + def test_memoized_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): - self.assertEquals(memoized_cut_rod(p, values[i]), values[i + 1]) + self.assertEqual(memoized_cut_rod(p, values[i]), values[i + 1]) + def test_bottom_up_cut_rod_with_fixed_cut_cost(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11, 6, 17, 7, 17, 8, 20, 9, 24, 10, 30] for i in range(0, len(values), 2): - self.assertEquals(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 2), values[i + 1]) + self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 2), values[i + 1]) values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11.5, 6, 17, 7, 17, 8, 20.5, 9, 24, 10, 30] for i in range(0, len(values), 2): - self.assertEquals(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 1.5), values[i + 1]) + self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 1.5), values[i + 1]) + def test_print_rod_solution(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] diff --git a/depth_tree.py b/depth_tree.py index 4440928..7feb09e 100644 --- a/depth_tree.py +++ b/depth_tree.py @@ -4,24 +4,30 @@ from rb_tree import rb_node, rb_tree + class depth_node(rb_node): def __init__(self, key, p, left, right, color, depth): rb_node.__init__(self, key, p, left, right, color) self.depth = depth + def update_depth_whole_tree(self, amount): if self.depth != -1: self.left.update_depth_whole_tree(amount) self.depth = self.depth + amount self.right.update_depth_whole_tree(amount) + + class depth_tree(rb_tree): nil = depth_node(None, None, None, None, 1, -1) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(depth_node(i, None, None, None, 0, 0)) else: - print "Not invalid argument" + print("Not invalid argument") + def left_rotate(self, x): y = x.right x.right = y.left @@ -40,6 +46,7 @@ def left_rotate(self, x): y.depth = y.depth - 1 x.left.update_depth_whole_tree(1) y.right.update_depth_whole_tree(-1) + def right_rotate(self, y): x = y.left y.left = x.right @@ -58,6 +65,7 @@ def right_rotate(self, y): y.depth = y.depth + 1 x.left.update_depth_whole_tree(-1) y.right.update_depth_whole_tree(1) + def insert(self, z): y = self.nil x = self.root @@ -79,8 +87,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def delete(self, z): y = z y_original_color = y.color diff --git a/depth_tree_test.py b/depth_tree_test.py index c9d6ac2..f37db6e 100755 --- a/depth_tree_test.py +++ b/depth_tree_test.py @@ -7,21 +7,25 @@ class TestRbtree(unittest.TestCase): def test_insert_one(self): T = depth_tree([41]) self.wrap(T, 41, 0) + def test_insert_two(self): T = depth_tree([41, 38]) self.wrap(T, 41, 0) self.wrap(T, 38, 1) + def test_insert_three(self): T = depth_tree([41, 38, 31]) self.wrap(T, 38, 0) self.wrap(T, 31, 1) self.wrap(T, 41, 1) + def test_insert_four(self): T = depth_tree([41, 38, 31, 12]) self.wrap(T, 38, 0) self.wrap(T, 31, 1) self.wrap(T, 41, 1) self.wrap(T, 12, 2) + def test_insert_five(self): T = depth_tree([41, 38, 31, 12, 19]) self.wrap(T, 38, 0) @@ -29,6 +33,7 @@ def test_insert_five(self): self.wrap(T, 41, 1) self.wrap(T, 12, 2) self.wrap(T, 31, 2) + def test_insert_six(self): T = depth_tree([41, 38, 31, 12, 19, 9]) self.wrap(T, 38, 0) @@ -37,6 +42,7 @@ def test_insert_six(self): self.wrap(T, 12, 2) self.wrap(T, 31, 2) self.wrap(T, 9, 3) + def test_delete_one(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -45,6 +51,7 @@ def test_delete_one(self): self.wrap(T, 41, 1) self.wrap(T, 12, 2) self.wrap(T, 31, 2) + def test_delete_two(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -53,6 +60,7 @@ def test_delete_two(self): self.wrap(T, 19, 1) self.wrap(T, 41, 1) self.wrap(T, 31, 2) + def test_delete_three(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -61,6 +69,7 @@ def test_delete_three(self): self.wrap(T, 38, 0) self.wrap(T, 31, 1) self.wrap(T, 41, 1) + def test_delete_four(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -69,6 +78,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, 0) self.wrap(T, 41, 1) + def test_delete_five(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -77,6 +87,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 41, 0) + def test_delete_six(self): T = depth_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -85,8 +96,11 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.nil.depth, -1) + self.assertEqual(T.nil.depth, -1) + def wrap(self, tree, node, depth): - self.assertEquals(tree.iterative_tree_search(node).depth, depth) + self.assertEqual(tree.iterative_tree_search(node).depth, depth) + + if __name__ == '__main__': unittest.main() diff --git a/disjoint_sets_forest.py b/disjoint_sets_forest.py index 09ff777..28f5ee7 100644 --- a/disjoint_sets_forest.py +++ b/disjoint_sets_forest.py @@ -1,24 +1,28 @@ #!/usr/bin/env ipython + class node(object): def __init__(self, key): self.key = key - #key.index = self + # key.index = self self.p = self self.rank = 0 self.child = [] + def union(self, y): self.find_set().link(y.find_set()) + def link(self, y): x = self if x.rank > y.rank: - x.child.append(y) + x.child.append(y) y.p = x else: - y.child.append(x) + y.child.append(x) x.p = y if x.rank == y.rank: y.rank = y.rank + 1 + def find_set(self): y = self x = self @@ -28,15 +32,17 @@ def find_set(self): z = x x = x.p z.p = y -# print y.key + # print( y.key) return y + def print_set(self): x = self while x != x.p: x = x.p x.print_set_aux() + def print_set_aux(self): - print self.key + print(self.key) if len(self.child) == 0: return for child in self.child: diff --git a/disjoint_sets_forest_test.py b/disjoint_sets_forest_test.py index 7e1ce6b..8dac3ce 100644 --- a/disjoint_sets_forest_test.py +++ b/disjoint_sets_forest_test.py @@ -2,40 +2,42 @@ import unittest import disjoint_sets_forest as ds + + class TestDisjointSets(unittest.TestCase): def test_forest(self): pool = [0] * 17 for i in range(1, 17): pool[i] = ds.node(i) for i in range(1, 17): - self.assertEquals(pool[i].p, pool[i]) + self.assertEqual(pool[i].p, pool[i]) for i in range(1, 16, 2): pool[i].union(pool[i + 1]) parent_list = [2, 2, 4, 4, 6, 6, 8, 8, 10, 10, 12, 12, 14, 14, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) for i in range(1, 14, 4): pool[i].union(pool[i + 2]) parent_list = [2, 4, 4, 4, 6, 8, 8, 8, 10, 12, 12, 12, 14, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) pool[1].union(pool[5]) parent_list = [4, 4, 4, 8, 8, 8, 8, 8, 10, 12, 12, 12, 14, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) pool[11].union(pool[13]) parent_list = [4, 4, 4, 8, 8, 8, 8, 8, 10, 12, 12, 16, 16, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) pool[1].union(pool[10]) parent_list = [8, 4, 4, 8, 8, 8, 8, 16, 10, 16, 12, 16, 16, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) self.assertTrue(pool[2].find_set() == pool[16]) parent_list = [8, 16, 4, 16, 8, 8, 8, 16, 10, 16, 12, 16, 16, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) self.assertTrue(pool[9].find_set() == pool[16]) parent_list = [8, 16, 4, 16, 8, 8, 8, 16, 16, 16, 12, 16, 16, 16, 16, 16] for i in range(1, 17): - self.assertEquals(pool[i].p, pool[parent_list[i - 1]]) + self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) diff --git a/disjoint_sets_test.py b/disjoint_sets_test.py index e78f8f4..6026884 100644 --- a/disjoint_sets_test.py +++ b/disjoint_sets_test.py @@ -2,14 +2,16 @@ import unittest import disjoint_sets_linked_list as ds + + class TestDisjointSets(unittest.TestCase): def test_linked_lists_with_head_and_tail(self): pool = [0] * 17 for i in range(1, 17): pool[i] = ds.node(i) a = ds.header(pool[i]) - self.assertEquals(a.head, pool[i]) - self.assertEquals(a.tail, pool[i]) + self.assertEqual(a.head, pool[i]) + self.assertEqual(a.tail, pool[i]) for i in range(1, 16, 2): pool[i].union(pool[i + 1]) for i in range(1, 14, 4): @@ -19,6 +21,7 @@ def test_linked_lists_with_head_and_tail(self): pool[1].union(pool[10]) self.assertTrue(pool[2].find_set() == pool[1]) self.assertTrue(pool[9].find_set() == pool[1]) + def test_linked_lists_no_tail(self): pool = [0] * 17 for i in range(1, 17): diff --git a/extended_bottom_up_cut_rod.py b/extended_bottom_up_cut_rod.py index ff4bdb2..316e42a 100644 --- a/extended_bottom_up_cut_rod.py +++ b/extended_bottom_up_cut_rod.py @@ -8,10 +8,11 @@ def extended_bottom_up_cut_rod(p, n): q = p[i - 1] + r[j - i] s[j] = i r[j] = q - return r, s + return r, s + def print_cut_rod_solution(p, n): - r,s = extended_bottom_up_cut_rod(p, n) + r, s = extended_bottom_up_cut_rod(p, n) while n > 0: - print s[n] + print(s[n]) n = n - s[n] diff --git a/fibonacci_heap.py b/fibonacci_heap.py index 53739b8..0f7434b 100644 --- a/fibonacci_heap.py +++ b/fibonacci_heap.py @@ -5,8 +5,10 @@ class fibonacci_node(object): mark = False left = None right = None + def __init__(self, k): self.key = k + def __iter__(self): '''generate a list of children of the node for iteration''' self.children = [] @@ -20,18 +22,21 @@ def __iter__(self): else: break return self + def next(self): if self.index < len(self.children): self.index = self.index + 1 return self.children[self.index - 1] else: raise StopIteration + def insert(self, x): '''insert x to the left of node''' x.left = self.left x.right = self self.left.right = x - self.left = x + self.left = x + def concatenate(self, x): '''concatenate two lists represented by the node and x, x mustn't be None''' @@ -39,9 +44,11 @@ def concatenate(self, x): x.right.left = self.left self.left = x x.right = self + def remove(self): - self.left.right = self.right + self.left.right = self.right self.right.left = self.left + def add_child(self, y): self.degree = self.degree + 1 y.mark = False @@ -51,8 +58,9 @@ def add_child(self, y): y.left = y y.right = y else: - self.child.insert(y) - print "y.left.key = {}, y.right.key = {}".format(y.left.key, y.right.key) + self.child.insert(y) + print("y.left.key = {}, y.right.key = {}".format(y.left.key, y.right.key)) + def remove_child(self, y): self.degree = self.degree - 1 if y.right == y: @@ -62,10 +70,13 @@ def remove_child(self, y): y.remove() else: y.remove() + + class fibonacci_heap(object): def __init__(self): self.n = 0 self.minimum = None + def __iter__(self): '''generate a list of children of the node for iteration''' self.root_list = [] @@ -79,18 +90,20 @@ def __iter__(self): else: break return self + def next(self): if self.index < len(self.root_list): self.index = self.index + 1 return self.root_list[self.index - 1] else: raise StopIteration + def __repr__(self): s = '' x = self.minimum if x != None: while True: - s = s + '\t' + str(x.key) + s = s + '\t' + str(x.key) if x == self.minimum.left: break else: @@ -98,6 +111,7 @@ def __repr__(self): return s else: return '' + def insert(self, x): '''insert the node x into the root list of fibonacci heap''' x.p = None @@ -110,8 +124,10 @@ def insert(self, x): if x.key < self.minimum.key: self.minimum = x self.n = self.n + 1 + def minimum(self): return self.minimum + def union(self, h): cat = fibonacci_heap() if self.minimum == None: @@ -126,6 +142,7 @@ def union(self, h): cat.minimum = h.minimum cat.n = self.n + h.n return cat + def extract_min(self): z = self.minimum if z != None: @@ -139,6 +156,7 @@ def extract_min(self): self.consolidate() self.n = self.n - 1 return z + def consolidate(self): D = self.n / 2 A = [None] * (D + 1) @@ -147,12 +165,12 @@ def consolidate(self): for w in self: x = w d = x.degree - print 'w.key = {}'.format(w.key) - print 'w.degree = {}'.format(w.degree) + print('w.key = {}'.format(w.key)) + print('w.degree = {}'.format(w.degree)) while A[d] != None: y = A[d] if x.key > y.key: - x,y = y,x + x, y = y, x self.link(y, x) A[d] = None d = d + 1 @@ -161,12 +179,14 @@ def consolidate(self): for i in A: if i != None: self.insert(i) + def link(self, y, x): y.remove() x.add_child(y) + def decrease_key(self, x, k): if k > x.key: - print "new key is greater than current key" + print("new key is greater than current key") return x.key = k y = x.p @@ -175,10 +195,12 @@ def decrease_key(self, x, k): self.cascading_cut(y) if x.key < self.minimum.key: self.minimum = x + def cut(self, x, y): y.remove_child(x) x.mark = False self.insert(x) + def cascading_cut(self, y): z = y.p if z != None: @@ -187,6 +209,7 @@ def cascading_cut(self, y): else: self.cut(y, z) self.cascading_cut(z) + def delete(self, x): self.decrease_key(x, float("-Inf")) self.extract_min() diff --git a/graph.py b/graph.py index d1a019d..43e668d 100644 --- a/graph.py +++ b/graph.py @@ -1,7 +1,8 @@ -from queue import queue +from queue import queue import disjoint_sets_forest as dsf import sys + class Vertex(object): def __init__(self, key): self.key = key @@ -10,18 +11,19 @@ def __repr__(self): return str(self.key) def print_path(self, v): - '''print out the vertices on a shortest path from s to + '''print( out the vertices on a shortest path from s to) v, assuming that BFS has already computed a breadth-first tree''' if self == v: - print self, + print(self, ) elif v.p == None: - print "No path from {} to {} exists".format(self.key, v.key) + print("No path from {} to {} exists".format(self.key, v.key)) else: self.print_path(v.p) - print v, + print(v, ) + class Graph(object): - def __init__(self, vertices = tuple(), edges = tuple(), directed = True): + def __init__(self, vertices=tuple(), edges=tuple(), directed=True): self.directed = directed self.vertices = set(vertices) self.edges = set() @@ -49,14 +51,14 @@ def _addEdge(self, u, v): if self.directed: self.adj[u].add(v) self.edges.add((u, v)) - elif u != v: # undirected graph does not allow self loop + elif u != v: # undirected graph does not allow self loop self.adj[u].add(v) self.edges.add((u, v)) self.adj[v].add(u) self.edges.add((v, u)) - def _addVertex(self, u, edges = tuple()): - self.vertices.add(u) + def _addVertex(self, u, edges=tuple()): + self.vertices.add(u) for u, v in edges: self._addEdge(u, v) @@ -144,7 +146,7 @@ def _is_cyclic_aux(self, u): def topological_sort(self): self.dfs() - return sorted(self.vertices, key = lambda x: x.f, reverse = True) + return sorted(self.vertices, key=lambda x: x.f, reverse=True) def print_all_edges(self): s = next(iter(self.vertices)) @@ -154,15 +156,16 @@ def print_all_edges(self): def _print_all_edges_aux(self, u): for v in self.adj[u]: if u == v.p: - print (u, v) + print((u, v)) self._print_all_edges_aux(v) - print (v, u) + print((v, u)) else: pass + def printAllEdges(self): self.status = dict() s = next(iter(self.vertices)) - print "key of s is {}".format(s.key) + print("key of s is {}".format(s.key)) self.printAllEdges_aux(s) def printAllEdges_aux(self, u): @@ -172,9 +175,9 @@ def printAllEdges_aux(self, u): except KeyError: self.status[(u, v)] = 1 self.status[(v, u)] = 1 - print (u, v) + print((u, v)) self.printAllEdges_aux(v) - print (v, u) + print((v, u)) def path_num(self, s, t): ''' @@ -208,7 +211,7 @@ def strongly_connected_components(self): u.p = None time = 0 cc = 0 - for u in sorted(self.vertices, key = lambda u: u.f, reverse = True): + for u in sorted(self.vertices, key=lambda u: u.f, reverse=True): if u.color == 0: cc = cc + 1 t.strongly_connected_components_dfs_visit(u) @@ -226,6 +229,7 @@ def strongly_connected_components_dfs_visit(self, u): u.color = 2 time = time + 1 u.f = time + def simplified(self): '''create a simplified graph that has the same strong connected components and component graph as G and that is as small @@ -233,6 +237,7 @@ def simplified(self): self.dfs() t = self.transpose() return t.simplified_dfs() + def simplified_dfs(self): global time, cc, status status = dict() @@ -242,7 +247,7 @@ def simplified_dfs(self): u.p = None time = 0 cc = 0 - for u in sorted(self.vertices, key = lambda u: u.f, reverse = True): + for u in sorted(self.vertices, key=lambda u: u.f, reverse=True): if u.color == 0: stack = [] cc = cc + 1 @@ -252,6 +257,7 @@ def simplified_dfs(self): if len(stack) > 1: s._addEdge(stack[len(stack) - 1], stack[0]) return s + def simplified_dfs_visit(self, u, stack, s): global time, cc, status stack.append(u) @@ -267,18 +273,22 @@ def simplified_dfs_visit(self, u, stack, s): try: st = status[(v.cc, u.cc)] except KeyError: - status[(v.cc, u.cc)] = 1 - s._addEdge(v, u) + status[(v.cc, u.cc)] = 1 + s._addEdge(v, u) u.color = 2 time = time + 1 u.f = time + def component_graph(self): - '''compute the component graph of a directed graph - there is at most one edge between two vertices in the component graph''' - global time, cc, cg, status, vertices_list + """ + compute the component graph of a directed graph + there is at most one edge between two vertices in the component graph + :return: + """ + global time, cc, cg, status, vertices_list self.dfs() - t = self.transpose() - for u in t.vertices: + t = self.transpose() + for u in t.vertices: u.color = 0 u.p = None time = 0 @@ -286,13 +296,14 @@ def component_graph(self): status = dict() vertices_list = list() cg = Graph() - for u in sorted(self.vertices, key = lambda u: u.f, reverse = True): + for u in sorted(self.vertices, key=lambda u: u.f, reverse=True): if u.color == 0: cc = cc + 1 vertices_list.append(Vertex(cc)) cg._addVertex(vertices_list[cc - 1]) t.component_graph_dfs_visit(u) return cg + def component_graph_dfs_visit(self, u): global time, cc, cg, vertices_list u.cc = cc @@ -307,18 +318,20 @@ def component_graph_dfs_visit(self, u): try: st = status[(v.cc, u.cc)] except KeyError: - status[(v.cc, u.cc)] = 1 - cg._addEdge(vertices_list[v.cc - 1], vertices_list[u.cc - 1]) + status[(v.cc, u.cc)] = 1 + cg._addEdge(vertices_list[v.cc - 1], vertices_list[u.cc - 1]) u.color = 2 time = time + 1 u.f = time + def semiconnected(self): cg = self.component_graph() - vertices_list = sorted(cg.vertices, key = lambda u: u.key, reverse = False) + vertices_list = sorted(cg.vertices, key=lambda u: u.key, reverse=False) for i in range(0, len(vertices_list) - 1): if vertices_list[i + 1] not in cg.adj[vertices_list[i]]: return False return True + def cut(self, x, y, w): '''For a given edge (x, y) contained in some minimum spanning tree, form a minimum spanning tree that contains (x, y) using a method like Prim's algorithm, @@ -340,6 +353,7 @@ def cut(self, x, y, w): v.root = u.root q.heap_decrease_key(v.index, w(u, v)) v.p = u + def alledges_undirected_dfs(self): global time, l for u in self.vertices: @@ -351,6 +365,7 @@ def alledges_undirected_dfs(self): if u.color == 0: self.alledges_undirected_dfs_visit(u) return l + def alledges_undirected_dfs_visit(self, u): global time, l time = time + 1 @@ -362,20 +377,22 @@ def alledges_undirected_dfs_visit(self, u): v.p = u self.alledges_undirected_dfs_visit(v) elif v.color == 1 and u.p != v: - l.append((u, v)) + l.append((u, v)) u.color = 2 time = time + 1 u.f = time + def Kruskal(self, w): A = set() for v in self.vertices: dsf_node(v) -# ls = self.alledges_undirected_dfs() - for u,v in sorted(self.edges, key=lambda x: w(x[0], x[1]), reverse = False): + # ls = self.alledges_undirected_dfs() + for u, v in sorted(self.edges, key=lambda x: w(x[0], x[1]), reverse=False): if u.index.find_set() != v.index.find_set(): - A = A.union({(u,v)}) + A = A.union({(u, v)}) u.index.union(v.index) return A + def Prim(self, w, r): '''G.Prim(weight, root) -- Given weight function and an arbitrary vertex root of the graph G, @@ -391,26 +408,27 @@ def Prim(self, w, r): if v in q and w(u, v) < v.weight: v.p = u q.heap_decrease_key(v.index, w(u, v)) -# def Prim_vEB(self, w, r, bound): -# '''G.Prim(weight, root) -- Given weight function -# and an arbitrary vertex root of the graph G, -# compute minimum spanning tree using Prim's algorithm''' -# for v in self.vertices: -# v.weight = bound - 1 -# v.p = None -# r.weight = 0 -# t = vEB_node(bound) -# for u in self.vertices: -# t.insert(u) -# while t.size > 0: -# u = t.minimum() -# t.delete(u) -# for v in self.adj[u]: -# if t.member(v) and w(u, v) < v.weight: -# v.p = u -# t.delete(v) -# v.weight = w(u, v) -# t.insert(v) + + # def Prim_vEB(self, w, r, bound): + # '''G.Prim(weight, root) -- Given weight function + # and an arbitrary vertex root of the graph G, + # compute minimum spanning tree using Prim's algorithm''' + # for v in self.vertices: + # v.weight = bound - 1 + # v.p = None + # r.weight = 0 + # t = vEB_node(bound) + # for u in self.vertices: + # t.insert(u) + # while t.size > 0: + # u = t.minimum() + # t.delete(u) + # for v in self.adj[u]: + # if t.member(v) and w(u, v) < v.weight: + # v.p = u + # t.delete(v) + # v.weight = w(u, v) + # t.insert(v) def Bellman_Ford(self, w, s): ''' The Bellman-Ford algorithm solves the single-source @@ -424,21 +442,24 @@ def Bellman_Ford(self, w, s): ''' self.initialize_signle_source(s) for i in range(1, len(self.vertices)): - for u,v in self.edges: + for u, v in self.edges: self.relax(u, v, w) - for u,v in self.edges: + for u, v in self.edges: if v.d > u.d + w(u, v): return False return True + def initialize_signle_source(self, s): for v in self.vertices: v.d = float("Inf") v.p = None s.d = 0 + def relax(self, u, v, w): if v.d > u.d + w(u, v): v.d = u.d + w(u, v) v.p = u + def Bellman_Ford_modified(self, w, s): ''' Given a weighted, directed graph G = (V, E) with @@ -453,17 +474,18 @@ def Bellman_Ford_modified(self, w, s): self.initialize_signle_source(s) for i in range(1, len(self.vertices)): if modified: - for u,v in self.edges: + for u, v in self.edges: number = self.relax_modified(u, v, w) + number if number == 0: modified = False number = 0 else: break - for u,v in self.edges: + for u, v in self.edges: if v.d > u.d + w(u, v): return False return True + def relax_modified(self, u, v, w): if v.d > u.d + w(u, v): v.d = u.d + w(u, v) @@ -471,6 +493,7 @@ def relax_modified(self, u, v, w): return 1 else: return 0 + def dag_shortest_paths(self, w, s): ''' compute shortest paths from a single source @@ -481,6 +504,7 @@ def dag_shortest_paths(self, w, s): for u in l: for v in self.adj[u]: self.relax(u, v, w) + def dag_shortest_paths_modified(self, s): ''' In the PERT chart analysis, vertices repre @@ -503,11 +527,12 @@ def dag_shortest_paths_modified(self, s): Ga = Graph(vertices, edges) Ga.dag_shortest_paths(lambda u, v: -u.weight, s) u = sink - l = [] + l = [] while u.p != None: - l.append(u.p) + l.append(u.p) u = u.p return l[::-1] + def total_path_number(self): ''' A algorithm to count the total number of paths in @@ -518,6 +543,7 @@ def total_path_number(self): for v in self.vertices: number = number + v.num return number + def _total_path_number_dfs(self): global time for u in self.vertices: @@ -528,6 +554,7 @@ def _total_path_number_dfs(self): for u in self.vertices: if u.color == 0: self._total_path_number_dfs_visit(u) + def _total_path_number_dfs_visit(self, u): global time time = time + 1 @@ -541,6 +568,7 @@ def _total_path_number_dfs_visit(self, u): u.color = 2 time = time + 1 u.f = time + def Dijkstra(self, w, s): ''' Dijkstra's algorithm solves the single-source shortest-paths problem @@ -558,6 +586,7 @@ def Dijkstra(self, w, s): v.d = u.d + w(u, v) v.p = u Q.heap_decrease_key(v.index, u.d + w(u, v)) + def Dijkstra_modified(self, w, s, W): ''' A algorithm to the the case when the values of @@ -576,10 +605,10 @@ def Dijkstra_modified(self, w, s, W): i = i + 1 if i > W * len(self.vertices): break - print "i = {}".format(i) + print("i = {}".format(i)) u = A[i].pop() - print u - print A[i] + print(u) + print(A[i]) S.add(u) for v in self.adj[u]: if v.d > u.d + w(u, v): @@ -598,15 +627,15 @@ def single_edge(self): the edges in E with all multiple edges between two vertices replaced by a single edge and with all self-loops removed ''' - return Graph(self.vertices, self.edges, directed = False) + return Graph(self.vertices, self.edges, directed=False) def union(self, G2): if self.directed != G2.directed: - print "The two graphs must be either both directed graphs or both undirected graphs" + print("The two graphs must be either both directed graphs or both undirected graphs") return None vertices = self.vertices | G2.vertices edges = self.edges | G2.edges - return Graph(vertices, edges, directed = self.directed) + return Graph(vertices, edges, directed=self.directed) def square(self): ''' @@ -624,27 +653,28 @@ def square(self): def height(self, u): maximum = 0 - print u.key + print(u.key) for v in self.adj[u]: if v.p == u: maximum = max(maximum, self.height(v) + 1) u.h = maximum - print u.key, u.h + print(u.key, u.h) return u.h + def mht(self): s = next(iter(self.vertices)) self.bfs(s) self.height(s) s.mh = s.h for u in self.adj[s]: - self.mhtAux(u) - - def mhtAux(self, u): + self._mht_aux(u) + + def _mht_aux(self, u): u.mh = max(u.h, u.p.mh + 1) for v in self.adj[u]: if v.p == u: - self.mhtAux(v) - + self._mht_aux(v) + class dsf_node(dsf.node): def __init__(self, key): @@ -654,6 +684,7 @@ def __init__(self, key): self.rank = 0 self.child = [] + class max_heap(list): def __init__(self, data, attr): list.__init__(self, data) @@ -663,14 +694,19 @@ def __init__(self, data, attr): self.attr = attr self.heap_size = self.length self.build_max_heap() + def __contains__(self, y): return y in self[0:self.heap_size] + def left(self, i): return 2 * i + 1 + def right(self, i): return 2 * i + 2 + def parent(self, i): - return (i - 1) / 2 + return (i - 1) // 2 + def max_heapify(self, i): l = self.left(i) r = self.right(i) @@ -680,19 +716,22 @@ def max_heapify(self, i): largest = i if (r <= (self.heap_size - 1)) and (self[r].__dict__[self.attr] > self[largest].__dict__[self.attr]): largest = r - if largest != i: - self[i],self[largest] = self[largest],self[i] + if largest != i: + self[i], self[largest] = self[largest], self[i] self[i].index = i self[largest].index = largest self.max_heapify(largest) + def build_max_heap(self): self.heap_size = self.length - for i in range(self.length / 2 - 1, -1, -1): + for i in range(self.length // 2 - 1, -1, -1): self.max_heapify(i) + class max_priority_queue(max_heap): def heap_maximum(self): return self[0] + def heap_extract_max(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -702,25 +741,28 @@ def heap_extract_max(self): self.heap_size = self.heap_size - 1 self.max_heapify(0) return maximum + def heap_increase_key(self, i, key): if key < self[i].__dict__[self.attr]: sys.exit("new key is smaller than current key") self[i].__dict__[self.attr] = key while i > 0 and self[self.parent(i)].__dict__[self.attr] < self[i].__dict__[self.attr]: - self[i],self[self.parent(i)] = self[self.parent(i)], self[i] + self[i], self[self.parent(i)] = self[self.parent(i)], self[i] self[i].index = i self[self.parent(i)].index = self.parent(i) i = self.parent(i) + def max_heap_insert(self, element): if self.heap_size >= self.length: sys.exit("heap overflow") self.heap_size = self.heap_size + 1 self[self.heap_size - 1] = element element.index = self.heap_size - 1 - key = element.__dict__[self.attr] + key = element.__dict__[self.attr] element.__dict__[self.attr] = float("-Inf") self.heap_increase_key(self.heap_size - 1, key) + class min_heap(list): def __init__(self, data, attr): ''' @@ -734,14 +776,19 @@ def __init__(self, data, attr): self.length = len(data) self.heap_size = self.length self.build_min_heap() + def __contains__(self, y): return y in self[0:self.heap_size] + def left(self, i): return 2 * i + 1 + def right(self, i): return 2 * i + 2 + def parent(self, i): - return (i - 1) / 2 + return (i - 1) // 2 + def min_heapify(self, i): l = self.left(i) r = self.right(i) @@ -751,19 +798,22 @@ def min_heapify(self, i): smallest = i if (r <= (self.heap_size - 1)) and (self[r].__dict__[self.attr] < self[smallest].__dict__[self.attr]): smallest = r - if smallest != i: - self[i],self[smallest] = self[smallest],self[i] + if smallest != i: + self[i], self[smallest] = self[smallest], self[i] self[i].index = i self[smallest].index = smallest self.min_heapify(smallest) + def build_min_heap(self): self.heap_size = self.length - for i in range(self.length / 2 - 1, -1, -1): + for i in range(self.length // 2 - 1, -1, -1): self.min_heapify(i) + class min_priority_queue(min_heap): def heap_minimum(self): return self[0] + def heap_extract_min(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -773,15 +823,17 @@ def heap_extract_min(self): self.heap_size = self.heap_size - 1 self.min_heapify(0) return minimum + def heap_decrease_key(self, i, key): if key > self[i].__dict__[self.attr]: sys.exit("new key is larger than current key") self[i].__dict__[self.attr] = key while i > 0 and self[self.parent(i)].__dict__[self.attr] > self[i].__dict__[self.attr]: - self[i],self[self.parent(i)] = self[self.parent(i)], self[i] + self[i], self[self.parent(i)] = self[self.parent(i)], self[i] self[i].index = i self[self.parent(i)].index = self.parent(i) i = self.parent(i) + def min_heap_insert(self, element): if self.heap_size >= self.length: sys.exit("heap overflow") @@ -791,4 +843,3 @@ def min_heap_insert(self, element): key = element.__dict__[self.attr] element.__dict__[self.attr] = float("Inf") self.heap_decrease_key(self.heap_size - 1, key) - diff --git a/graph_test.py b/graph_test.py index 215e941..65b920a 100644 --- a/graph_test.py +++ b/graph_test.py @@ -2,6 +2,7 @@ import unittest from graph import Vertex, Graph + class TestGraph(unittest.TestCase): def setUp(self): self.graphs = [] @@ -17,11 +18,11 @@ def setUp(self): self.v4 = v4 self.v5 = v5 self.v6 = v6 - vertices = [v1,v2,v3,v4,v5,v6] + vertices = [v1, v2, v3, v4, v5, v6] edges = [(v1, v2), (v1, v3), (v2, v3), (v2, v4), (v2, v5), (v3, v4), (v3, v6), (v4, v5), (v5, v6)] self.graphs.append(Graph(vertices, edges)) - edges = [(v1, v2), (v2, v3), (v3, v4), (v4, v2), (v3, v5), (v2, v4), (v4, v3)] - self.graphs.append(Graph([v1, v2, v3, v4, v5], edges)) + edges = [(v1, v2), (v2, v3), (v3, v4), (v4, v2), (v3, v5), (v2, v4), (v4, v3), (v1, v6)] + self.graphs.append(Graph([v1, v2, v3, v4, v5, v6], edges)) def tearDown(self): pass @@ -49,23 +50,25 @@ def testBfs(self): u = Vertex('u') y = Vertex('y') z = Vertex('z') - vertices = [v,r,s,w,t,x,u,y,z] - edges = [(s, r), (s, w), (r, v), (r, s), (v, r), (w, s), (w, t), (w, x), (t, w), (t, x), (t, u), (u, t), (u, x), (u, y), (x, w), (x, t), (x, u), (x, y), (y, x), (y, u)] + vertices = [v, r, s, w, t, x, u, y, z] + edges = [(s, r), (s, w), (r, v), (r, s), (v, r), (w, s), (w, t), (w, x), (t, w), (t, x), (t, u), (u, t), (u, x), + (u, y), (x, w), (x, t), (x, u), (x, y), (y, x), (y, u)] g = Graph(vertices, edges) - #g.printAllEdges() - #for i in g.vertices: - # i.printEdge() - # print + # g.print(AllEdges()) + # for i in g.vertices: + # i.print(Edge()) + # print() g.bfs(s) - # g.printVertices() - self.assertEquals(s.d, 0) - self.assertEquals(r.d, 1) - self.assertEquals(v.d, 2) - self.assertEquals(w.d, 1) - self.assertEquals(t.d, 2) - self.assertEquals(x.d, 2) - self.assertEquals(u.d, 3) - self.assertEquals(y.d, 3) + # g.print(Vertices()) + self.assertEqual(s.d, 0) + self.assertEqual(r.d, 1) + self.assertEqual(v.d, 2) + self.assertEqual(w.d, 1) + self.assertEqual(t.d, 2) + self.assertEqual(x.d, 2) + self.assertEqual(u.d, 3) + self.assertEqual(y.d, 3) + def testDfs(self): s = Vertex('s') v = Vertex('v') @@ -75,194 +78,202 @@ def testDfs(self): x = Vertex('x') t = Vertex('t') u = Vertex('u') - #edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] - #vertices = (s, v, z, w, y, x, t, u) - #map(lambda vertex, edges: map(lambda vertex, edge: vertex.addEdge(edge), zip([vertex] * len(edges) , edges)), zip(vertices, edges_list)) + # edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] + # vertices = (s, v, z, w, y, x, t, u) + # map(lambda vertex, edges: map(lambda vertex, edge: vertex.addEdge(edge), zip([vertex] * len(edges) , edges)), zip(vertices, edges_list)) vertices = [s, v, z, w, y, x, t, u] edges = [(y, x), (x, z), (z, y), (z, w), (w, x), (s, z), (s, w), (v, w), (v, s), (t, v), (t, u), (u, v), (u, t)] g = Graph(vertices, edges) g.dfs() vertices = (s, v, z, w, y, x, t, u) -# for u in vertices: -# print u, u.d, u.f - #df = [(1, 10), (12, 13), (2, 9), (7, 8), (3, 6), (4, 5), (11, 16), (14, 15)] - #edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] + + # for u in vertices: + # print( u, u.d, u.f) + # df = [(1, 10), (12, 13), (2, 9), (7, 8), (3, 6), (4, 5), (11, 16), (14, 15)] + # edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] def testPathNum(self): - m = Vertex('m') - n = Vertex('n') - o = Vertex('o') - p = Vertex('p') - q = Vertex('q') - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - u = Vertex('u') - v = Vertex('v') - w = Vertex('w') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + m = Vertex('m') + n = Vertex('n') + o = Vertex('o') + p = Vertex('p') + q = Vertex('q') + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + u = Vertex('u') + v = Vertex('v') + w = Vertex('w') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [m, n, o, p, q, r, s, t, u, v, w, x, y, z] - edges = [(m, q), (m, r), (m, x), (n, q), (n, o), (n, u), (o, r), (o, s), (o, v), (p, o), (p, s), (p, z), (q, t), (r, u), (r, y), (s, r), (u, t), (v, w), (v, x), (w, z), (y, v)] + edges = [(m, q), (m, r), (m, x), (n, q), (n, o), (n, u), (o, r), (o, s), (o, v), (p, o), (p, s), (p, z), (q, t), + (r, u), (r, y), (s, r), (u, t), (v, w), (v, x), (w, z), (y, v)] g = Graph(vertices, edges) - self.assertEquals(g.path_num(m, v), 1) - self.assertEquals(g.path_num(n, v), 3) - self.assertEquals(g.path_num(o, v), 3) - self.assertEquals(g.path_num(p, v), 4) - self.assertEquals(g.path_num(q, v), 0) - self.assertEquals(g.path_num(r, v), 1) - self.assertEquals(g.path_num(s, v), 1) - self.assertEquals(g.path_num(t, v), 0) - self.assertEquals(g.path_num(u, v), 0) - self.assertEquals(g.path_num(v, v), 1) - self.assertEquals(g.path_num(w, v), 0) - self.assertEquals(g.path_num(x, v), 0) - self.assertEquals(g.path_num(y, v), 1) - self.assertEquals(g.path_num(z, v), 0) + self.assertEqual(g.path_num(m, v), 1) + self.assertEqual(g.path_num(n, v), 3) + self.assertEqual(g.path_num(o, v), 3) + self.assertEqual(g.path_num(p, v), 4) + self.assertEqual(g.path_num(q, v), 0) + self.assertEqual(g.path_num(r, v), 1) + self.assertEqual(g.path_num(s, v), 1) + self.assertEqual(g.path_num(t, v), 0) + self.assertEqual(g.path_num(u, v), 0) + self.assertEqual(g.path_num(v, v), 1) + self.assertEqual(g.path_num(w, v), 0) + self.assertEqual(g.path_num(x, v), 0) + self.assertEqual(g.path_num(y, v), 1) + self.assertEqual(g.path_num(z, v), 0) g = self.graphs[0] - self.assertEquals(g.path_num(self.v1, self.v2), 1) - self.assertEquals(g.path_num(self.v1, self.v3), 2) - self.assertEquals(g.path_num(self.v1, self.v4), 3) - self.assertEquals(g.path_num(self.v1, self.v5), 4) - self.assertEquals(g.path_num(self.v1, self.v6), 6) - self.assertEquals(g.path_num(self.v2, self.v1), 0) - self.assertEquals(g.path_num(self.v2, self.v3), 1) - self.assertEquals(g.path_num(self.v2, self.v4), 2) - self.assertEquals(g.path_num(self.v2, self.v5), 3) - self.assertEquals(g.path_num(self.v2, self.v6), 4) + self.assertEqual(g.path_num(self.v1, self.v2), 1) + self.assertEqual(g.path_num(self.v1, self.v3), 2) + self.assertEqual(g.path_num(self.v1, self.v4), 3) + self.assertEqual(g.path_num(self.v1, self.v5), 4) + self.assertEqual(g.path_num(self.v1, self.v6), 6) + self.assertEqual(g.path_num(self.v2, self.v1), 0) + self.assertEqual(g.path_num(self.v2, self.v3), 1) + self.assertEqual(g.path_num(self.v2, self.v4), 2) + self.assertEqual(g.path_num(self.v2, self.v5), 3) + self.assertEqual(g.path_num(self.v2, self.v6), 4) g = self.graphs[1] - self.assertEquals(g.path_num(self.v1, self.v5), 1) + self.assertEqual(g.path_num(self.v1, self.v5), 1) def testSCC(self): - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') - g = Vertex('g') - h = Vertex('h') + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') + g = Vertex('g') + h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) G.strongly_connected_components() - self.assertEquals(a.cc, 1) - self.assertEquals(b.cc, 1) - self.assertEquals(c.cc, 2) - self.assertEquals(d.cc, 2) - self.assertEquals(e.cc, 1) - self.assertEquals(f.cc, 3) - self.assertEquals(g.cc, 3) - self.assertEquals(h.cc, 4) + self.assertEqual(a.cc, 1) + self.assertEqual(b.cc, 1) + self.assertEqual(c.cc, 2) + self.assertEqual(d.cc, 2) + self.assertEqual(e.cc, 1) + self.assertEqual(f.cc, 3) + self.assertEqual(g.cc, 3) + self.assertEqual(h.cc, 4) + def testSimplified(self): - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') - g = Vertex('g') - h = Vertex('h') + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') + g = Vertex('g') + h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - #edges = [(a, c), (b, a), (d, h), (d, f), (e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + # edges = [(a, c), (b, a), (d, h), (d, f), (e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) s = G.simplified() -# for u in s.vertices: -# print "u.key: {}, u.cc: {}".format(u.key, u.cc) -# s.printEdge(u) - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') + # for u in s.vertices: + # print( "u.key: {}, u.cc: {}".format(u.key, u.cc) ) + # s.print(Edge(u)) + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') vertices = [a, b, c, d, e, f] edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) s = G.simplified() - #for u in s.vertices: - # print "u.key: {}, u.cc: {}".format(u.key, u.cc) - # s.printEdge(u) + # for u in s.vertices: + # print( "u.key: {}, u.cc: {}".format(u.key, u.cc) ) + # s.print(Edge(u)) + def testComponentGraph(self): - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') - g = Vertex('g') - h = Vertex('h') + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') + g = Vertex('g') + h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), + (h, h)] G = Graph(vertices, edges) cg = G.component_graph() -# print -# for u in cg.vertices: -# print "u.key: {}".format(u.key) -# cg.printEdge(u) - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') + # print() + # for u in cg.vertices: + # print( "u.key: {}".format(u.key) ) + # cg.print(Edge(u)) + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') vertices = [a, b, c, d, e, f] edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) cg = G.component_graph() -# print "www" -# print -# for u in cg.vertices: -# print "u.key: {}".format(u.key) -# cg.printEdge(u) + + # print( "www") + # print() + # for u in cg.vertices: + # print( "u.key: {}".format(u.key) ) + # cg.print(Edge(u)) def testSemiconnected(self): - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') - g = Vertex('g') - h = Vertex('h') + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') + g = Vertex('g') + h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), + (h, h)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), True) - a = Vertex('a') - b = Vertex('b') - c = Vertex('c') - d = Vertex('d') - e = Vertex('e') - f = Vertex('f') + self.assertEqual(G.semiconnected(), True) + a = Vertex('a') + b = Vertex('b') + c = Vertex('c') + d = Vertex('d') + e = Vertex('e') + f = Vertex('f') vertices = [a, b, c, d, e, f] edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), True) + self.assertEqual(G.semiconnected(), True) edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (e, f)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), False) - abe = Vertex('abe') - cd = Vertex('cd') - fg = Vertex('fg') - h = Vertex('h') + self.assertEqual(G.semiconnected(), False) + abe = Vertex('abe') + cd = Vertex('cd') + fg = Vertex('fg') + h = Vertex('h') vertices = [abe, cd, fg, h] edges = [(abe, fg), (abe, cd), (fg, h), (cd, h), (cd, fg)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), True) + self.assertEqual(G.semiconnected(), True) edges = [(abe, fg), (abe, cd), (fg, h), (cd, h)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), False) + self.assertEqual(G.semiconnected(), False) edges = [(abe, fg), (abe, cd), (cd, h), (cd, fg)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), False) + self.assertEqual(G.semiconnected(), False) edges = [(abe, fg), (abe, cd), (fg, h), (cd, fg)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), True) + self.assertEqual(G.semiconnected(), True) edges = [(abe, cd), (fg, h), (cd, fg)] G = Graph(vertices, edges) - self.assertEquals(G.semiconnected(), True) + self.assertEqual(G.semiconnected(), True) + def testCut(self): a = Vertex('a') b = Vertex('b') @@ -274,16 +285,19 @@ def testCut(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), (h, i)] - G = Graph(vertices, edges, directed = False) - #weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 2, 1, 8, 7] + edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), + (h, i)] + G = Graph(vertices, edges, directed=False) + # weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 2, 1, 8, 7] weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 1, 6, 8, 7] z = dict() - for x,y in zip(edges, weight): - z[x] = y + for x, y in zip(edges, weight): + z[x] = y z[(x[1], x[0])] = y + def w(x, y): - return z[(x, y)] + return z[(x, y)] + G.cut(a, h, w) r1 = set() r2 = set() @@ -292,10 +306,11 @@ def w(x, y): r1.add(u) else: r2.add(u) - self.assertEquals(r1, set([a, b])) - self.assertEquals(r2, set([h, i, g, c, f, d, e])) -# for u in G.vertices: -# print "u.key: {}, u.root = {}".format(u.key, u.root) + self.assertEqual(r1, set([a, b])) + self.assertEqual(r2, set([h, i, g, c, f, d, e])) + + # for u in G.vertices: + # print( "u.key: {}, u.root = {}".format(u.key, u.root)) def testKruskal(self): a = Vertex('a') b = Vertex('b') @@ -307,17 +322,22 @@ def testKruskal(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), (i, h), (i, g)] + edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), + (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), + (i, h), (i, g)] G = Graph(vertices, edges) weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] z = dict() - for x,y in zip(edges, weight): - z[x] = y - print "{}: {}".format(x, y) + for x, y in zip(edges, weight): + z[x] = y + print("{}: {}".format(x, y)) + def w(x, y): - return z[(x, y)] + return z[(x, y)] + ls = G.Kruskal(w) - print ls + print(ls) + def testPrim(self): a = Vertex('a') b = Vertex('b') @@ -329,23 +349,27 @@ def testPrim(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - #edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), (i, h), (i, g)] - #weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] - edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), (h, i)] + # edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), (i, h), (i, g)] + # weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] + edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), + (h, i)] weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 1, 6, 8, 7] G = Graph(vertices, edges, False) z = dict() - for x,y in zip(edges, weight): - z[x] = y + for x, y in zip(edges, weight): + z[x] = y z[(x[1], x[0])] = y - #print "Prim edges: {}, weight: {}".format(x, y) + # print( "Prim edges: {}, weight: {}".format(x, y)) + def w(x, y): - return z[(x, y)] + return z[(x, y)] + G.Prim(w, i) s = set() for u in G.vertices: - s.add((u.p, u)) -# self.assertEquals(s, set([(g, h), (f, g), (None, i), (c, d), (c, f), (i, c), (h, a), (d, e), (a, b)])) + s.add((u.p, u)) + # self.assertEqual(s, set([(g, h), (f, g), (None, i), (c, d), (c, f), (i, c), (h, a), (d, e), (a, b)])) + def testBellmanFord(self): s = Vertex('s') t = Vertex('t') @@ -357,11 +381,14 @@ def testBellmanFord(self): weight = [6, 7, 8, 5, -4, -3, 9, -2, 2, 7] G = Graph(vertices, edges) we = dict() - for x,y in zip(edges, weight): - we[x] = y + for x, y in zip(edges, weight): + we[x] = y + def w(x, y): - return we[(x, y)] + return we[(x, y)] + G.Bellman_Ford(w, z) + def testBellmanFordModified(self): s = Vertex('s') t = Vertex('t') @@ -374,73 +401,81 @@ def testBellmanFordModified(self): weight = [1, 0, 3, 4, 2, 6] G = Graph(vertices, edges) we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] -# G.Bellman_Ford(w, s) + return we[(x, y)] + + # G.Bellman_Ford(w, s) G.Bellman_Ford_modified(w, s) - self.assertEquals([i.p for i in vertices], [None, s, t, s, s, s]) - self.assertEquals([i.d for i in vertices], [0, 1, 3, 0, 3, 4]) - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + self.assertEqual([i.p for i in vertices], [None, s, t, s, s, s]) + self.assertEqual([i.d for i in vertices], [0, 1, 3, 0, 3, 4]) + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [r, s, t, x, y, z] edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + G.Bellman_Ford_modified(w, s) - self.assertEquals([i.p for i in vertices], [None, None, s, s, x, y]) - self.assertEquals([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) + self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) + self.assertEqual([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) + def testTopologicalSort(self): - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [r, s, t, x, y, z] edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] G = Graph(vertices, edges) l = G.topological_sort() - self.assertEquals(l, [r, s, t, x, y, z]) - + self.assertEqual(l, [r, s, t, x, y, z]) + result = [] l = [self.v1, self.v2, self.v3, self.v4, self.v5, self.v6] result.append(l) for i in range(len(self.graphs)): - self.assertEquals(self.graphs[i].topological_sort(), result[i]) + self.assertEqual(self.graphs[i].topological_sort(), l) def testDagShortestPaths(self): - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [r, s, t, x, y, z] edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + G.dag_shortest_paths(w, s) - self.assertEquals([i.p for i in vertices], [None, None, s, s, x, y]) - self.assertEquals([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) + self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) + self.assertEqual([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) G.dag_shortest_paths(w, r) - self.assertEquals([i.p for i in vertices], [None, r, r, t, t, t]) - self.assertEquals([i.d for i in vertices], [0, 5, 3, 10, 7, 5]) + self.assertEqual([i.p for i in vertices], [None, r, r, t, t, t]) + self.assertEqual([i.d for i in vertices], [0, 5, 3, 10, 7, 5]) + def TestDagShortestPathsModified(self): u = Vertex('u') v = Vertex('v') @@ -453,21 +488,23 @@ def TestDagShortestPathsModified(self): vertices = [u, v, w, z] edges = [(u, v), (v, w), (v, z)] G = Graph(vertices, edges) - self.assertEquals(dag_shortest_paths_modified(G, u), [u, v, z]) + self.assertEqual(dag_shortest_paths_modified(G, u), [u, v, z]) + def testTotalPathNumber(self): - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [r, s, t, x, y, z] edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) number = G.total_path_number() - self.assertEquals([i.num for i in vertices], [21, 12, 7, 3, 1, 0]) - self.assertEquals(number, 44) + self.assertEqual([i.num for i in vertices], [21, 12, 7, 3, 1, 0]) + self.assertEqual(number, 44) + def testDijkstra(self): s = Vertex('s') t = Vertex('t') @@ -479,13 +516,15 @@ def testDijkstra(self): g = Graph(vertices, edges) weight = [10, 5, 1, 2, 4, 3, 9, 2, 7, 6] we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + g.Dijkstra(w, s) - self.assertEquals([i.p for i in vertices], [None, y, t, s, y]) - self.assertEquals([i.d for i in vertices], [0, 8, 9, 5, 7]) + self.assertEqual([i.p for i in vertices], [None, y, t, s, y]) + self.assertEqual([i.d for i in vertices], [0, 8, 9, 5, 7]) s = Vertex('s') t = Vertex('t') x = Vertex('x') @@ -496,16 +535,19 @@ def w(x, y): g = Graph(vertices, edges) weight = [3, 5, 6, 2, 2, 1, 4, 6, 3, 7] we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + g.Dijkstra(w, s) - self.assertEquals([i.p for i in vertices], [None, s, t, s, y]) - self.assertEquals([i.d for i in vertices], [0, 3, 9, 5, 11]) + self.assertEqual([i.p for i in vertices], [None, s, t, s, y]) + self.assertEqual([i.d for i in vertices], [0, 3, 9, 5, 11]) g.Dijkstra(w, z) - self.assertEquals([i.p for i in vertices], [z, s, z, s, None]) - self.assertEquals([i.d for i in vertices], [3, 6, 7, 8, 0]) + self.assertEqual([i.p for i in vertices], [z, s, z, s, None]) + self.assertEqual([i.d for i in vertices], [3, 6, 7, 8, 0]) + def testDijkstraModified(self): s = Vertex('s') t = Vertex('t') @@ -517,13 +559,15 @@ def testDijkstraModified(self): g = Graph(vertices, edges) weight = [10, 5, 1, 2, 4, 3, 9, 2, 7, 6] we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + g.Dijkstra_modified(w, s, 10) - self.assertEquals([i.p for i in vertices], [None, y, t, s, y]) - self.assertEquals([i.d for i in vertices], [0, 8, 9, 5, 7]) + self.assertEqual([i.p for i in vertices], [None, y, t, s, y]) + self.assertEqual([i.d for i in vertices], [0, 8, 9, 5, 7]) s = Vertex('s') t = Vertex('t') x = Vertex('x') @@ -534,34 +578,36 @@ def w(x, y): g = Graph(vertices, edges) weight = [3, 5, 6, 2, 2, 1, 4, 6, 3, 7] we = dict() - for i,j in zip(edges, weight): - we[i] = j + for i, j in zip(edges, weight): + we[i] = j + def w(x, y): - return we[(x, y)] + return we[(x, y)] + g.Dijkstra_modified(w, s, 7) - self.assertEquals([i.p for i in vertices], [None, s, t, s, y]) - self.assertEquals([i.d for i in vertices], [0, 3, 9, 5, 11]) + self.assertEqual([i.p for i in vertices], [None, s, t, s, y]) + self.assertEqual([i.d for i in vertices], [0, 3, 9, 5, 11]) g.Dijkstra_modified(w, z, 7) - self.assertEquals([i.p for i in vertices], [z, s, z, s, None]) - self.assertEquals([i.d for i in vertices], [3, 6, 7, 8, 0]) - + self.assertEqual([i.p for i in vertices], [z, s, z, s, None]) + self.assertEqual([i.d for i in vertices], [3, 6, 7, 8, 0]) + def testSingleEdge(self): a = Vertex(1) b = Vertex(2) c = Vertex(3) d = Vertex(4) - vertices = [a, b, c, d] + vertices = [a, b, c, d] edges = [(a, b), (b, a), (a, c), (d, d)] G = Graph(vertices, edges) G2 = G.single_edge() edges = set([(a, b), (b, a), (a, c), (c, a)]) vertices = set(vertices) - self.assertEquals(G2.vertices, vertices) - self.assertEquals(G2.edges, edges) - self.assertEquals(G2.adj[a], {b, c}) - self.assertEquals(G2.adj[b], {a}) - self.assertEquals(G2.adj[c], {a}) - self.assertEquals(G2.adj[d], set()) + self.assertEqual(G2.vertices, vertices) + self.assertEqual(G2.edges, edges) + self.assertEqual(G2.adj[a], {b, c}) + self.assertEqual(G2.adj[b], {a}) + self.assertEqual(G2.adj[c], {a}) + self.assertEqual(G2.adj[d], set()) def testUnion(self): a = Vertex(1) @@ -571,21 +617,21 @@ def testUnion(self): G1 = Graph([a, b, c], [(a, b), (a, c)]) G2 = Graph([c, d], [(c, d)]) G3 = G1.union(G2) - self.assertEquals(G3.vertices, {a, b, c, d}) - self.assertEquals(G3.edges, {(a, b), (a, c), (c, d)}) - self.assertEquals(G3.adj[a], {b, c}) - self.assertEquals(G3.adj[b], set()) - self.assertEquals(G3.adj[c], {d}) - self.assertEquals(G3.adj[d], set()) - G1 = Graph([a, b, c], [(a, b), (a, c)], directed = False) - G2 = Graph([c, d], [(c, d)], directed = False) + self.assertEqual(G3.vertices, {a, b, c, d}) + self.assertEqual(G3.edges, {(a, b), (a, c), (c, d)}) + self.assertEqual(G3.adj[a], {b, c}) + self.assertEqual(G3.adj[b], set()) + self.assertEqual(G3.adj[c], {d}) + self.assertEqual(G3.adj[d], set()) + G1 = Graph([a, b, c], [(a, b), (a, c)], directed=False) + G2 = Graph([c, d], [(c, d)], directed=False) G3 = G1.union(G2) - self.assertEquals(G3.vertices, {a, b, c, d}) - self.assertEquals(G3.edges, {(a, b), (b, a), (a, c), (c, a), (c, d), (d, c)}) - self.assertEquals(G3.adj[a], {b, c}) - self.assertEquals(G3.adj[b], {a}) - self.assertEquals(G3.adj[c], {d, a}) - self.assertEquals(G3.adj[d], {c}) + self.assertEqual(G3.vertices, {a, b, c, d}) + self.assertEqual(G3.edges, {(a, b), (b, a), (a, c), (c, a), (c, d), (d, c)}) + self.assertEqual(G3.adj[a], {b, c}) + self.assertEqual(G3.adj[b], {a}) + self.assertEqual(G3.adj[c], {d, a}) + self.assertEqual(G3.adj[d], {c}) def testCopy(self): a = Vertex(1) @@ -593,7 +639,7 @@ def testCopy(self): c = Vertex(3) G1 = Graph([a, b, c], [(a, b), (a, c)]) G2 = G1.copy() - self.assertEquals(G1, G2) + self.assertEqual(G1, G2) def testSquareGraph(self): a = Vertex(1) @@ -602,37 +648,37 @@ def testSquareGraph(self): d = Vertex(4) G = Graph([a, b, c, d], [(a, b), (a, c), (c, d)]) sqrt = G.square() - self.assertEquals(sqrt.vertices, {a, b, c, d}) - self.assertEquals(sqrt.edges, {(a, b), (a, c), (a, d), (c, d)}) - self.assertEquals(sqrt.adj[a], {b, c, d}) - self.assertEquals(sqrt.adj[b], set()) - self.assertEquals(sqrt.adj[c], {d}) - self.assertEquals(sqrt.adj[d], set()) + self.assertEqual(sqrt.vertices, {a, b, c, d}) + self.assertEqual(sqrt.edges, {(a, b), (a, c), (a, d), (c, d)}) + self.assertEqual(sqrt.adj[a], {b, c, d}) + self.assertEqual(sqrt.adj[b], set()) + self.assertEqual(sqrt.adj[c], {d}) + self.assertEqual(sqrt.adj[d], set()) a = Vertex(1) b = Vertex(2) c = Vertex(3) G = Graph([a, b, c], [(a, b), (b, c), (a, c)]) sqrt = G.square() - self.assertEquals(G, sqrt) + self.assertEqual(G, sqrt) def testMht(self): - print "start mht" + print("start mht") g = self.graphs[0] g.mht() - print "height" - print self.v1.h - print self.v2.h - print self.v3.h - print self.v4.h - print self.v5.h - print self.v6.h - print "height" - print self.v1.mh - print self.v2.mh - print self.v3.mh - print self.v4.mh - print self.v5.mh - print self.v6.mh + print("height") + print(self.v1.h) + print(self.v2.h) + print(self.v3.h) + print(self.v4.h) + print(self.v5.h) + print(self.v6.h) + print("height") + print(self.v1.mh) + print(self.v2.mh) + print(self.v3.mh) + print(self.v4.mh) + print(self.v5.mh) + print(self.v6.mh) # def testJohnson(self): # a1 = Vertex(1) # a2 = Vertex(2) diff --git a/hamiltonian_path_test.py b/hamiltonian_path_test.py index 3dd2c32..3541bd3 100644 --- a/hamiltonian_path_test.py +++ b/hamiltonian_path_test.py @@ -3,30 +3,31 @@ from graph import Vertex, Graph from hamiltonian_path import hamiltonian_path + class TestHamiltonianPath(unittest.TestCase): def testHamPath(self): - r = Vertex('r') - s = Vertex('s') - t = Vertex('t') - x = Vertex('x') - y = Vertex('y') - z = Vertex('z') + r = Vertex('r') + s = Vertex('s') + t = Vertex('t') + x = Vertex('x') + y = Vertex('y') + z = Vertex('z') vertices = [r, s, t, x, y, z] edges = [(r, s), (s, t), (t, x), (x, y), (y, z)] G = Graph(vertices, edges) - self.assertEquals([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, True]) + self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, True]) edges = [(r, s), (r, t), (s, x), (s, y), (t, z)] G = Graph(vertices, edges) - self.assertEquals([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, False]) + self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False, False]) edges = [(r, s), (s, t), (s, x), (t, x)] vertices = [r, s, t, x] G = Graph(vertices, edges) - self.assertEquals([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True]) + self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True]) edges = [(r, s), (s, t), (s, x), (t, x), (r, y), (y, s)] vertices = [r, s, t, x, y] G = Graph(vertices, edges) - self.assertEquals([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True, False]) + self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, True, False]) edges = [(r, s), (s, t), (s, x), (t, x), (r, y)] vertices = [r, s, t, x, y] G = Graph(vertices, edges) - self.assertEquals([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False]) + self.assertEqual([hamiltonian_path(G, r, v) for v in vertices], [False, False, False, False, False]) diff --git a/hash.py b/hash.py index 93f79a4..6b88130 100755 --- a/hash.py +++ b/hash.py @@ -9,18 +9,27 @@ def hash_insert(T, k, h): return j else: i = i + 1 + + def linear_probe(k, i): return (aux(k) + i) % len(T) + + def quad_probe(k, i): return (aux(k) + i + 3 * i * i) % len(T) + + def aux(k): return k + + def double_hashing(k, i): return (k + i * (1 + k % (len(T) - 1))) % len(T) + T = [None for i in range(0, 11)] -print "length of T is ", len(T) +print("length of T is ", len(T)) for i in 10, 22, 31, 4, 15, 28, 17, 88, 59: - hash_insert(T, i, double_hashing) + hash_insert(T, i, double_hashing) -print T +print(T) diff --git a/heap.py b/heap.py index 04f5db1..56804b4 100644 --- a/heap.py +++ b/heap.py @@ -1,52 +1,69 @@ +import math + + class max_heap(list): def __init__(self, data): list.__init__(self, data) self.length = len(data) self.heap_size = self.length self.build_max_heap() + def left(self, i): return 2 * i + 1 + def right(self, i): return 2 * i + 2 + def parent(self, i): - return (i - 1) / 2 + return (i - 1) // 2 + def max_heapify(self, i): - l = self.left(i) - r = self.right(i) - if (l <= (self.heap_size - 1)) and (self[l] > self[i]): - largest = l + left = self.left(i) + right = self.right(i) + if (left <= (self.heap_size - 1)) and (self[left] > self[i]): + largest = left else: largest = i - if (r <= (self.heap_size - 1)) and (self[r] > self[largest]): - largest = r - if largest != i: - self[i],self[largest] = self[largest],self[i] + if (right <= (self.heap_size - 1)) and (self[right] > self[largest]): + largest = right + if largest != i: + self[i], self[largest] = self[largest], self[i] self.max_heapify(largest) + def build_max_heap(self): self.heap_size = self.length - for i in range(self.length / 2 - 1, -1, -1): + print(self.length) + for i in range(self.length // 2 - 1, -1, -1): self.max_heapify(i) + def heapsort(self): self.build_max_heap() for i in range(self.length - 1, 0, -1): - self[0],self[i] = self[i],self[0] + self[0], self[i] = self[i], self[0] self.heap_size = self.heap_size - 1 self.max_heapify(0) -# print self + + +# print( self) class min_heap(list): def __init__(self, data): list.__init__(self, data) self.length = len(data) self.heap_size = self.length self.build_min_heap() + def __contains__(self, y): return y in self[0:self.heap_size] + def left(self, i): return 2 * i + 1 + def right(self, i): return 2 * i + 2 + def parent(self, i): - return (i - 1) / 2 + return (i - 1) // 2 + def min_heapify(self, i): l = self.left(i) r = self.right(i) @@ -56,10 +73,11 @@ def min_heapify(self, i): smallest = i if (r <= (self.heap_size - 1)) and (self[r] < self[smallest]): smallest = r - if smallest != i: - self[i],self[smallest] = self[smallest],self[i] + if smallest != i: + self[i], self[smallest] = self[smallest], self[i] self.min_heapify(smallest) + def build_min_heap(self): self.heap_size = self.length - for i in range(self.length / 2 - 1, -1, -1): + for i in range(self.length // 2 - 1, -1, -1): self.min_heapify(i) diff --git a/heap_test.py b/heap_test.py index 9c16baa..cfff113 100644 --- a/heap_test.py +++ b/heap_test.py @@ -1,34 +1,39 @@ import unittest from heap import max_heap, min_heap + class TestHeap(unittest.TestCase): -# def test_init(self): -# a = heap([4, 1, 3, 2, 16, 9, 10, 14, 8, 7]) -# self.assertEquals(a.__heap, a) -# self.assertEquals(a.__length, 10) -# self.assertEquals(a.__heap_size, 10) + # def test_init(self): + # a = heap([4, 1, 3, 2, 16, 9, 10, 14, 8, 7]) + # self.assertEqual(a.__heap, a) + # self.assertEqual(a.__length, 10) + # self.assertEqual(a.__heap_size, 10) def test_max_heapify(self): a = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1] h = max_heap(a) h.max_heapify(1) - self.assertEquals(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + def test_build_max_heap(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] h = max_heap(a) h.build_max_heap() - self.assertEquals(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + def test_heapsort(self): a = [4, 1, 3, 3, 16, 9, 10, 14, 8, 7] h = max_heap(a) h.heapsort() - self.assertEquals(h, [1, 3, 3, 4, 7, 8, 9, 10, 14, 16]) + self.assertEqual(h, [1, 3, 3, 4, 7, 8, 9, 10, 14, 16]) + def test_min_heapify(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] h = min_heap(a) h.min_heapify(1) - self.assertEquals(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) + self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) + def test_build_min_heap(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] h = min_heap(a) h.build_min_heap() - self.assertEquals(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) + self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) diff --git a/huffman.py b/huffman.py index 90857b7..b40286e 100644 --- a/huffman.py +++ b/huffman.py @@ -1,4 +1,7 @@ -from priority_queue import min_priority_queue +from priority_queue import min_priority_queue +import sys + + class Min_priority_queue(min_priority_queue): def min_heap_insert(self, key): if self.heap_size >= self.length: @@ -6,66 +9,89 @@ def min_heap_insert(self, key): self.heap_size = self.heap_size + 1 self.heap[self.heap_size - 1] = node(None, None, float("Inf")) self.heap_decrease_key(self.heap_size - 1, key) + + class character(object): - def __init__(self, char, freq, sibling = None): + def __init__(self, char, freq, sibling=None): self.char = char self.freq = freq self.sibling = sibling + def __eq__(self, y): if self.freq == y.freq: return True + def __gt__(self, y): if self.freq > y.freq: return True + def __ge__(self, y): if self.freq >= y.freq: return True + def __le__(self, y): if self.freq <= y.freq: return True + def __lt__(self, y): if self.freq < y.freq: return True + + class node(object): def __init__(self, left, right, freq): self.left = left - self.right =right + self.right = right self.freq = freq + def __eq__(self, y): if self.freq == y.freq: return True + def __gt__(self, y): if self.freq > y.freq: return True + def __ge__(self, y): if self.freq >= y.freq: return True + def __le__(self, y): if self.freq <= y.freq: return True + def __lt__(self, y): if self.freq < y.freq: return True + + class tenary_node(object): - def __init__(self, freq, child = None, sibling = None): + def __init__(self, freq, child=None, sibling=None): self.freq = freq self.child = child self.sibling = sibling + def __eq__(self, y): if self.freq == y.freq: return True + def __gt__(self, y): if self.freq > y.freq: return True + def __ge__(self, y): if self.freq >= y.freq: return True + def __le__(self, y): if self.freq <= y.freq: return True + def __lt__(self, y): if self.freq < y.freq: return True + + def huffman(chars, freqs): n = len(chars) c = [0] * n @@ -77,24 +103,34 @@ def huffman(chars, freqs): y = q.heap_extract_min() q.min_heap_insert(node(x, y, x.freq + y.freq)) return q.heap_extract_min() + + def print_code(root): print_code_aux(root, '') + + def print_code_aux(node, s): if hasattr(node, "left"): - print_code_aux(node.left, s + '0') print_code_aux(node.right, s + '1') + print_code_aux(node.left, s + '0') else: - print "character: {}\tfrequency: {}\tcode: {}".format(node.char, node.freq, s) + print("character: {}\tfrequency: {}\tcode: {}".format(node.char, node.freq, s)) + + def compact_store_prefix_code(root): store = [] compact_store_prefix_code_aux(root, store, '') return store + + def compact_store_prefix_code_aux(node, store, string): if hasattr(node, "left"): compact_store_prefix_code_aux(node.left, store, string + '0') compact_store_prefix_code_aux(node.right, store, '1') else: store.append((node.char, string)) + + def decode_compact_prefix_code(store): code = '' pos = 0 @@ -108,7 +144,9 @@ def decode_compact_prefix_code(store): code = store[i][1] else: code = code[0:pos] + store[i][1] - print "char: {}, code: {}".format(store[i][0], code) + print("char: {}, code: {}".format(store[i][0], code)) + + def huffman_tenary(chars, freqs, m): ''' generalize Huffman's algorithm to tenary codewords the parameter m is the number of symbols we use, eg, in @@ -131,19 +169,23 @@ def huffman_tenary(chars, freqs, m): return q.heap_extract_min() x = q.heap_extract_min() z = tenary_node(x.freq, x) - while q.heap_size > 0: + while q.heap_size > 0: y = q.heap_extract_min() x.sibling = y z.freq = z.freq + y.freq x = y q.min_heap_insert(z) return q.heap_extract_min() + + def print_huffman_tenary(root): print_huffman_tenary_aux(root, '', '') + + def print_huffman_tenary_aux(node, string, sibling): if hasattr(node, "child"): - print_huffman_tenary_aux(node.child, string + str(sibling), 0) + print_huffman_tenary_aux(node.child, string + str(sibling), 0) else: - print "character: {}\tfrequency: {}\tcode: {}".format(node.char, node.freq, string + str(sibling)) - if node.sibling != None: + print("character: {}\tfrequency: {}\tcode: {}".format(node.char, node.freq, string + str(sibling))) + if node.sibling: print_huffman_tenary_aux(node.sibling, string, sibling + 1) diff --git a/interpolation.py b/interpolation.py index 5c228bc..956798b 100644 --- a/interpolation.py +++ b/interpolation.py @@ -2,6 +2,7 @@ import synthetic_division as di + def roots_interpolation(roots, n): A = [0] * (n + 1) if n == 1: @@ -17,21 +18,22 @@ def roots_interpolation(roots, n): A[0] = -1 * x * B[0] return A + def Lagrange_interpolation(X, Y, n): R = roots_interpolation(X, n) -# print "length of R is {}".format(len(R)) + # print( "length of R is {}".format(len(R))) A = [0] * n for k in range(0, n): q, re = di.synthetic_division(R, n + 1, X[k]) -# print q - # print "length of q is {}".format(len(q)) + # print( q) + # print( "length of q is {}".format(len(q))) m = 1.0 for j in range(0, n): if j != k: m = m * (X[k] - X[j]) - # print "m = {}".format(m) + # print( "m = {}".format(m)) m = Y[k] / m - # print "m = {}".format(m) + # print( "m = {}".format(m)) for j in range(0, n): A[j] = A[j] + q[j] * m return A diff --git a/interval_tree.py b/interval_tree.py index a4fcf41..c3e6b64 100755 --- a/interval_tree.py +++ b/interval_tree.py @@ -2,10 +2,13 @@ from rb_tree import rb_node, rb_tree + class interval(object): def __init__(self, low, high): self.low = low self.high = high + + class interval_node(rb_node): def __init__(self, key, p, left, right, color, interval, maximum): rb_node.__init__(self, key, p, left, right, color) @@ -15,7 +18,7 @@ def __init__(self, key, p, left, right, color, interval, maximum): def list_all_overlapping_intervals(self, T, i): x = self if x.interval.high >= i.low and i.high >= x.interval.low: - print x.interval.low, x.interval.high + print(x.interval.low, x.interval.high) if x.left != T.nil and x.left.maximum >= i.low: self.left.list_all_overlapping_intervals(T, i) self.right.list_all_overlapping_intervals(T, i) @@ -23,7 +26,7 @@ def list_all_overlapping_intervals(self, T, i): self.right.list_all_overlapping_intervals(T, i) def interval_search_exactly(self, T, i): - if self.interval.low == i.low and self.interval.high == i.high: + if self.interval.low == i.low and self.interval.high == i.high: return self if self.interval.low > i.low: if self.left != T.nil: @@ -36,17 +39,18 @@ def interval_search_exactly(self, T, i): else: return T.nil - class interval_tree(rb_tree): nil = interval_node(None, None, None, None, 1, None, float("-Inf")) root = nil + def __init__(self, intervals): if isinstance(intervals, list): for i in intervals: self.insert(interval_node(i.low, None, None, None, 0, i, i.high)) else: - print "Not invalid argument" + print("Not invalid argument") + def insert(self, z): y = self.nil x = self.root @@ -67,8 +71,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def left_rotate(self, x): y = x.right x.right = y.left @@ -85,6 +90,7 @@ def left_rotate(self, x): x.p = y y.maximum = x.maximum x.maximum = max(x.left.maximum, x.interval.high, x.right.maximum) + def right_rotate(self, y): x = y.left y.left = x.right @@ -101,6 +107,7 @@ def right_rotate(self, y): y.p = x x.maximum = y.maximum y.maximum = max(y.left.maximum, y.interval.high, y.right.maximum) + def delete(self, z): y = z y_original_color = y.color @@ -168,11 +175,11 @@ def open_interval_search(self, interval): return x def list_all_overlapping_intervals(self, i): - if self.root == self.nil: + if self.root == self.nil: return else: self.root.list_all_overlapping_intervals(self, i) - print + print() def interval_search_exactly(self, i): if self.root == self.nil: diff --git a/interval_tree_test.py b/interval_tree_test.py index e5b8be0..96f6648 100755 --- a/interval_tree_test.py +++ b/interval_tree_test.py @@ -21,6 +21,7 @@ def test_insert_one(self): values = [38, 45, 19, 45, 41, 41, 12, 45, 31, 35, 9, 21] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_one(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -31,6 +32,7 @@ def test_delete_one(self): values = [38, 45, 19, 45, 41, 41, 12, 45, 31, 35] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_two(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -42,6 +44,7 @@ def test_delete_two(self): values = [38, 42, 19, 35, 41, 41, 31, 35] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_three(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -54,6 +57,7 @@ def test_delete_three(self): values = [38, 42, 31, 35, 41, 41] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_four(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -67,6 +71,7 @@ def test_delete_four(self): values = [38, 42, 41, 41] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_five(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -81,6 +86,7 @@ def test_delete_five(self): values = [41, 41] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) + def test_delete_six(self): intervals = [] values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] @@ -93,8 +99,8 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.nil.maximum, float("-Inf")) - + self.assertEqual(T.nil.maximum, float("-Inf")) + def test_interval_search(self): intervals = [] values = [41, 41, 38, 52, 43, 48] @@ -103,13 +109,13 @@ def test_interval_search(self): T = interval_tree(intervals) i = interval(50, 51) t = T.closed_interval_search(i) - self.assertEquals(T.root.left, t) + self.assertEqual(T.root.left, t) i = interval(58, 60) t = T.closed_interval_search(i) - self.assertEquals(T.nil, t) + self.assertEqual(T.nil, t) i = interval(38, 48) t = T.closed_interval_search(i) - self.assertEquals(T.root, t) + self.assertEqual(T.root, t) def test_interval_search_minimum_low_end(self): intervals = [] @@ -119,13 +125,13 @@ def test_interval_search_minimum_low_end(self): T = interval_tree(intervals) i = interval(22, 51) t = T.closed_interval_search_minimum_low_end(i) - self.assertEquals(T.root.left, t) + self.assertEqual(T.root.left, t) i = interval(58, 60) t = T.closed_interval_search_minimum_low_end(i) - self.assertEquals(T.nil, t) + self.assertEqual(T.nil, t) i = interval(38, 48) t = T.closed_interval_search_minimum_low_end(i) - self.assertEquals(T.root.left, t) + self.assertEqual(T.root.left, t) def test_list_all_overlapping_intervals(self): intervals = [] @@ -152,26 +158,29 @@ def test_interval_search_exactly(self): T = interval_tree(intervals) i = interval(22, 51) t = T.interval_search_exactly(i) - self.assertEquals(t, T.nil) + self.assertEqual(t, T.nil) i = interval(41, 41) t = T.interval_search_exactly(i) - self.assertEquals(t, T.root) + self.assertEqual(t, T.root) i = interval(38, 52) t = T.interval_search_exactly(i) - self.assertEquals(t, T.root.left) + self.assertEqual(t, T.root.left) i = interval(43, 48) t = T.interval_search_exactly(i) - self.assertEquals(t, T.root.right) + self.assertEqual(t, T.root.right) i = interval(43, 49) t = T.interval_search_exactly(i) - self.assertEquals(t, T.nil) + self.assertEqual(t, T.nil) i = interval(20, 50) t = T.interval_search_exactly(i) - self.assertEquals(t, T.nil) + self.assertEqual(t, T.nil) i = interval(39, 41) t = T.interval_search_exactly(i) - self.assertEquals(t, T.nil) + self.assertEqual(t, T.nil) + def wrap(self, tree, node, maximum): - self.assertEquals(tree.iterative_tree_search(node).maximum, maximum) + self.assertEqual(tree.iterative_tree_search(node).maximum, maximum) + + if __name__ == '__main__': unittest.main() diff --git a/inversion_tree.py b/inversion_tree.py index e02fa8d..97f818f 100644 --- a/inversion_tree.py +++ b/inversion_tree.py @@ -10,8 +10,8 @@ def inversion(A): i = i + 1 x = rank_node(key, None, None, None, 0, 1) T.insert(x) - # print 'x.key = {}, x.rank = {}'.format(x.key, x.rank) + # print( 'x.key = {}, x.rank = {}'.format(x.key, x.rank)) inversion = inversion + i - x.rank return inversion else: - print "Not invalid argument" + print("Not invalid argument") diff --git a/k_way_merge.py b/k_way_merge.py index af45cf1..c0d13af 100644 --- a/k_way_merge.py +++ b/k_way_merge.py @@ -35,6 +35,6 @@ def k_way_merge(lists): elif length == 2: return merge(lists[0], lists[1]) else: - list1 = k_way_merge(lists[0:length / 2]) - list2 = k_way_merge(lists[length / 2 : length]) + list1 = k_way_merge(lists[0:length // 2]) + list2 = k_way_merge(lists[length // 2: length]) return merge(list1, list2) diff --git a/k_way_merge_test.py b/k_way_merge_test.py index 3245415..a9d8051 100644 --- a/k_way_merge_test.py +++ b/k_way_merge_test.py @@ -3,14 +3,14 @@ import random from k_way_merge import k_way_merge + class TestKWayMerge(unittest.TestCase): def test_k_way_merge(self): - for j in range(0, 10000): - A = [random.randint(1, 10000) for i in range(0, 100)] - lists = [None] * 10 - for i in range(0, 10): - lists[i] = A[10 * i : (i + 1) * 10] - lists[i].sort() - A.sort() - self.assertEquals(k_way_merge(lists), A) - + for j in range(0, 10000): + A = [random.randint(1, 10000) for _ in range(0, 100)] + lists = [None] * 10 + for i in range(0, 10): + lists[i] = A[10 * i: (i + 1) * 10] + lists[i].sort() + A.sort() + self.assertEqual(k_way_merge(lists), A) diff --git a/knapsack_0_1.py b/knapsack_0_1.py index 52407b4..987c458 100644 --- a/knapsack_0_1.py +++ b/knapsack_0_1.py @@ -1,17 +1,19 @@ from numpy import zeros + def knapsack_0_1(W, w, v): n = len(w) return knapsack_0_1_aux(W, w, v, 1, n) + def knapsack_0_1_aux(W, w, v, m, n): - ''' + """ m: the first item n: the last item W: total weight w: the list of weights of items v: the list of values of items - ''' + """ # if m > n, then we have scanned all the items if m > n: @@ -25,16 +27,18 @@ def knapsack_0_1_aux(W, w, v, m, n): else: return max(knapsack_0_1_aux(W - w[m - 1], w, v, m + 1, n) + v[m - 1], knapsack_0_1_aux(W, w, v, m + 1, n)) + def knapsack_0_1_memoized(W, w, v): m = 1 n = len(w) - value = zeros((W + 1, n + 1)) - solution = zeros((W + 1, n + 1)) + value = zeros((W + 1, n + 1)) + solution = zeros((W + 1, n + 1)) for i in range(0, W + 1): for j in range(0, n + 1): value[i, j] = float("-Inf") knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution) - return value,solution + return value, solution + def knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution): if m > n: @@ -42,7 +46,7 @@ def knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution): if value[W, m] >= 0: return value[W, m] if W < w[m - 1]: - value[W, m] = knapsack_0_1_memoized_aux(W, w, v, m + 1, n, value, solution) + value[W, m] = knapsack_0_1_memoized_aux(W, w, v, m + 1, n, value, solution) solution[W, m] = 0 else: s = knapsack_0_1_memoized_aux(W - w[m - 1], w, v, m + 1, n, value, solution) + v[m - 1] @@ -52,12 +56,13 @@ def knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution): value[W, m] = max(s, t) return value[W, m] + def print_knapsack_solution(solution, w): W = solution.shape[0] - 1 n = solution.shape[1] - 1 i = 1 while W != 0 and i <= n: if solution[W, i] == 1: - print i + print(i) W = W - w[i - 1] i = i + 1 diff --git a/kth-Quantiles.py b/kth-Quantiles.py index 13d9ef6..8d7c0bb 100755 --- a/kth-Quantiles.py +++ b/kth-Quantiles.py @@ -5,40 +5,45 @@ from randomized_select import randomized_select from quicksort import randomized_quicksort + def kth_quantiles(A, B, k, p, r): if k > 0: n = r - p + 1 location = math.floor(k / 2) * math.ceil(n / k) - B[math.floor(k / 2)]= randomized_select(A, p, r, location) + B[math.floor(k / 2)] = randomized_select(A, p, r, location) kth_quantiles(A, B, p, math.floor(k / 2) - 1, location - 1) kth_quantiles(A, B, math.floor(k / 2), location + 1, r) + def median_of_two_arrays(X, x_start, x_end, Y, y_start, y_end, size): - print X[x_start:x_end + 1], '\t', Y[y_start:y_end + 1], '\t', size + print(X[x_start:x_end + 1], '\t', Y[y_start:y_end + 1], '\t', size) if size == 1: return min(X[x_start], Y[y_start]) xc = X[x_start + int(math.floor(size / 2)) - 1] yc = Y[y_start + int(math.ceil(size / 2)) - 1] - print xc, yc + print(xc, yc) if xc == yc: return xc elif xc < yc: - return median_of_two_arrays(X, x_start + int(math.floor(size / 2)), x_end, Y, y_start, y_end, math.ceil(size / 2)) + return median_of_two_arrays(X, x_start + int(math.floor(size / 2)), x_end, Y, y_start, y_end, + math.ceil(size / 2)) else: - return median_of_two_arrays(X, x_start, x_end, Y, y_start + int(math.ceil(size / 2)), y_end, math.floor(size / 2)) -A = [random.randint(1, 100) for i in range(0, 15)] -print A + return median_of_two_arrays(X, x_start, x_end, Y, y_start + int(math.ceil(size / 2)), y_end, + math.floor(size / 2)) + + +A = [random.randint(1, 100) for i in range(0, 15)] +print(A) randomized_quicksort(A, 0, 14) -print A -B = [random.randint(1, 100) for i in range(0, 15)] -print B +print(A) +B = [random.randint(1, 100) for i in range(0, 15)] +print(B) randomized_quicksort(B, 0, 14) -print B -print median_of_two_arrays(A, 0, 14, B, 0, 14, 3.0) -#randomized_select(A, 0, 14, 7) -#print A -#for i in range(1, 16): +print(B) +print(median_of_two_arrays(A, 0, 14, B, 0, 14, 3.0)) +# randomized_select(A, 0, 14, 7) +# print( A) +# for i in range(1, 16): # randomized_select(A, 0, 14, i) -# print i, '\t', A -# print randomized_select(A, 0, 14, i) - +# print( i, '\t', A) +# print( randomized_select(A, 0, 14, i)) diff --git a/linked_list.py b/linked_list.py index ead4c9a..c9eb281 100644 --- a/linked_list.py +++ b/linked_list.py @@ -1,33 +1,40 @@ class linked_list(object): - def __init__(self, key = None): + def __init__(self, key=None): self.head = None self.size = 0 self.key = key + def empty(self): return self.size == 0 + def search(self, k): x = self.head - while x != None and x.key != k: + while x and x.key != k: x = x.next return x + def insert(self, x): self.size = self.size + 1 x.next = self.head - if self.head != None: + if self.head: self.head.prev = x self.head = x x.prev = None + def delete(self, x): self.size = self.size - 1 - if x.prev != None: + if x.prev: x.prev.next = x.next else: self.head = x.next - if x.next != None: + if x.next: x.next.prev = x.prev + def extract(self, x): self.delete(x) return x + + class linked_list_node(object): def __init__(self, element): self.key = element diff --git a/linked_list_test.py b/linked_list_test.py index c1f44f6..bbe6f4d 100644 --- a/linked_list_test.py +++ b/linked_list_test.py @@ -1,6 +1,7 @@ import unittest from linked_list import linked_list, linked_list_node + class TestLinkedList(unittest.TestCase): def test_insert(self): L = linked_list() @@ -16,10 +17,11 @@ def test_insert(self): L.insert(e) l = [] x = L.head - while x != None: + while x: l.append(x) x = x.next - self.assertEquals(l, [e, d, c, b, a]) + self.assertEqual(l, [e, d, c, b, a]) + def test_search(self): L = linked_list() a = linked_list_node(1) @@ -32,7 +34,8 @@ def test_search(self): L.insert(c) L.insert(d) L.insert(e) - self.assertEquals(L.search(4), b) + self.assertEqual(L.search(4), b) + def test_delete(self): L = linked_list() a = linked_list_node(1) @@ -48,7 +51,7 @@ def test_delete(self): L.delete(b) l = [] x = L.head - while x != None: + while x: l.append(x) x = x.next - self.assertEquals(l, [e, d, c, a]) + self.assertEqual(l, [e, d, c, a]) diff --git a/longest_common_subsequence.py b/longest_common_subsequence.py index 2d4db66..dcf61a7 100644 --- a/longest_common_subsequence.py +++ b/longest_common_subsequence.py @@ -1,5 +1,6 @@ from numpy import zeros + def lcs_length(X, Y): m = len(X) n = len(Y) @@ -17,7 +18,9 @@ def lcs_length(X, Y): else: c[i, j] = c[i, j - 1] b[i, j] = 2 - return c,b + return c, b + + def lcs_length_one_row(X, Y): m = len(X) n = len(Y) @@ -35,14 +38,15 @@ def lcs_length_one_row(X, Y): a = c[j] c[j] = value return c[n] + + def print_lcs(b, X, i, j): if i == 0 or j == 0: return if b[i, j] == 0: print_lcs(b, X, i - 1, j - 1) - print X[i - 1], + print(X[i - 1], ) elif b[i, j] == 1: print_lcs(b, X, i - 1, j) else: print_lcs(b, X, i, j - 1) - diff --git a/longest_common_subsequence_test.py b/longest_common_subsequence_test.py index 84bd881..79b8962 100644 --- a/longest_common_subsequence_test.py +++ b/longest_common_subsequence_test.py @@ -2,27 +2,29 @@ import unittest from longest_common_subsequence import lcs_length_one_row, lcs_length + class TestLCS(unittest.TestCase): def test_lcs_length(self): X = "ABCBDAB" Y = "BDCABA" - c,b = lcs_length(X, Y) - self.assertEquals(c[len(X), len(Y)], 4) + c, b = lcs_length(X, Y) + self.assertEqual(c[len(X), len(Y)], 4) X = [1, 0, 0, 1, 0, 1, 0, 1] Y = [0, 1, 0, 1, 1, 0, 1, 1, 0] - c,b = lcs_length(X, Y) - self.assertEquals(c[len(X), len(Y)], 6) + c, b = lcs_length(X, Y) + self.assertEqual(c[len(X), len(Y)], 6) X = "ACCGGTCGAGTGCGCGGAAGCCGGCCGAA" Y = "GTCGTTCGGAATGCCGTTGCTCTGTAAA" - c,b = lcs_length(X, Y) - self.assertEquals(c[len(X), len(Y)], 20) + c, b = lcs_length(X, Y) + self.assertEqual(c[len(X), len(Y)], 20) + def test_lcs_length_one_row(self): X = "ABCBDAB" Y = "BDCABA" - self.assertEquals(lcs_length_one_row(X, Y), 4) + self.assertEqual(lcs_length_one_row(X, Y), 4) X = [1, 0, 0, 1, 0, 1, 0, 1] Y = [0, 1, 0, 1, 1, 0, 1, 1, 0] - self.assertEquals(lcs_length_one_row(X, Y), 6) + self.assertEqual(lcs_length_one_row(X, Y), 6) X = "ACCGGTCGAGTGCGCGGAAGCCGGCCGAA" Y = "GTCGTTCGGAATGCCGTTGCTCTGTAAA" - self.assertEquals(lcs_length_one_row(X, Y), 20) + self.assertEqual(lcs_length_one_row(X, Y), 20) diff --git a/longest_monotonically_increasing_subsequence_test.py b/longest_monotonically_increasing_subsequence_test.py index 6f94d7f..3be5ef2 100644 --- a/longest_monotonically_increasing_subsequence_test.py +++ b/longest_monotonically_increasing_subsequence_test.py @@ -7,8 +7,8 @@ class TestLMIS(unittest.TestCase): def test_longest_monotonically_increasing_subsequence(self): X = [5, 4, 1, 3, 2] - self.assertEquals(longest_monotonically_increasing_subsequence(X), 2) + self.assertEqual(longest_monotonically_increasing_subsequence(X), 2) X = [1, 3, 4, 2, 5] - self.assertEquals(longest_monotonically_increasing_subsequence(X), 4) + self.assertEqual(longest_monotonically_increasing_subsequence(X), 4) X = [1, 3, 10, 5, 3, 4] - self.assertEquals(longest_monotonically_increasing_subsequence(X), 3) + self.assertEqual(longest_monotonically_increasing_subsequence(X), 3) diff --git a/longest_palindrome_subsequence.py b/longest_palindrome_subsequence.py index 66b87b5..e186c6e 100644 --- a/longest_palindrome_subsequence.py +++ b/longest_palindrome_subsequence.py @@ -3,11 +3,12 @@ from longest_common_subsequence import lcs_length, print_lcs + def longest_palindrome_subsequence(s): - #c, b = lcs_length(s, s[::-1]) - #print_lcs(b, s, len(s), len(s)) + # c, b = lcs_length(s, s[::-1]) + # print(_lcs(b, s, len(s), len(s))) n = len(s) - c = [[0] * n for i in range(n)] + c = [[0] * n for _ in range(n)] for i in range(n): c[i][i] = 1 for i in range(n - 1): @@ -19,12 +20,13 @@ def longest_palindrome_subsequence(s): for i in range(0, n - length + 1): j = i + length - 1 if s[i] == s[j]: - print i, j, c[i + 1][j - 1] + print(i, j, c[i + 1][j - 1]) c[i][j] = 2 + c[i + 1][j - 1] else: c[i][j] = max(c[i][j - 1], c[i + 1][j]) return c + def print_lps(c, s): start = 0 end = len(s) - 1 @@ -48,8 +50,3 @@ def print_lps(c, s): l.insert(index, s[start]) idx.insert(index, start) return ''.join(l), idx - - - - - diff --git a/main.c b/main.c deleted file mode 100644 index 0c2685f..0000000 --- a/main.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -int main(int argc, char *argv[]) { - //int pow1(int, unsigned); - //int pow1(int, unsigned); - //int num = atoi(argv[1]); - //int exp = atoi(argv[2]); -// - //printf("%d\n", pow2(num, exp)); - //printf("%d\n", pow1(num, exp)); - void matrix_exp(int *, int *, int, int); - int A[16] = {-1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1}; - int B[16]; - int C[4] = {1, 1, 0, 1}; //3, 2, -4, -2};//1, 0, 0, 1}; - int E[9] = {2, 1, 1, 3, 1, 0, 0, 1, 2};//1, 0, 0, 1, 0, 1, 0, 1, 0}; - int D[4]; - int i, j; - int n = 2; - matrix_exp(C, D, n, atoi(argv[1])); - for (i = 0; i < n; i++) { - for (j = 0; j < n; j++) - printf("%d\t", *(D + n * i + j)); - printf("\n"); - } - - return 0; -} diff --git a/matrix_chain_order.py b/matrix_chain_order.py index e494ae4..5de6f1e 100644 --- a/matrix_chain_order.py +++ b/matrix_chain_order.py @@ -1,6 +1,7 @@ #!/usr/bin/env ipython -from numpy import zeros +from numpy import zeros + def bottom_up_matrix_chain_order(p): n = len(p) - 1 @@ -15,7 +16,9 @@ def bottom_up_matrix_chain_order(p): if q < m[i, j]: m[i, j] = q s[i, j] = k - return m,s + return m, s + + def memoized_matrix_chain_order(p): n = len(p) - 1 m = zeros((n + 1, n + 1)) @@ -23,6 +26,8 @@ def memoized_matrix_chain_order(p): for j in range(1, n + 1): m[i, j] = float("Inf") return lookup_chain(m, p, 1, n) + + def lookup_chain(m, p, i, j): if m[i, j] < float("Inf"): return m[i, j] @@ -34,22 +39,27 @@ def lookup_chain(m, p, i, j): if q < m[i, j]: m[i, j] = q return m[i, j] + + def print_optimal_parens(s, i, j): if i == j: - print "A{}".format(int(i)), + print("A{}".format(int(i)), ) else: - print "(", + print("(", ) print_optimal_parens(s, i, s[i, j]) print_optimal_parens(s, s[i, j] + 1, j) - print ")", + print(")", ) + # An incorrect greedy approach for matrix chain order problem def greedy_matrix_chain_order(p): n = len(p) - 1 return greedy_matrix_chain_order_aux(p, 1, n) + + def greedy_matrix_chain_order_aux(p, i, j): if i == j: - return 0 + return 0 q = float("Inf") for k in range(i, j): value = p[i - 1] * p[k] * p[j] diff --git a/min_gap_tree.py b/min_gap_tree.py index 44df937..77d4925 100644 --- a/min_gap_tree.py +++ b/min_gap_tree.py @@ -16,7 +16,7 @@ def __init__(self, values): for i in values: self.insert(min_gap_node(i, None, None, None, 0, None, None)) else: - print "Not invalid argument" + print( "Not invalid argument") def insert(self, z): y = self.nil x = self.root diff --git a/min_gap_tree_test.py b/min_gap_tree_test.py index aef1bb7..776db14 100755 --- a/min_gap_tree_test.py +++ b/min_gap_tree_test.py @@ -7,28 +7,33 @@ class TestMinGapTree(unittest.TestCase): def test_insert_one(self): T = min_gap_tree([50]) self.wrap(T, 50, float("Inf")) + def test_insert_two(self): T = min_gap_tree([50, 38]) self.wrap(T, 50, 12) self.wrap(T, 38, 12) + def test_insert_three(self): T = min_gap_tree([50, 38, 31]) self.wrap(T, 38, 7) self.wrap(T, 31, 7) self.wrap(T, 50, float("Inf")) + def test_insert_four(self): T = min_gap_tree([50, 38, 31, 12]) - self.wrap(T, 38, 7) + self.wrap(T, 38, 7) self.wrap(T, 31, 7) self.wrap(T, 50, float("Inf")) self.wrap(T, 12, 19) + def test_insert_five(self): T = min_gap_tree([50, 38, 31, 12, 19]) - self.wrap(T, 38, 7) + self.wrap(T, 38, 7) self.wrap(T, 19, 7) self.wrap(T, 50, float("Inf")) self.wrap(T, 12, 7) self.wrap(T, 31, 7) + def test_insert_six(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) self.wrap(T, 38, 3) @@ -37,6 +42,7 @@ def test_insert_six(self): self.wrap(T, 12, 3) self.wrap(T, 31, 7) self.wrap(T, 9, 3) + def test_delete_one(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -45,6 +51,7 @@ def test_delete_one(self): self.wrap(T, 50, float("Inf")) self.wrap(T, 12, 7) self.wrap(T, 31, 7) + def test_delete_two(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -53,6 +60,7 @@ def test_delete_two(self): self.wrap(T, 19, 7) self.wrap(T, 50, float("Inf")) self.wrap(T, 31, 7) + def test_delete_three(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -61,6 +69,7 @@ def test_delete_three(self): self.wrap(T, 38, 7) self.wrap(T, 31, 7) self.wrap(T, 50, float("Inf")) + def test_delete_four(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -69,6 +78,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, 12) self.wrap(T, 50, float("Inf")) + def test_delete_five(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -77,6 +87,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 50, float("Inf")) + def test_delete_six(self): T = min_gap_tree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -85,8 +96,11 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(50)) - self.assertEquals(T.root, T.nil) + self.assertEqual(T.root, T.nil) + def wrap(self, tree, node, min_gap): - self.assertEquals(tree.iterative_tree_search(node).min_gap, min_gap) + self.assertEqual(tree.iterative_tree_search(node).min_gap, min_gap) + + if __name__ == '__main__': unittest.main() diff --git a/min_heap_with_linked_list.py b/min_heap_with_linked_list.py index fc2a7bd..35902ea 100644 --- a/min_heap_with_linked_list.py +++ b/min_heap_with_linked_list.py @@ -1,4 +1,6 @@ from linked_list import linked_list_node, linked_list +import sys + class min_heap(list): def __init__(self, data): @@ -6,14 +8,19 @@ def __init__(self, data): self.length = len(data) self.heap_size = self.length self.build_min_heap() + def __contains__(self, y): return y in self[0:self.heap_size] + def left(self, i): return 2 * i + 1 + def right(self, i): return 2 * i + 2 + def parent(self, i): return (i - 1) / 2 + def min_heapify(self, i): l = self.left(i) r = self.right(i) @@ -23,16 +30,20 @@ def min_heapify(self, i): smallest = i if (r <= (self.heap_size - 1)) and (self[r].key < self[smallest].key): smallest = r - if smallest != i: - self[i],self[smallest] = self[smallest],self[i] + if smallest != i: + self[i], self[smallest] = self[smallest], self[i] self.min_heapify(smallest) + def build_min_heap(self): self.heap_size = self.length - for i in range(self.length / 2 - 1, -1, -1): + for i in range(self.length // 2 - 1, -1, -1): self.min_heapify(i) + + class min_priority_queue(min_heap): def heap_minimum(self): return self[0].head + def heap_extract_min(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -42,6 +53,7 @@ def heap_extract_min(self): self.heap_size = self.heap_size - 1 self.min_heapify(0) return minimum + def heap_decrease_key(self, i, element, key): if key > self[i]: sys.exit("new key is larger than current key") @@ -49,8 +61,9 @@ def heap_decrease_key(self, i, element, key): while i > 0 and self[self.parent(i)] > self[i]: tmp = self[self.parent(i)] self[self.parent(i)] = self[i] - self[i] = tmp + self[i] = tmp i = self.parent(i) + def min_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py index 67bbdaf..432b1a2 100644 --- a/min_heap_with_linked_list_test.py +++ b/min_heap_with_linked_list_test.py @@ -19,7 +19,7 @@ def test_min_heapify(self): L3.insert(linked_list_node(5)) h = min_heap([L5, L1, L2, L3, L4]) h.min_heapify(0) - self.assertEquals(h, [L1, L3, L2, L5, L4]) + self.assertEqual(h, [L1, L3, L2, L5, L4]) def test_build_min_heap(self): L1 = linked_list(1) L2 = linked_list(2) @@ -36,7 +36,7 @@ def test_build_min_heap(self): L3.insert(linked_list_node(5)) h = min_heap([L3, L4, L5, L2, L1]) h.build_min_heap() - self.assertEquals(h, [L1, L2, L5, L3, L4]) + self.assertEqual(h, [L1, L2, L5, L3, L4]) def test_heap_minimum(self): L1 = linked_list(1) L1.insert(linked_list_node(1)) @@ -54,7 +54,7 @@ def test_heap_minimum(self): L3.insert(linked_list_node(5)) L3.insert(linked_list_node(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) - self.assertEquals(q.heap_minimum().key, 1) + self.assertEqual(q.heap_minimum().key, 1) def test_heap_extract_min(self): L1 = linked_list(1) L1.insert(linked_list_node(1)) @@ -72,18 +72,18 @@ def test_heap_extract_min(self): L3.insert(linked_list_node(5)) L3.insert(linked_list_node(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) - self.assertEquals(q.heap_extract_min().key, 1) - self.assertEquals(q, [L1, L2, L3, L4, L5]) - self.assertEquals(q.heap_extract_min().key, 1) - self.assertEquals(q, [L2, L4, L3, L5, L5]) + self.assertEqual(q.heap_extract_min().key, 1) + self.assertEqual(q, [L1, L2, L3, L4, L5]) + self.assertEqual(q.heap_extract_min().key, 1) + self.assertEqual(q, [L2, L4, L3, L5, L5]) # def test_heap_decrease_key(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] # q = min_priority_queue(a) # q.heap_decrease_key(8, 1) -# self.assertEquals(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) +# self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) # def test_heap_insert(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] # q = min_priority_queue(a) # q.heap_extract_min() # q.min_heap_insert(0) -# self.assertEquals(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) +# self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/min_priority_queue_using_rb_tree_test.py b/min_priority_queue_using_rb_tree_test.py index d6faca0..6ebf788 100644 --- a/min_priority_queue_using_rb_tree_test.py +++ b/min_priority_queue_using_rb_tree_test.py @@ -3,38 +3,43 @@ from min_priority_queue_using_rb_tree import min_priority_queue from rb_tree import rb_node + class TestMinPriorityQueue(unittest.TestCase): def test_extract_min(self): q = min_priority_queue([41, 38, 31, 12, 19, 9]) - self.assertEquals(q.heap_extract_min().key, 9) - self.assertEquals(q.heap_extract_min().key, 12) - self.assertEquals(q.heap_extract_min().key, 19) - self.assertEquals(q.heap_extract_min().key, 31) - self.assertEquals(q.heap_extract_min().key, 38) - self.assertEquals(q.heap_extract_min().key, 41) + self.assertEqual(q.heap_extract_min().key, 9) + self.assertEqual(q.heap_extract_min().key, 12) + self.assertEqual(q.heap_extract_min().key, 19) + self.assertEqual(q.heap_extract_min().key, 31) + self.assertEqual(q.heap_extract_min().key, 38) + self.assertEqual(q.heap_extract_min().key, 41) + def test_heap_decrease_key(self): q = min_priority_queue([41, 38, 31, 12, 19, 9]) q.heap_decrease_key(q.iterative_tree_search(9), 5) q.heap_decrease_key(q.iterative_tree_search(38), 5) - self.assertEquals(q.heap_extract_min().key, 5) - self.assertEquals(q.heap_extract_min().key, 5) - self.assertEquals(q.heap_extract_min().key, 12) - self.assertEquals(q.heap_extract_min().key, 19) - self.assertEquals(q.heap_extract_min().key, 31) - self.assertEquals(q.heap_extract_min().key, 41) + self.assertEqual(q.heap_extract_min().key, 5) + self.assertEqual(q.heap_extract_min().key, 5) + self.assertEqual(q.heap_extract_min().key, 12) + self.assertEqual(q.heap_extract_min().key, 19) + self.assertEqual(q.heap_extract_min().key, 31) + self.assertEqual(q.heap_extract_min().key, 41) + def test_heap_insert(self): q = min_priority_queue([41, 38, 31, 12, 19, 9]) q.min_heap_insert(rb_node(5, None, None, None, 0)) q.min_heap_insert(rb_node(38, None, None, None, 0)) q.min_heap_insert(rb_node(50, None, None, None, 0)) - self.assertEquals(q.heap_extract_min().key, 5) - self.assertEquals(q.heap_extract_min().key, 9) - self.assertEquals(q.heap_extract_min().key, 12) - self.assertEquals(q.heap_extract_min().key, 19) - self.assertEquals(q.heap_extract_min().key, 31) - self.assertEquals(q.heap_extract_min().key, 38) - self.assertEquals(q.heap_extract_min().key, 38) - self.assertEquals(q.heap_extract_min().key, 41) - self.assertEquals(q.heap_extract_min().key, 50) + self.assertEqual(q.heap_extract_min().key, 5) + self.assertEqual(q.heap_extract_min().key, 9) + self.assertEqual(q.heap_extract_min().key, 12) + self.assertEqual(q.heap_extract_min().key, 19) + self.assertEqual(q.heap_extract_min().key, 31) + self.assertEqual(q.heap_extract_min().key, 38) + self.assertEqual(q.heap_extract_min().key, 38) + self.assertEqual(q.heap_extract_min().key, 41) + self.assertEqual(q.heap_extract_min().key, 50) + + if __name__ == '__main__': unittest.main() diff --git a/most_reliable_path_test.py b/most_reliable_path_test.py index 1383f7b..4817889 100644 --- a/most_reliable_path_test.py +++ b/most_reliable_path_test.py @@ -2,6 +2,7 @@ import unittest from graph import Vertex, Graph + class TestMostReliablePath(unittest.TestCase): def test_most_reliable_path(self): s = Vertex('s') @@ -11,15 +12,17 @@ def test_most_reliable_path(self): vertices = [s, u, v, w] edges = [(s, u), (s, v), (s, w), (u, v), (u, w), (w, u)] G = Graph(vertices, edges) - probabilities = [0.2, 0.1, 0.15, 0.7, 0.6, 0.9] + probabilities = [0.2, 0.1, 0.15, 0.7, 0.6, 0.9] re = dict() - for i,j in zip(edges, probabilities): - re[i] = j + for i, j in zip(edges, probabilities): + re[i] = j + def r(x, y): - return re[(x, y)] + return re[(x, y)] + most_reliable_path(G, r, s) - self.assertEquals([i.p for i in vertices], [None, s, u, s]) - self.assertEquals([round(i.r, 2) for i in vertices], [1, 0.2, 0.14, 0.15]) + self.assertEqual([i.p for i in vertices], [None, s, u, s]) + self.assertEqual([round(i.r, 2) for i in vertices], [1, 0.2, 0.14, 0.15]) most_reliable_path(G, r, u) - self.assertEquals([i.p for i in vertices], [None, None, u, u]) - self.assertEquals([round(i.r, 2) for i in vertices], [0, 1, 0.7, 0.6]) + self.assertEqual([i.p for i in vertices], [None, None, u, u]) + self.assertEqual([round(i.r, 2) for i in vertices], [0, 1, 0.7, 0.6]) diff --git a/optimal_binary_search_tree.py b/optimal_binary_search_tree.py index b5b1419..6687b6d 100644 --- a/optimal_binary_search_tree.py +++ b/optimal_binary_search_tree.py @@ -1,11 +1,12 @@ from numpy import zeros + def optimal_bst(p, q, n): e = zeros((n + 2, n + 1)) w = zeros((n + 2, n + 1)) root = zeros((1 + n, 1 + n)) for i in range(1, n + 2): - print "i = {}".format(i) + print("i = {}".format(i)) e[i, i - 1] = q[i - 1] w[i, i - 1] = q[i - 1] for l in range(1, n + 1): @@ -18,27 +19,31 @@ def optimal_bst(p, q, n): if t < e[i, j]: e[i, j] = t root[i, j] = r - return e,root + return e, root + + def construct_optimal_bst(root): n = root.shape[1] - 1 r = root[1, n] - print "k{} is the root".format(int(r)) + print("k{} is the root".format(int(r))) construct_optimal_bst_aux(root, r, 1, r - 1) construct_optimal_bst_aux(root, r, r + 1, n) + + def construct_optimal_bst_aux(root, p, i, j): if j < p: if i <= j: r = root[i, j] - print "k{} is the left child of k{}".format(int(r), int(p)) + print("k{} is the left child of k{}".format(int(r), int(p))) construct_optimal_bst_aux(root, r, i, r - 1) construct_optimal_bst_aux(root, r, r + 1, j) else: - print "d{} is the left child of k{}".format(int(j), int(p)) + print("d{} is the left child of k{}".format(int(j), int(p))) if i > p: if i <= j: r = root[i, j] - print "k{} is the right child of k{}".format(int(r), int(p)) + print("k{} is the right child of k{}".format(int(r), int(p))) construct_optimal_bst_aux(root, r, i, r - 1) construct_optimal_bst_aux(root, r, r + 1, j) else: - print "d{} is the right child of k{}".format(int(j), int(p)) + print("d{} is the right child of k{}".format(int(j), int(p))) diff --git a/os_tree.py b/os_tree.py index a30d31e..de4ea05 100755 --- a/os_tree.py +++ b/os_tree.py @@ -2,10 +2,12 @@ from rb_tree import rb_node, rb_tree + class os_node(rb_node): def __init__(self, key, p, left, right, color, size): rb_node.__init__(self, key, p, left, right, color) self.size = size + def select_recursive(self, i): r = self.left.size + 1 if i == r: @@ -14,6 +16,7 @@ def select_recursive(self, i): return self.left.select_recursive(i) else: return self.right.select_recursive(i - r) + def select_iterative(self, i): x = self while True: @@ -25,6 +28,7 @@ def select_iterative(self, i): else: x = x.right i = i - r + def key_rank(self, k): r = self.left.size + 1 if k == self.key: @@ -33,6 +37,7 @@ def key_rank(self, k): return self.left.key_rank(k) else: return r + self.right.key_rank(k) + def ith_successor(self, i): if i == 0: return self @@ -47,15 +52,19 @@ def ith_successor(self, i): y = y.p if y.size != 0: return y.ith_successor(i - r - 1) + + class os_tree(rb_tree): nil = os_node(None, None, None, None, 1, 0) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(os_node(i, None, None, None, 0, 1)) else: - print "Not invalid argument" + print("Not invalid argument") + def insert(self, z): y = self.nil x = self.root @@ -75,8 +84,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def delete(self, z): y = z y_original_color = y.color @@ -106,6 +116,7 @@ def delete(self, z): traverse = traverse.p if y_original_color == 1: self.delete_fixup(x) + def left_rotate(self, x): y = x.right x.right = y.left @@ -122,6 +133,7 @@ def left_rotate(self, x): x.p = y y.size = x.size x.size = x.left.size + x.right.size + 1 + def right_rotate(self, y): x = y.left y.left = x.right @@ -138,6 +150,7 @@ def right_rotate(self, y): y.p = x x.size = y.size y.size = y.left.size + y.right.size + 1 + def rank(self, x): r = x.left.size + 1 y = x diff --git a/os_tree_test.py b/os_tree_test.py index 83e77b2..bf84248 100755 --- a/os_tree_test.py +++ b/os_tree_test.py @@ -6,50 +6,56 @@ class TestOstree(unittest.TestCase): def test_insert_one(self): T = os_tree([41]) - print T.root.iterative_tree_search(41).p.key - self.assertEquals(T.root, T.root.iterative_tree_search(41)) - self.assertEquals(T.nil.size, 0) + print(T.root.iterative_tree_search(41).p.key) + self.assertEqual(T.root, T.root.iterative_tree_search(41)) + self.assertEqual(T.nil.size, 0) self.wrap(T, 41, -1, -1, -1, 1, 1) + def test_insert_two(self): T = os_tree([41, 38]) - self.assertEquals(T.root, T.iterative_tree_search(41)) - self.assertEquals(T.nil.size, 0) + self.assertEqual(T.root, T.iterative_tree_search(41)) + self.assertEqual(T.nil.size, 0) self.wrap(T, 41, 38, -1, -1, 1, 2) self.wrap(T, 38, -1, -1, 41, 0, 1) + def test_insert_three(self): T = os_tree([41, 38, 31]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.size, 0) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.size, 0) self.wrap(T, 38, 31, 41, -1, 1, 3) self.wrap(T, 31, -1, -1, 38, 0, 1) self.wrap(T, 41, -1, -1, 38, 0, 1) + def test_insert_four(self): T = os_tree([41, 38, 31, 12]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.size, 0) - self.wrap(T, 38, 31, 41, -1, 1, 4) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.size, 0) + self.wrap(T, 38, 31, 41, -1, 1, 4) self.wrap(T, 31, 12, -1, 38, 1, 2) self.wrap(T, 41, -1, -1, 38, 1, 1) self.wrap(T, 12, -1, -1, 31, 0, 1) + def test_insert_five(self): T = os_tree([41, 38, 31, 12, 19]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.size, 0) - self.wrap(T, 38, 19, 41, -1, 1, 5) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.size, 0) + self.wrap(T, 38, 19, 41, -1, 1, 5) self.wrap(T, 19, 12, 31, 38, 1, 3) self.wrap(T, 41, -1, -1, 38, 1, 1) self.wrap(T, 12, -1, -1, 19, 0, 1) self.wrap(T, 31, -1, -1, 19, 0, 1) + def test_insert_six(self): T = os_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.size, 0) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.size, 0) self.wrap(T, 38, 19, 41, -1, 1, 6) self.wrap(T, 19, 12, 31, 38, 0, 4) self.wrap(T, 41, -1, -1, 38, 1, 1) self.wrap(T, 12, 9, -1, 19, 1, 2) self.wrap(T, 31, -1, -1, 19, 1, 1) self.wrap(T, 9, -1, -1, 12, 0, 1) + def test_delete_one(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -58,6 +64,7 @@ def test_delete_one(self): self.wrap(T, 41, -1, -1, 38, 1, 1) self.wrap(T, 12, -1, -1, 19, 1, 1) self.wrap(T, 31, -1, -1, 19, 1, 1) + def test_delete_two(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -66,6 +73,7 @@ def test_delete_two(self): self.wrap(T, 19, -1, 31, 38, 1, 2) self.wrap(T, 41, -1, -1, 38, 1, 1) self.wrap(T, 31, -1, -1, 19, 0, 1) + def test_delete_three(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -74,6 +82,7 @@ def test_delete_three(self): self.wrap(T, 38, 31, 41, -1, 1, 3) self.wrap(T, 31, -1, -1, 38, 1, 1) self.wrap(T, 41, -1, -1, 38, 1, 1) + def test_delete_four(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -82,6 +91,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, -1, 41, -1, 1, 2) self.wrap(T, 41, -1, -1, 38, 0, 1) + def test_delete_five(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -90,6 +100,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 41, -1, -1, -1, 1, 1) + def test_delete_six(self): T = os_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -98,62 +109,69 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.root, T.nil) - self.assertEquals(T.nil.size, 0) + self.assertEqual(T.root, T.nil) + self.assertEqual(T.nil.size, 0) + def test_key_rank(self): T = os_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.root.key_rank(41), 6) - self.assertEquals(T.root.key_rank(38), 5) - self.assertEquals(T.root.key_rank(31), 4) - self.assertEquals(T.root.key_rank(12), 2) - self.assertEquals(T.root.key_rank(19), 3) - self.assertEquals(T.root.key_rank(9), 1) + self.assertEqual(T.root.key_rank(41), 6) + self.assertEqual(T.root.key_rank(38), 5) + self.assertEqual(T.root.key_rank(31), 4) + self.assertEqual(T.root.key_rank(12), 2) + self.assertEqual(T.root.key_rank(19), 3) + self.assertEqual(T.root.key_rank(9), 1) + def test_rank(self): T = os_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.rank(T.iterative_tree_search(41)), 6) - self.assertEquals(T.rank(T.iterative_tree_search(38)), 5) - self.assertEquals(T.rank(T.iterative_tree_search(31)), 4) - self.assertEquals(T.rank(T.iterative_tree_search(12)), 2) - self.assertEquals(T.rank(T.iterative_tree_search(19)), 3) - self.assertEquals(T.rank(T.iterative_tree_search(9)), 1) + self.assertEqual(T.rank(T.iterative_tree_search(41)), 6) + self.assertEqual(T.rank(T.iterative_tree_search(38)), 5) + self.assertEqual(T.rank(T.iterative_tree_search(31)), 4) + self.assertEqual(T.rank(T.iterative_tree_search(12)), 2) + self.assertEqual(T.rank(T.iterative_tree_search(19)), 3) + self.assertEqual(T.rank(T.iterative_tree_search(9)), 1) + def test_select(self): T = os_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.root.select_recursive(1).key, 9) - self.assertEquals(T.root.select_recursive(2).key, 12) - self.assertEquals(T.root.select_recursive(3).key, 19) - self.assertEquals(T.root.select_recursive(4).key, 31) - self.assertEquals(T.root.select_recursive(5).key, 38) - self.assertEquals(T.root.select_recursive(6).key, 41) - self.assertEquals(T.root.select_iterative(1).key, 9) - self.assertEquals(T.root.select_iterative(2).key, 12) - self.assertEquals(T.root.select_iterative(3).key, 19) - self.assertEquals(T.root.select_iterative(4).key, 31) - self.assertEquals(T.root.select_iterative(5).key, 38) - self.assertEquals(T.root.select_iterative(6).key, 41) + self.assertEqual(T.root.select_recursive(1).key, 9) + self.assertEqual(T.root.select_recursive(2).key, 12) + self.assertEqual(T.root.select_recursive(3).key, 19) + self.assertEqual(T.root.select_recursive(4).key, 31) + self.assertEqual(T.root.select_recursive(5).key, 38) + self.assertEqual(T.root.select_recursive(6).key, 41) + self.assertEqual(T.root.select_iterative(1).key, 9) + self.assertEqual(T.root.select_iterative(2).key, 12) + self.assertEqual(T.root.select_iterative(3).key, 19) + self.assertEqual(T.root.select_iterative(4).key, 31) + self.assertEqual(T.root.select_iterative(5).key, 38) + self.assertEqual(T.root.select_iterative(6).key, 41) + def test_ith_successor(self): T = os_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.iterative_tree_search(9).ith_successor(1).key, 12) - self.assertEquals(T.iterative_tree_search(9).ith_successor(2).key, 19) - self.assertEquals(T.iterative_tree_search(9).ith_successor(3).key, 31) - self.assertEquals(T.iterative_tree_search(9).ith_successor(4).key, 38) - self.assertEquals(T.iterative_tree_search(9).ith_successor(5).key, 41) -# def test_insert_stack(self): -# T = os_tree([]) -# for i in 41, 38, 31, 12, 19, 9: -# T.insert_stack(os_node(i, None, None, None, 0)) -# self.assertEquals(T.root, T.iterative_tree_search(38)) -# self.assertEquals(T.nil.color, 1) -# self.wrap(T, 38, 19, 41, -1, 1) -# self.wrap(T, 19, 12, 31, 38, 0) -# self.wrap(T, 41, -1, -1, 38, 1) -# self.wrap(T, 12, 9, -1, 19, 1) -# self.wrap(T, 31, -1, -1, 19, 1) -# self.wrap(T, 9, -1, -1, 12, 0) + self.assertEqual(T.iterative_tree_search(9).ith_successor(1).key, 12) + self.assertEqual(T.iterative_tree_search(9).ith_successor(2).key, 19) + self.assertEqual(T.iterative_tree_search(9).ith_successor(3).key, 31) + self.assertEqual(T.iterative_tree_search(9).ith_successor(4).key, 38) + self.assertEqual(T.iterative_tree_search(9).ith_successor(5).key, 41) + + # def test_insert_stack(self): + # T = os_tree([]) + # for i in 41, 38, 31, 12, 19, 9: + # T.insert_stack(os_node(i, None, None, None, 0)) + # self.assertEqual(T.root, T.iterative_tree_search(38)) + # self.assertEqual(T.nil.color, 1) + # self.wrap(T, 38, 19, 41, -1, 1) + # self.wrap(T, 19, 12, 31, 38, 0) + # self.wrap(T, 41, -1, -1, 38, 1) + # self.wrap(T, 12, 9, -1, 19, 1) + # self.wrap(T, 31, -1, -1, 19, 1) + # self.wrap(T, 9, -1, -1, 12, 0) def wrap(self, tree, node, left, right, p, color, size): - self.assertEquals(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEquals(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEquals(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) - self.assertEquals(tree.iterative_tree_search(node).color, color) - self.assertEquals(tree.iterative_tree_search(node).size, size) + self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search(node).color, color) + self.assertEqual(tree.iterative_tree_search(node).size, size) + + if __name__ == '__main__': unittest.main() diff --git a/partition.py b/partition.py index 2f449b5..d335eba 100644 --- a/partition.py +++ b/partition.py @@ -1,5 +1,6 @@ import random + def partition(A, p, r): x = A[r] i = p - 1 @@ -10,10 +11,11 @@ def partition(A, p, r): A[i + 1], A[r] = A[r], A[i + 1] return i + 1 + def partition2(A, p, r): - ''' + """ Partition A into three parts: < x, = x, > x. The return value is the median of the second part. So the return value is floor((p + r) / 2) when all elements in the array A[p .. r] have the same value. Partition in place. - ''' + """ x = A[r] i = p - 1 k = i @@ -28,12 +30,13 @@ def partition2(A, p, r): k = k + 1 A[k], A[j] = A[j], A[k] A[k + 1], A[r] = A[r], A[k + 1] - return (k + 2 + i) / 2 + return (k + 2 + i) // 2 + def partition3(A, p, r): - ''' + """ Variant of partition2. Requires O(n) extra space, but it is easier to implement. - ''' + """ x = A[r] n = r - p + 1 i = -1 @@ -50,7 +53,8 @@ def partition3(A, p, r): B[j] = x for j in range(p, r + 1): A[j] = B[j - p] - return (2 * p + i + k) / 2 + return (2 * p + i + k) // 2 + def randomized_partition(A, p, r): i = random.randint(p, r) diff --git a/partition_test.py b/partition_test.py index c5407ef..7f82011 100644 --- a/partition_test.py +++ b/partition_test.py @@ -1,17 +1,19 @@ import unittest from partition import partition, partition2, partition3 + class TestPartition(unittest.TestCase): def test_partition(self): a = [2, 8, 7, 1, 3, 5, 6, 4] partition(a, 0, 7) - self.assertEquals(a, [2, 1, 3, 4, 7, 5, 6, 8]) + self.assertEqual(a, [2, 1, 3, 4, 7, 5, 6, 8]) + def test_partition2(self): a = [2, 8, 7, 1, 4, 5, 6, 4] partition2(a, 0, 7) - self.assertEquals(a, [2, 1, 4, 4, 7, 5, 6, 8]) + self.assertEqual(a, [2, 1, 4, 4, 7, 5, 6, 8]) + def test_partition3(self): a = [2, 8, 7, 1, 3, 5, 6, 4] partition3(a, 0, 7) - self.assertEquals(a, [2, 1, 3, 4, 6, 5, 7, 8]) - + self.assertEqual(a, [2, 1, 3, 4, 6, 5, 7, 8]) diff --git a/pointer_tree.py b/pointer_tree.py index 57e431f..72ad12d 100644 --- a/pointer_tree.py +++ b/pointer_tree.py @@ -2,6 +2,7 @@ from rb_tree import rb_node, rb_tree + class pointer_node(rb_node): def __init__(self, key, p, left, right, color, minimum, maximum, predecessor, successor): rb_node.__init__(self, key, p, left, right, color) @@ -9,17 +10,21 @@ def __init__(self, key, p, left, right, color, minimum, maximum, predecessor, su self.maximum = maximum self.predecessor = predecessor self.successor = successor + + class pointer_tree(rb_tree): negative_infinity = pointer_node(float("-Inf"), None, None, None, 1, None, None, None, None) positive_infinity = pointer_node(float("Inf"), None, None, None, 1, None, None, None, None) nil = pointer_node(None, None, None, None, 1, negative_infinity, positive_infinity, None, None) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(pointer_node(i, None, None, None, 0, None, None, None, None)) else: - print "Not invalid argument" + print("Not invalid argument") + def insert(self, z): y = self.nil x = self.root @@ -61,8 +66,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def left_rotate(self, x): y = x.right x.right = y.left @@ -82,6 +88,7 @@ def left_rotate(self, x): x.maximum = x else: x.maximum = x.right.maximum + def right_rotate(self, y): x = y.left y.left = x.right @@ -101,6 +108,7 @@ def right_rotate(self, y): y.minimum = y else: y.minimum = y.left.minimum + def delete(self, z): y = z y_original_color = y.color diff --git a/pointer_tree_test.py b/pointer_tree_test.py index 4ef4f6c..a682d74 100755 --- a/pointer_tree_test.py +++ b/pointer_tree_test.py @@ -7,21 +7,25 @@ class TestOstree(unittest.TestCase): def test_insert_one(self): T = pointer_tree([41]) self.wrap(T, 41, 41, 41, float("-Inf"), float("Inf")) + def test_insert_two(self): T = pointer_tree([41, 38]) self.wrap(T, 41, 38, 41, 38, float("Inf")) self.wrap(T, 38, 38, 38, float("-Inf"), 41) + def test_insert_three(self): T = pointer_tree([41, 38, 31]) self.wrap(T, 38, 31, 41, 31, 41) self.wrap(T, 31, 31, 31, float("-Inf"), 38) self.wrap(T, 41, 41, 41, 38, float("Inf")) + def test_insert_four(self): T = pointer_tree([41, 38, 31, 12]) self.wrap(T, 38, 12, 41, 31, 41) self.wrap(T, 31, 12, 31, 12, 38) self.wrap(T, 41, 41, 41, 38, float("Inf")) self.wrap(T, 12, 12, 12, float("-Inf"), 31) + def test_insert_five(self): T = pointer_tree([41, 38, 31, 12, 19]) self.wrap(T, 38, 12, 41, 31, 41) @@ -29,6 +33,7 @@ def test_insert_five(self): self.wrap(T, 41, 41, 41, 38, float("Inf")) self.wrap(T, 12, 12, 12, float("-Inf"), 19) self.wrap(T, 31, 31, 31, 19, 38) + def test_insert_six(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) self.wrap(T, 38, 9, 41, 31, 41) @@ -37,6 +42,7 @@ def test_insert_six(self): self.wrap(T, 12, 9, 12, 9, 19) self.wrap(T, 31, 31, 31, 19, 38) self.wrap(T, 9, 9, 9, float("-Inf"), 12) + def test_delete_one(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -45,6 +51,7 @@ def test_delete_one(self): self.wrap(T, 41, 41, 41, 38, float("Inf")) self.wrap(T, 12, 12, 12, float("-Inf"), 19) self.wrap(T, 31, 31, 31, 19, 38) + def test_delete_two(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -53,6 +60,7 @@ def test_delete_two(self): self.wrap(T, 19, 19, 31, float("-Inf"), 31) self.wrap(T, 41, 41, 41, 38, float("Inf")) self.wrap(T, 31, 31, 31, 19, 38) + def test_delete_three(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -61,6 +69,7 @@ def test_delete_three(self): self.wrap(T, 38, 31, 41, 31, 41) self.wrap(T, 31, 31, 31, float("-Inf"), 38) self.wrap(T, 41, 41, 41, 38, float("Inf")) + def test_delete_four(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -69,6 +78,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, 38, 41, float("-Inf"), 41) self.wrap(T, 41, 41, 41, 38, float("Inf")) + def test_delete_five(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -76,7 +86,8 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(19)) T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) - self.wrap(T, 41, 41, 41, float("-Inf"), float("Inf")) + self.wrap(T, 41, 41, 41, float("-Inf"), float("Inf")) + def test_delete_six(self): T = pointer_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -85,11 +96,14 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.root, T.nil) + self.assertEqual(T.root, T.nil) + def wrap(self, tree, node, minimum, maximum, predecessor, successor): - self.assertEquals(tree.iterative_tree_search(node).minimum.key, minimum) - self.assertEquals(tree.iterative_tree_search(node).maximum.key, maximum) - self.assertEquals(tree.iterative_tree_search(node).predecessor.key, predecessor) - self.assertEquals(tree.iterative_tree_search(node).successor.key, successor) + self.assertEqual(tree.iterative_tree_search(node).minimum.key, minimum) + self.assertEqual(tree.iterative_tree_search(node).maximum.key, maximum) + self.assertEqual(tree.iterative_tree_search(node).predecessor.key, predecessor) + self.assertEqual(tree.iterative_tree_search(node).successor.key, successor) + + if __name__ == '__main__': unittest.main() diff --git a/polynomial_multiply.py b/polynomial_multiply.py index 11fd194..e6dc60e 100644 --- a/polynomial_multiply.py +++ b/polynomial_multiply.py @@ -1,11 +1,12 @@ import math -import ft +import fft -def polynominal_multiply(a, b, precision = 0): + +def polynominal_multiply(a, b, precision=0): a_len = len(a) b_len = len(b) length = int(2 ** (1 + math.ceil(math.log(max(a_len, b_len))))) - print length + print(length) extend_a = [0] * length extend_b = [0] * length for i in range(0, a_len): @@ -16,8 +17,8 @@ def polynominal_multiply(a, b, precision = 0): extend_b[i] = b[i] for i in range(b_len, length): extend_b[i] = 0 - a_fft = ft.recursive_fft(extend_a) - b_fft = ft.recursive_fft(extend_b) + a_fft = fft.recursive_fft(extend_a) + b_fft = fft.recursive_fft(extend_b) m_fft = [a_fft[i] * b_fft[i] for i in range(0, len(a_fft))] - ab = ft.recursive_inverse_fft(m_fft) - return [round(ab[i].real, precision) for i in range(0, a_len + b_len - 1)] + ab = fft.recursive_inverse_fft(m_fft) + return [round(ab[i].real, precision) for i in range(0, a_len + b_len - 1)] diff --git a/pow.c b/pow.c index 491909c..9a2501a 100644 --- a/pow.c +++ b/pow.c @@ -1,9 +1,4 @@ -// AUTHOR: WangQiang -// CREATE DATE: -// LAST UPDATE DATE: 20140524 -// EMAIL: cntqrxj@gmail.com - -/* pow: comput x^n; return value: x ^ n */ +/* pow: compute x^n; return value: x ^ n */ int pow1(int x, unsigned n) { int square; diff --git a/priority_queue_test.py b/priority_queue_test.py index b9a9999..c556694 100644 --- a/priority_queue_test.py +++ b/priority_queue_test.py @@ -1,74 +1,86 @@ import unittest from priority_queue import max_priority_queue, min_priority_queue + class TestMaxPriorityQueue(unittest.TestCase): def test_init(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] q = max_priority_queue(a) - self.assertEquals(q, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + self.assertEqual(q, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) + def test_heap_maximum(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - self.assertEquals(max_priority_queue(a).heap_maximum(), 16) + self.assertEqual(max_priority_queue(a).heap_maximum(), 16) + def test_heap_extract_max(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] h = max_priority_queue(a) - self.assertEquals(h.heap_extract_max(), 16) - self.assertEquals(h, [14, 8, 10, 4, 7, 9, 3, 2, 1, 1]) + self.assertEqual(h.heap_extract_max(), 16) + self.assertEqual(h, [14, 8, 10, 4, 7, 9, 3, 2, 1, 1]) + def test_heap_increase_key(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] h = max_priority_queue(a) h.heap_increase_key(8, 15) - self.assertEquals(h, [16, 15, 10, 14, 7, 9, 3, 2, 8, 1]) + self.assertEqual(h, [16, 15, 10, 14, 7, 9, 3, 2, 8, 1]) + def test_heap_insert(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] queue = max_priority_queue(a) queue.heap_extract_max() queue.max_heap_insert(100) - self.assertEquals(queue, [100, 14, 10, 4, 8, 9, 3, 2, 1, 7]) + self.assertEqual(queue, [100, 14, 10, 4, 8, 9, 3, 2, 1, 7]) + def test_heap_delete(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] h = max_priority_queue(a) h.heap_delete(4) - self.assertEquals(h[0:h.heap_size], [16, 14, 10, 8, 1, 9, 3, 2, 4]) + self.assertEqual(h[0:h.heap_size], [16, 14, 10, 8, 1, 9, 3, 2, 4]) h.heap_delete(2) - self.assertEquals(h[0:h.heap_size], [16, 14, 9, 8, 1, 4, 3, 2]) + self.assertEqual(h[0:h.heap_size], [16, 14, 9, 8, 1, 4, 3, 2]) h.heap_delete(0) - self.assertEquals(h[0:h.heap_size], [14, 8, 9, 2, 1, 4, 3]) + self.assertEqual(h[0:h.heap_size], [14, 8, 9, 2, 1, 4, 3]) h.heap_delete(5) - self.assertEquals(h[0:h.heap_size], [14, 8, 9, 2, 1, 3]) + self.assertEqual(h[0:h.heap_size], [14, 8, 9, 2, 1, 3]) h.heap_delete(3) - self.assertEquals(h[0:h.heap_size], [14, 8, 9, 3, 1]) + self.assertEqual(h[0:h.heap_size], [14, 8, 9, 3, 1]) h.heap_delete(1) - self.assertEquals(h[0:h.heap_size], [14, 3, 9, 1]) + self.assertEqual(h[0:h.heap_size], [14, 3, 9, 1]) h.heap_delete(3) - self.assertEquals(h[0:h.heap_size], [14, 3, 9]) + self.assertEqual(h[0:h.heap_size], [14, 3, 9]) h.heap_delete(2) - self.assertEquals(h[0:h.heap_size], [14, 3]) + self.assertEqual(h[0:h.heap_size], [14, 3]) h.heap_delete(1) - self.assertEquals(h[0:h.heap_size], [14]) + self.assertEqual(h[0:h.heap_size], [14]) h.heap_delete(0) - self.assertEquals(h[0:h.heap_size], []) + self.assertEqual(h[0:h.heap_size], []) + + class TestMinPriorityQueue(unittest.TestCase): def test_init(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] q = min_priority_queue(a) - self.assertEquals(q, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) + self.assertEqual(q, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) + def test_heap_minimum(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - self.assertEquals(min_priority_queue(a).heap_minimum(), 1) + self.assertEqual(min_priority_queue(a).heap_minimum(), 1) + def test_heap_extract_min(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] q = min_priority_queue(a) - self.assertEquals(q.heap_extract_min(), 1) - self.assertEquals(q, [2, 4, 3, 10, 7, 8, 9, 16, 14, 16]) + self.assertEqual(q.heap_extract_min(), 1) + self.assertEqual(q, [2, 4, 3, 10, 7, 8, 9, 16, 14, 16]) + def test_heap_decrease_key(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - q = min_priority_queue(a) + q = min_priority_queue(a) q.heap_decrease_key(8, 1) - self.assertEquals(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) + self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) + def test_heap_insert(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] q = min_priority_queue(a) q.heap_extract_min() q.min_heap_insert(0) - self.assertEquals(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) + self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/queue.py b/queue.py index fbbc0f1..37ad81c 100644 --- a/queue.py +++ b/queue.py @@ -1,34 +1,42 @@ class FullException(Exception): def __init__(self): Exception.__init__(self) + + class EmptyException(Exception): def __init__(self): Exception.__init__(self) + + class queue(object): def __init__(self, size): self.data = [0] * size self.length = size self.head = 0 self.tail = 0 + def enqueue(self, x): if self.full(): - raise FullException() + raise FullException() self.data[self.tail] = x if self.tail == self.length - 1: self.tail = 0 else: self.tail = self.tail + 1 + def dequeue(self): if self.empty(): - raise EmptyException() + raise EmptyException() x = self.data[self.head] if self.head == self.length - 1: self.head = 0 else: self.head = self.head + 1 return x + def empty(self): return self.tail == self.head + def full(self): - #print "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length) + # print( "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length)) return (self.tail + 1) % self.length == self.head diff --git a/quicksort_test.py b/quicksort_test.py index e09c230..e5605ac 100644 --- a/quicksort_test.py +++ b/quicksort_test.py @@ -1,32 +1,34 @@ import unittest from partition import partition, partition2, partition3 import random -from quicksort import quicksort, randomized_quicksort +from quicksort import quicksort, randomized_quicksort + class TestQuickSort(unittest.TestCase): def test_quicksort(self): - for i in range(0, 100): - A = [random.randint(1, 10000) for i in range(0, 100)] + for i in range(100): + A = [random.randint(1, 10000) for i in range(100)] B = A[:] quicksort(A, 0, len(A) - 1, partition) B.sort() - self.assertEquals(A, B) - for i in range(0, 100): - A = [random.randint(1, 10000) for i in range(0, 100)] + self.assertEqual(A, B) + for i in range(100): + A = [random.randint(1, 10000) for i in range(100)] B = A[:] quicksort(A, 0, len(A) - 1, partition2) B.sort() - self.assertEquals(A, B) - for i in range(0, 100): - A = [random.randint(1, 10000) for i in range(0, 100)] + self.assertEqual(A, B) + for i in range(100): + A = [random.randint(1, 10000) for i in range(100)] B = A[:] quicksort(A, 0, len(A) - 1, partition3) B.sort() - self.assertEquals(A, B) + self.assertEqual(A, B) + def test_randomized_quicksort(self): - for i in range(0, 100): - A = [random.randint(1, 10000) for i in range(0, 100)] + for i in range(100): + A = [random.randint(1, 10000) for i in range(100)] B = A[:] randomized_quicksort(A, 0, len(A) - 1) B.sort() - self.assertEquals(A, B) + self.assertEqual(A, B) diff --git a/randomized_select.py b/randomized_select.py index fac9905..101525f 100644 --- a/randomized_select.py +++ b/randomized_select.py @@ -1,5 +1,6 @@ from partition import randomized_partition + def randomized_select(A, p, r, i): if p == r: return A[p] @@ -11,4 +12,3 @@ def randomized_select(A, p, r, i): return randomized_select(A, p, q - 1, i) else: return randomized_select(A, q + 1, r, i - k) - diff --git a/randomized_select_test.py b/randomized_select_test.py index 64b6d72..a500497 100644 --- a/randomized_select_test.py +++ b/randomized_select_test.py @@ -1,12 +1,14 @@ import unittest from randomized_select import randomized_select + class TestRandSelect(unittest.TestCase): def test_randomize_select_distinct(self): a = [10, 11, 5, 3, 2, 6, 0, 8, 100, 50] - self.assertEquals(randomized_select(a, 0, 9, 5), 6) + self.assertEqual(randomized_select(a, 0, 9, 5), 6) + def test_randomize_select_duplicate(self): a = [10, 11, 5, 8, 2, 6, 8, 8, 100, 50] - self.assertEquals(randomized_select(a, 0, 9, 4), 8) - self.assertEquals(randomized_select(a, 0, 9, 5), 8) - self.assertEquals(randomized_select(a, 0, 9, 6), 8) + self.assertEqual(randomized_select(a, 0, 9, 4), 8) + self.assertEqual(randomized_select(a, 0, 9, 5), 8) + self.assertEqual(randomized_select(a, 0, 9, 6), 8) diff --git a/rank_tree.py b/rank_tree.py index e9d66d4..3ba8f09 100644 --- a/rank_tree.py +++ b/rank_tree.py @@ -1,17 +1,20 @@ # The variant of os_tree that use rank instead of size -#!/usr/bin/env ipython +# !/usr/bin/env ipython from rb_tree import rb_node, rb_tree + class rank_node(rb_node): def __init__(self, key, p, left, right, color, rank): rb_node.__init__(self, key, p, left, right, color) self.rank = rank + def update_rank_whole_tree(self, amount): if self.rank != 0: self.rank = self.rank + amount self.left.update_rank_whole_tree(amount) self.right.update_rank_whole_tree(amount) + def decrease_all_successors(self, amount): self.rank = self.rank - amount self.right.update_rank_whole_tree(-1 * amount) @@ -23,15 +26,18 @@ def decrease_all_successors(self, amount): if y.rank != 0: y.decrease_all_successors(amount) + class rank_tree(rb_tree): nil = rank_node(None, None, None, None, 1, 0) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(rank_node(i, None, None, None, 0, 1)) else: - print "Not invalid argument" + print("Not invalid argument") + def insert(self, z): y = self.nil x = self.root @@ -55,10 +61,11 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def delete(self, z): - z.decrease_all_successors(1) # z is counted as a successor + z.decrease_all_successors(1) # z is counted as a successor y = z y_original_color = y.color if z.left == self.nil: diff --git a/rank_tree_test.py b/rank_tree_test.py index 2aa547e..d68c842 100755 --- a/rank_tree_test.py +++ b/rank_tree_test.py @@ -6,50 +6,56 @@ class TestOstree(unittest.TestCase): def test_insert_one(self): T = rank_tree([41]) - print T.root.iterative_tree_search(41).p.key - self.assertEquals(T.root, T.root.iterative_tree_search(41)) - self.assertEquals(T.nil.rank, 0) + print(T.root.iterative_tree_search(41).p.key) + self.assertEqual(T.root, T.root.iterative_tree_search(41)) + self.assertEqual(T.nil.rank, 0) self.wrap(T, 41, -1, -1, -1, 1, 1) + def test_insert_two(self): T = rank_tree([41, 38]) - self.assertEquals(T.root, T.iterative_tree_search(41)) - self.assertEquals(T.nil.rank, 0) + self.assertEqual(T.root, T.iterative_tree_search(41)) + self.assertEqual(T.nil.rank, 0) self.wrap(T, 41, 38, -1, -1, 1, 2) self.wrap(T, 38, -1, -1, 41, 0, 1) + def test_insert_three(self): T = rank_tree([41, 38, 31]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.rank, 0) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.rank, 0) self.wrap(T, 38, 31, 41, -1, 1, 2) self.wrap(T, 31, -1, -1, 38, 0, 1) self.wrap(T, 41, -1, -1, 38, 0, 3) + def test_insert_four(self): T = rank_tree([41, 38, 31, 12]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.rank, 0) - self.wrap(T, 38, 31, 41, -1, 1, 3) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.rank, 0) + self.wrap(T, 38, 31, 41, -1, 1, 3) self.wrap(T, 31, 12, -1, 38, 1, 2) self.wrap(T, 41, -1, -1, 38, 1, 4) self.wrap(T, 12, -1, -1, 31, 0, 1) + def test_insert_five(self): T = rank_tree([41, 38, 31, 12, 19]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.rank, 0) - self.wrap(T, 38, 19, 41, -1, 1, 4) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.rank, 0) + self.wrap(T, 38, 19, 41, -1, 1, 4) self.wrap(T, 19, 12, 31, 38, 1, 2) self.wrap(T, 41, -1, -1, 38, 1, 5) self.wrap(T, 12, -1, -1, 19, 0, 1) self.wrap(T, 31, -1, -1, 19, 0, 3) + def test_insert_six(self): T = rank_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.rank, 0) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.rank, 0) self.wrap(T, 38, 19, 41, -1, 1, 5) self.wrap(T, 19, 12, 31, 38, 0, 3) self.wrap(T, 41, -1, -1, 38, 1, 6) self.wrap(T, 12, 9, -1, 19, 1, 2) self.wrap(T, 31, -1, -1, 19, 1, 4) self.wrap(T, 9, -1, -1, 12, 0, 1) + def test_delete_one(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -58,6 +64,7 @@ def test_delete_one(self): self.wrap(T, 41, -1, -1, 38, 1, 5) self.wrap(T, 12, -1, -1, 19, 1, 1) self.wrap(T, 31, -1, -1, 19, 1, 3) + def test_delete_two(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -66,6 +73,7 @@ def test_delete_two(self): self.wrap(T, 19, -1, 31, 38, 1, 1) self.wrap(T, 41, -1, -1, 38, 1, 4) self.wrap(T, 31, -1, -1, 19, 0, 2) + def test_delete_three(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -74,6 +82,7 @@ def test_delete_three(self): self.wrap(T, 38, 31, 41, -1, 1, 2) self.wrap(T, 31, -1, -1, 38, 1, 1) self.wrap(T, 41, -1, -1, 38, 1, 3) + def test_delete_four(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -82,6 +91,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, -1, 41, -1, 1, 1) self.wrap(T, 41, -1, -1, 38, 0, 2) + def test_delete_five(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -90,6 +100,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 41, -1, -1, -1, 1, 1) + def test_delete_six(self): T = rank_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -98,13 +109,16 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.root, T.nil) - self.assertEquals(T.nil.rank, 0) + self.assertEqual(T.root, T.nil) + self.assertEqual(T.nil.rank, 0) + def wrap(self, tree, node, left, right, p, color, rank): - self.assertEquals(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEquals(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEquals(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) - self.assertEquals(tree.iterative_tree_search(node).color, color) - self.assertEquals(tree.iterative_tree_search(node).rank, rank) + self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search(node).color, color) + self.assertEqual(tree.iterative_tree_search(node).rank, rank) + + if __name__ == '__main__': unittest.main() diff --git a/rb_tree.py b/rb_tree.py index 3d5d0a3..e7ec3e0 100644 --- a/rb_tree.py +++ b/rb_tree.py @@ -4,10 +4,12 @@ from tree import Node, Tree + class rb_node(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color + def minimum(self, nil): x = self y = x @@ -16,17 +18,21 @@ def minimum(self, nil): x = x.left return y + class rb_tree(Tree): nil = rb_node(None, None, None, None, 1) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(rb_node(i, None, None, None, 0)) else: - print "Not invalid argument" + print("Not invalid argument") + def minimum(self): return self.root.minimum(self.nil) + def __getitem__(self, key): return self.iterative_tree_search(key) @@ -82,8 +88,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def insert_fixed(self, z): while z.p.color == 0: if z.p.p.left == z.p: @@ -117,6 +124,7 @@ def insert_fixed(self, z): z.color = 0 z.p.color = 1 self.root.color = 1 + def iterative_tree_search(self, k): x = self.root while x != self.nil and x.key != k: @@ -134,6 +142,7 @@ def transplant(self, u, v): else: u.p.right = v v.p = u.p + def delete(self, z): y = z y_original_color = y.color @@ -159,6 +168,7 @@ def delete(self, z): y.color = z.color if y_original_color == 1: self.delete_fixup(x) + def delete_fixup(self, x): while x != self.root and x.color == 1: if x == x.p.left: diff --git a/rb_tree_test.py b/rb_tree_test.py index 9efa1f6..4d22e1c 100755 --- a/rb_tree_test.py +++ b/rb_tree_test.py @@ -6,50 +6,56 @@ class TestRbtree(unittest.TestCase): def test_insert_one(self): T = rb_tree([41]) - print T.root.iterative_tree_search(41).p.key - self.assertEquals(T.root, T.root.iterative_tree_search(41)) - self.assertEquals(T.nil.color, 1) + print(T.root.iterative_tree_search(41).p.key) + self.assertEqual(T.root, T.root.iterative_tree_search(41)) + self.assertEqual(T.nil.color, 1) self.wrap(T, 41, -1, -1, -1, 1) + def test_insert_two(self): T = rb_tree([41, 38]) - self.assertEquals(T.root, T.iterative_tree_search(41)) - self.assertEquals(T.nil.color, 1) + self.assertEqual(T.root, T.iterative_tree_search(41)) + self.assertEqual(T.nil.color, 1) self.wrap(T, 41, 38, -1, -1, 1) self.wrap(T, 38, -1, -1, 41, 0) + def test_insert_three(self): T = rb_tree([41, 38, 31]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.color, 1) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 31, 41, -1, 1) self.wrap(T, 31, -1, -1, 38, 0) self.wrap(T, 41, -1, -1, 38, 0) + def test_insert_four(self): T = rb_tree([41, 38, 31, 12]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.color, 1) - self.wrap(T, 38, 31, 41, -1, 1) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.color, 1) + self.wrap(T, 38, 31, 41, -1, 1) self.wrap(T, 31, 12, -1, 38, 1) self.wrap(T, 41, -1, -1, 38, 1) self.wrap(T, 12, -1, -1, 31, 0) + def test_insert_five(self): T = rb_tree([41, 38, 31, 12, 19]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.color, 1) - self.wrap(T, 38, 19, 41, -1, 1) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.color, 1) + self.wrap(T, 38, 19, 41, -1, 1) self.wrap(T, 19, 12, 31, 38, 1) self.wrap(T, 41, -1, -1, 38, 1) self.wrap(T, 12, -1, -1, 19, 0) self.wrap(T, 31, -1, -1, 19, 0) + def test_insert_six(self): T = rb_tree([41, 38, 31, 12, 19, 9]) - self.assertEquals(T.root, T.iterative_tree_search(38)) - self.assertEquals(T.nil.color, 1) + self.assertEqual(T.root, T.iterative_tree_search(38)) + self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 19, 41, -1, 1) self.wrap(T, 19, 12, 31, 38, 0) self.wrap(T, 41, -1, -1, 38, 1) self.wrap(T, 12, 9, -1, 19, 1) self.wrap(T, 31, -1, -1, 19, 1) self.wrap(T, 9, -1, -1, 12, 0) + def test_delete_one(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -58,6 +64,7 @@ def test_delete_one(self): self.wrap(T, 41, -1, -1, 38, 1) self.wrap(T, 12, -1, -1, 19, 1) self.wrap(T, 31, -1, -1, 19, 1) + def test_delete_two(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -66,6 +73,7 @@ def test_delete_two(self): self.wrap(T, 19, -1, 31, 38, 1) self.wrap(T, 41, -1, -1, 38, 1) self.wrap(T, 31, -1, -1, 19, 0) + def test_delete_three(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -74,6 +82,7 @@ def test_delete_three(self): self.wrap(T, 38, 31, 41, -1, 1) self.wrap(T, 31, -1, -1, 38, 1) self.wrap(T, 41, -1, -1, 38, 1) + def test_delete_four(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -82,6 +91,7 @@ def test_delete_four(self): T.delete(T.iterative_tree_search(31)) self.wrap(T, 38, -1, 41, -1, 1) self.wrap(T, 41, -1, -1, 38, 0) + def test_delete_five(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -90,6 +100,7 @@ def test_delete_five(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) self.wrap(T, 41, -1, -1, -1, 1) + def test_delete_six(self): T = rb_tree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) @@ -98,11 +109,14 @@ def test_delete_six(self): T.delete(T.iterative_tree_search(31)) T.delete(T.iterative_tree_search(38)) T.delete(T.iterative_tree_search(41)) - self.assertEquals(T.root, T.nil) + self.assertEqual(T.root, T.nil) + def wrap(self, tree, node, left, right, p, color): - self.assertEquals(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEquals(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEquals(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) - self.assertEquals(tree.iterative_tree_search(node).color, color) + self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search(node).color, color) + + if __name__ == '__main__': unittest.main() diff --git a/segment_intersect.py b/segment_intersect.py index b17b420..a8d1864 100644 --- a/segment_intersect.py +++ b/segment_intersect.py @@ -1,5 +1,6 @@ #!/usr/bin/env ipython + def segments_intersect(p1, p2, p3, p4): d1 = direction(p3, p4, p1) d2 = direction(p3, p4, p2) @@ -17,10 +18,14 @@ def segments_intersect(p1, p2, p3, p4): return True else: return False + + def direction(pi, pj, pk): v1 = (pk[0] - pi[0], pk[1] - pi[1]) v2 = (pj[0] - pi[0], pj[1] - pi[1]) return v1[0] * v2[1] - v2[0] * v1[1] + + def on_segment(pi, pj, pk): if min(pi[0], pj[0]) <= pk[0] and pk[0] <= max(pi[0], pj[0]) and min(pi[1], pj[1]) <= pk[1] and pk[1] <= max(pi[1], pj[1]): return True diff --git a/simplex.py b/simplex.py index d472d2d..8f4b922 100644 --- a/simplex.py +++ b/simplex.py @@ -2,33 +2,35 @@ import sys + def pivot(N, B, A, b, c, v, l, e): new_A = dict() new_b = dict() new_c = dict() -#Compute the coefficients of the equation for new basic variable + # Compute the coefficients of the equation for new basic variable new_b[e] = b[l] / A[l][e] new_A[e] = dict() for j in N - {e}: new_A[e][j] = A[l][j] / A[l][e] new_A[e][l] = 1 / A[l][e] -#Compute the coefficients of the remaining constraints + # Compute the coefficients of the remaining constraints for i in B - {l}: new_A[i] = dict() new_b[i] = b[i] - A[i][e] * new_b[e] for j in N - {e}: new_A[i][j] = A[i][j] - A[i][e] * new_A[e][j] new_A[i][l] = -1 * A[i][e] * new_A[e][l] -#Compute the objective function + # Compute the objective function new_v = v + c[e] * new_b[e] for j in N - {e}: new_c[j] = c[j] - c[e] * new_A[e][j] new_c[l] = -1 * c[e] * new_A[e][l] -#Compute new sets of basic and nonbasic variables + # Compute new sets of basic and nonbasic variables new_N = (N - {e}).union({l}) new_B = (B - {l}).union({e}) return new_N, new_B, new_A, new_b, new_c, new_v + def simplex(A, b, c): N, B, A, b, c, v = initialize_simplex(A, b, c) while True: @@ -37,7 +39,7 @@ def simplex(A, b, c): if c[j] > 0: e = j break - if e == None: + if not e: break minimum = float("Inf") for i in sorted(B): @@ -50,7 +52,7 @@ def simplex(A, b, c): return "unbounded" else: (N, B, A, b, c, v) = pivot(N, B, A, b, c, v, l, e) - print N, B, A, b, c, v + print(N, B, A, b, c, v) n = len(N) x = [0] * n for i in range(1, n + 1): @@ -58,6 +60,7 @@ def simplex(A, b, c): x[i - 1] = b[i] return x + def initialize_simplex(A, b, c): m = len(b) n = len(c) @@ -88,7 +91,7 @@ def initialize_simplex(A, b, c): new_A[n + i] = dict() new_A[n + i][0] = -1 for j in range(1, n + 1): - new_A[n + i][j] = A[i -1][j - 1] + new_A[n + i][j] = A[i - 1][j - 1] for j in range(1, n + 1): new_c[j] = 0 new_c[0] = -1 @@ -100,17 +103,17 @@ def initialize_simplex(A, b, c): v = 0 l = n + k (N, B, A, b, c, v) = pivot(N, B, A, b, c, v, l, 0) - print N, B, A, b, c, v + print(N, B, A, b, c, v) while True: e = None - print N + print(N) for j in sorted(N): - print "c[{}] = {}".format(j, c[j]) + print("c[{}] = {}".format(j, c[j])) if c[j] > 0: e = j break - print "e = {}".format(e) - if e == None: + print("e = {}".format(e)) + if not e: break minimum = float("Inf") for i in sorted(B): @@ -119,15 +122,15 @@ def initialize_simplex(A, b, c): if minimum > delta: l = i minimum = delta - print "l = {}".format(l) + print("l = {}".format(l)) if minimum == float("Inf"): -# return "unbounded" + # return "unbounded" break else: (N, B, A, b, c, v) = pivot(N, B, A, b, c, v, l, e) - print N, B, A, b, c, v + print(N, B, A, b, c, v) if abs(v) <= 2.0e-10: - # if v == 0: + # if v == 0: if 0 in B: for e in N: if A[0][e] != 0: @@ -144,21 +147,20 @@ def initialize_simplex(A, b, c): N = N - {0} for j in N: new_c[j] = 0 - j - print N, B, A, b, c, v + print(N, B, A, b, c, v) for i in range(1, n + 1): if i in B: v = v + c[i] * b[i] for j in N: new_c[j] = new_c[j] - c[i] * A[i][j] else: - print "i = {}".format(i) - print N - print B - print new_c - print c + print("i = {}".format(i)) + print(N) + print(B) + print(new_c) + print(c) new_c[i] = new_c[i] + c[i - 1] - print N, B, new_A, b, new_c, v + print(N, B, new_A, b, new_c, v) return N, B, new_A, b, new_c, v else: sys.exit("infeasible") diff --git a/single_edge.py b/single_edge.py index 50e57b1..5f42ddf 100644 --- a/single_edge.py +++ b/single_edge.py @@ -4,8 +4,10 @@ class node(object): def __init__(self, key, right): self.right = right self.key = key + + class graph(object): - def __init__(self, data, option = 0): + def __init__(self, data, option=0): if option == 0: self.vertices_number = len(data) self.vertices = [None] * self.vertices_number @@ -17,57 +19,63 @@ def __init__(self, data, option = 0): self.vertices_number = data self.vertices = [None] * self.vertices_number self.edges_number = 0 + def transpose(self): t = graph(self.vertices_number, 1) for i in range(0, self.vertices_number): j = self.vertices[i] - while j != None: + while j is not None: t.insert_edge(j.key, i + 1) j = j.right return t + def union(self, g): u = graph(self.vertices_number, 1) for i in range(0, self.vertices_number): j = self.vertices[i] - while j != None: + while j is not None: u.insert_edge(i + 1, j.key) j = j.right for i in range(0, g.vertices_number): j = g.vertices[i] - while j != None: + while j is not None: u.insert_edge(i + 1, j.key) j = j.right - return u + return u + def single_edge(self): g = self.union(self.transpose()) single = graph(g.vertices_number, 1) s = [0] * g.vertices_number for u in range(0, g.vertices_number): v = g.vertices[u] - while v != None: + while v: if (u + 1) != v.key and s[v.key - 1] == 0: single.insert_edge(u + 1, v.key) s[v.key - 1] = 1 v = v.right v = g.vertices[u] - while v != None: + while v: if s[v.key - 1] == 1: s[v.key - 1] = 0 v = v.right s[u] = 2 return single + def insert_edge(self, u, v): a = node(v, self.vertices[u - 1]) self.vertices[u - 1] = a self.edges_number = self.edges_number + 1 + def print_graph(self): for i in range(0, self.vertices_number): j = self.vertices[i] - print '{}: '.format(i + 1), - while j != None: - print j.key, + print('{}: '.format(i + 1), ) + while j is not None: + print(j.key, ) j = j.right - print + print() + def square(self): grandchild = graph(self.vertices_number, 1) descendent = graph(self.vertices_number, 1) @@ -75,61 +83,62 @@ def square(self): # generate grandchild graph for i in range(0, self.vertices_number): j = self.vertices[i] - while j != None: + while j is not None: k = self.vertices[j.key - 1] - while k != None: + while k is not None: if s[k.key - 1] == 0: - grandchild.insert_edge(i + 1, k.key) + grandchild.insert_edge(i + 1, k.key) s[k.key - 1] = 1 k = k.right j = j.right j = grandchild.vertices[i] - while j != None: + while j is not None: s[j.key - 1] = 0 j = j.right # generate great grandchild graph for i in range(0, grandchild.vertices_number): j = grandchild.vertices[i] - while j != None: + while j is not None: k = self.vertices[j.key - 1] - while k != None: + while k is not None: if s[k.key - 1] == 0: - descendent.insert_edge(i + 1, k.key) + descendent.insert_edge(i + 1, k.key) k = k.right j = j.right j = descendent.vertices[i] - while j != None: + while j is not None: s[j.key - 1] = 0 j = j.right square = graph(self.vertices_number, 1) for i in range(0, self.vertices_number): j = self.vertices[i] - print j - while j != None: + print(j) + while j is not None: square.insert_edge(i + 1, j.key) s[j.key - 1] = 1 j = j.right j = grandchild.vertices[i] - while j != None: + while j is not None: if s[j.key - 1] == 0 and (i + 1) != j.key: square.insert_edge(i + 1, j.key) s[j.key - 1] = 1 j = j.right j = descendent.vertices[i] - while j != None: + while j is not None: if s[j.key - 1] == 0 and (i + 1) != j.key: square.insert_edge(i + 1, j.key) s[j.key - 1] = 1 j = j.right j = square.vertices[i] - while j != None: + while j is not None: s[j.key - 1] = 0 j = j.right -# self.print_graph() -# grandchild.print_graph() -# print -# descendent.print_graph() + # self.print(_graph()) + # grandchild.print(_graph()) + # print() + # descendent.print(_graph()) return square + def grandchild(self): pass diff --git a/square-matrix-multiply-Strassen.py b/square_matrix_multiply_Strassen.py similarity index 50% rename from square-matrix-multiply-Strassen.py rename to square_matrix_multiply_Strassen.py index f39dd74..a006392 100755 --- a/square-matrix-multiply-Strassen.py +++ b/square_matrix_multiply_Strassen.py @@ -1,40 +1,36 @@ #! /usr/bin/python2.7 -# AUTHOR: WangQiang -# CREATE DATE: 20140603 -# LAST UPDATE DATE: 20140604 -# EMAIL: cntqrxj@gmail.com - from numpy import * + def square_matrix_multiply(A, B): shape = A.shape length = shape[0] half = length / 2 - - C = zeros(shape, dtype = int64) + + C = zeros(shape, dtype=int64) if length == 1: C[0, 0] = A[0, 0] * B[0, 0] return C - - S1 = zeros((half, half), dtype = int64) - S2 = zeros((half, half), dtype = int64) - S3 = zeros((half, half), dtype = int64) - S4 = zeros((half, half), dtype = int64) - S5 = zeros((half, half), dtype = int64) - S6 = zeros((half, half), dtype = int64) - S7 = zeros((half, half), dtype = int64) - S8 = zeros((half, half), dtype = int64) - S9 = zeros((half, half), dtype = int64) - S10 = zeros((half, half), dtype = int64) - P1 = zeros((half, half), dtype = int64) - P2 = zeros((half, half), dtype = int64) - P3 = zeros((half, half), dtype = int64) - P4 = zeros((half, half), dtype = int64) - P5 = zeros((half, half), dtype = int64) - P6 = zeros((half, half), dtype = int64) - P7 = zeros((half, half), dtype = int64) + S1 = zeros((half, half), dtype=int64) + S2 = zeros((half, half), dtype=int64) + S3 = zeros((half, half), dtype=int64) + S4 = zeros((half, half), dtype=int64) + S5 = zeros((half, half), dtype=int64) + S6 = zeros((half, half), dtype=int64) + S7 = zeros((half, half), dtype=int64) + S8 = zeros((half, half), dtype=int64) + S9 = zeros((half, half), dtype=int64) + S10 = zeros((half, half), dtype=int64) + + P1 = zeros((half, half), dtype=int64) + P2 = zeros((half, half), dtype=int64) + P3 = zeros((half, half), dtype=int64) + P4 = zeros((half, half), dtype=int64) + P5 = zeros((half, half), dtype=int64) + P6 = zeros((half, half), dtype=int64) + P7 = zeros((half, half), dtype=int64) S1 = B[0:half, half:length] - B[half:length, half:length] S2 = A[0:half, 0:half] + A[0:half, half:length] @@ -54,21 +50,22 @@ def square_matrix_multiply(A, B): P5 = square_matrix_multiply(S5, S6) P6 = square_matrix_multiply(S7, S8) P7 = square_matrix_multiply(S9, S10) - + C[0:half, 0:half] = P5 + P4 - P2 + P6 C[0:half, half:length] = P1 + P2 C[half:length, 0:half] = P3 + P4 C[half:length, half:length] = P5 + P1 - P3 - P7 - - return C -#A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) -#B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) -#A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -#B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) -A = array([[1, 3], [7, 5]]) -B = array([[6, 8], [4, 2]]) -#A = array([[1, 2, 3], [4, 5, 6]]) -#B = array([[1, 2], [4, 5]]) -print square_matrix_multiply(A, B) -#print dot(A, B) + return C + + +# # A = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) +# # B = array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) +# # A = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# # B = array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) +# A = array([[1, 3], [7, 5]]) +# B = array([[6, 8], [4, 2]]) +# # A = array([[1, 2, 3], [4, 5, 6]]) +# # B = array([[1, 2], [4, 5]]) +# print(square_matrix_multiply(A, B)) +# # print( dot(A, B)) diff --git a/stack.py b/stack.py index 854f5bf..eb8e765 100644 --- a/stack.py +++ b/stack.py @@ -1,5 +1,7 @@ class FullException(BaseException): pass + + class EmptyException(BaseException): pass @@ -9,22 +11,26 @@ def __init__(self, size): list.__init__(self, [None] * size) self.top = -1 self.size = len(size) + def push(self, x): if self.full(): raise FullException("This stack is full") else: self.top = self.top + 1 self[self.top] = x + def pop(self): if self.empty(): raise EmptyException('This stack is empty') else: self.top = self.top - 1 return self[self.top + 1] + def empty(self): - return self.top == -1: + return self.top == -1 + def full(self): - return self.top == self.size - 1: + return self.top == self.size - 1 # def multipop(self, k): # l = [] diff --git a/synthetic_division.py b/synthetic_division.py index 260e3e5..0f4b483 100644 --- a/synthetic_division.py +++ b/synthetic_division.py @@ -1,5 +1,6 @@ #!/usr/bin/env ipython + def synthetic_division(A, n, x): q = [0] * (n - 1) q[n - 2] = A[n - 1] diff --git a/three_points_colinear.py b/three_points_colinear.py index f1ebe7a..00d9274 100644 --- a/three_points_colinear.py +++ b/three_points_colinear.py @@ -2,8 +2,9 @@ from heap import max_heap + class vector(object): - def __init__(self, p1, p2, p1_index = 0, p2_index = 0): + def __init__(self, p1, p2, p1_index=0, p2_index=0): # gurantee that the polar angle of this vector with respect to the origin point is in the range [0, pi) if p1[1] > p2[1]: self.x = p1[0] - p2[0] @@ -18,24 +19,31 @@ def __init__(self, p1, p2, p1_index = 0, p2_index = 0): self.p2 = p2 self.p1_index = p1_index self.p2_index = p2_index + def cross_product(self, v): return self.x * v.y - v.x * self.y + def __lt__(self, v): return self.cross_product(v) > 0 + def __gt__(self, v): return self.cross_product(v) < 0 + def __eq__(self, v): return self.cross_product(v) == 0 + def __le__(self, v): return self.cross_product(v) >= 0 + def __ge__(self, v): return self.cross_product(v) <= 0 + def three_points_colinear(points_list): '''An algorithm to determine whether any three points in a set of n points are colinear''' n = len(points_list) vectors_list = [] - for i in range(0, n): + for i in range(n): for j in range(i + 1, n): vectors_list.append(vector(points_list[i], points_list[j], i, j)) v0 = vector((1, 0), (0, 0)) @@ -61,9 +69,9 @@ def three_points_colinear(points_list): stack.append(v.p1_index) stack.append(v.p2_index) else: - print len(stack) - print stack - for i in range(0, len(stack)): + print(len(stack)) + print(stack) + for i in range(len(stack)): status[stack.pop()] = False stack.append(v.p1_index) stack.append(v.p2_index) diff --git a/tree.py b/tree.py index 07327b6..28313f4 100755 --- a/tree.py +++ b/tree.py @@ -2,30 +2,35 @@ import random + class Node(object): def __init__(self, key, p, left, right): self.key = key self.p = p self.left = left self.right = right + def inorder_tree_walk(self): - if self.left != None: - self.left.inorder_tree_walk() - print self.key, - if self.right != None: - self.right.inorder_tree_walk() + if self.left is not None: + self.left.inorder_tree_walk() + print(self.key, ) + if self.right is not None: + self.right.inorder_tree_walk() + def preorder_tree_walk(self): - print self.key, - if self.left != None: - self.left.preorder_tree_walk() - if self.right != None: - self.right.preorder_tree_walk() + print(self.key, ) + if self.left is not None: + self.left.preorder_tree_walk() + if self.right is not None: + self.right.preorder_tree_walk() + def postorder_tree_walk(self): - if self.left != None: - self.left.postorder_tree_walk() - if self.right != None: - self.right.postorder_tree_walk() - print self.key, + if self.left is not None: + self.left.postorder_tree_walk() + if self.right is not None: + self.right.postorder_tree_walk() + print(self.key, ) + def inorder_tree_walk_stack(self): s = [] s.append({"data": self, "status": 0}) @@ -33,91 +38,105 @@ def inorder_tree_walk_stack(self): record = s.pop() if record["status"] == 0: x = record["data"] - if x.right != None: + if x.right is not None: s.append({"data": x.right, "status": 0}) s.append({"data": x, "status": 1}) - if x.left != None: + if x.left is not None: s.append({"data": x.left, "status": 0}) else: - print record["data"].key, - print + print(record["data"].key, ) + print() + def iterative_tree_search(self, k): x = self - while x != None and x.key != k: + while x is not None and x.key != k: if x.key < k: x = x.right else: x = x.left return x + def minimum(self): x = self - while x.left != None: + while x.left is not None: x = x.left return x + def maximum(self): x = self - while x.right != None: + while x.right is not None: x = x.right return x + def successor(self): x = self - if x.right != None: + if x.right is not None: return x.right.minimum() else: - while x.p != None and x.p.right == x: + while x.p is not None and x.p.right == x: x = x.p return x.p + def predecessor(self): x = self - if x.left != None: + if x.left is not None: return x.left.maximum() else: - while x.p != None and x.p.left == x: + while x.p is not None and x.p.left == x: x = x.p return x.p + + class Tree(object): root = None + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(Node(i, None, None, None)) else: - print "Not invalid argument" + print("Not invalid argument") + def minimum(self): return self.root.minimum() + def __getitem__(self, key): return self.root.iterative_tree_search(key) + def insert(self, node): y = None x = self.root - while x != None: + while x is not None: y = x if node.key <= x.key: x = x.left else: x = x.right node.p = y - if y == None: + if y is None: self.root = node elif node.key <= y.key: y.left = node else: y.right = node + def iterative_tree_search(self, k): pass + def transplant(self, u, v): - if u.p == None: + if u.p is None: self.root = v elif u == u.p.left: u.p.left = v else: u.p.right = v - if v != None: + if v is not None: v.p = u.p + def delete(self, z): - if z.left == None: + if z.left is None: self.transplant(z, z.right) - elif z.right == None: + elif z.right is None: self.transplant(z, z.left) else: y = z.right.minimum() @@ -128,31 +147,33 @@ def delete(self, z): self.transplant(z, y) y.left = z.left y.left.p = y -#A = [random.randint(1, 100) for i in range(0, 15)] -#A = [29, 81, 53, 51, 28, 31, 57, 30, 22, 62, 6, 50, 7, 2, 24, 55, 54, 56, 98] -#print A -#T = Tree(A) -#T.delete(T.root.iterative_tree_search(57)) -#T.delete(T.root.iterative_tree_search(81)) -#T.root.postorder_tree_walk() -#print "maximum: %d" % (T.root.maximum().key) -#inorder_tree_walk_stack(T.root) -#T.root.inorder_tree_walk_stack() -#T.root.inorder_tree_walk() -print -#T.root.preorder_tree_walk() -print -#T.root.postorder_tree_walk() -#x = T.root.iterative_tree_search(50) -#if x == None: -# print "None" -#else: -# print x.key -#print T.root.mimimum().key + + +# A = [random.randint(1, 100) for i in range(0, 15)] +# A = [29, 81, 53, 51, 28, 31, 57, 30, 22, 62, 6, 50, 7, 2, 24, 55, 54, 56, 98] +# print( A) +# T = Tree(A) +# T.delete(T.root.iterative_tree_search(57)) +# T.delete(T.root.iterative_tree_search(81)) +# T.root.postorder_tree_walk() +# print( "maximum: %d" % (T.root.maximum().key)) +# inorder_tree_walk_stack(T.root) +# T.root.inorder_tree_walk_stack() +# T.root.inorder_tree_walk() +print() +# T.root.preorder_tree_walk() +print() +# T.root.postorder_tree_walk() +# x = T.root.iterative_tree_search(50) +# if x is None: +# print( "None") +# else: +# print( x.key) +# print( T.root.mimimum().key) # -#su = T.root.successor() -#if su: -# print su.key -#pr = T.root.predecessor() -#if pr: -# print "predecessor of root is %d " % (pr.key) +# su = T.root.successor() +# if su: +# print( su.key) +# pr = T.root.predecessor() +# if pr: +# print( "predecessor of root is %d " % (pr.key)) diff --git a/universal_sink.py b/universal_sink.py index 1aab58a..bc56b0c 100644 --- a/universal_sink.py +++ b/universal_sink.py @@ -1,22 +1,24 @@ #!/usr/bin/env ipython + def universal_sink(M): - ''' + """ An algorithm to determine whether a directed graph G contains a universal sink---a vertex with in-degree |V| - 1 and out-degree 0---in time O(V), given an adjacency matrix for G M: numpy matrix, the adjacency matrix for the graph rtype: vertex index if G contains a universal sink, otherwise, return None - ''' + """ return universal_sink_aux(M, 1) + def universal_sink_aux(M, i): - ''' + """ M: numpy matrix i: vertex index - ''' + """ size = M.shape[0] j = i while True: @@ -30,6 +32,6 @@ def universal_sink_aux(M, i): for j in range(1, size + 1): if M[j - 1][i - 1] == 0 and j != i: return None - return i + return i else: return universal_sink_aux(M, j) diff --git a/universal_sink_test.py b/universal_sink_test.py index de46f8a..5d7a11e 100644 --- a/universal_sink_test.py +++ b/universal_sink_test.py @@ -2,17 +2,30 @@ import unittest import numpy + class TestRbtree(unittest.TestCase): def test_universal_sink(self): - data = numpy.array([[0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 0, 0], [1, 0, 0, 0, 0, 1]]) - self.assertEquals(us.universal_sink(data), 1) - data = numpy.array([[0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0], [1, 1, 0, 0, 0, 1]]) - self.assertEquals(us.universal_sink(data), 2) - data = numpy.array([[0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0], [1, 1, 1, 0, 0, 1]]) - self.assertEquals(us.universal_sink(data), 3) - data = numpy.array([[0, 1, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 1, 0, 1]]) - self.assertEquals(us.universal_sink(data), 4) - data = numpy.array([[0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 0], [1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 1, 1]]) - self.assertEquals(us.universal_sink(data), 5) - data = numpy.array([[0, 1, 1, 0, 1, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0]]) - self.assertEquals(us.universal_sink(data), 6) + data = numpy.array( + [[0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 1, 0], [1, 0, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 0, 0, 1, 0, 0], + [1, 0, 0, 0, 0, 1]]) + self.assertEqual(us.universal_sink(data), 1) + data = numpy.array( + [[0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 1, 1], [1, 1, 0, 0, 0, 0], [1, 1, 0, 1, 0, 0], + [1, 1, 0, 0, 0, 1]]) + self.assertEqual(us.universal_sink(data), 2) + data = numpy.array( + [[0, 1, 1, 0, 0, 0], [0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [1, 1, 1, 1, 0, 0], + [1, 1, 1, 0, 0, 1]]) + self.assertEqual(us.universal_sink(data), 3) + data = numpy.array( + [[0, 1, 0, 1, 0, 0], [0, 0, 0, 1, 1, 0], [0, 0, 0, 1, 1, 1], [0, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], + [0, 0, 0, 1, 0, 1]]) + self.assertEqual(us.universal_sink(data), 4) + data = numpy.array( + [[0, 1, 1, 0, 1, 0], [0, 0, 1, 0, 1, 0], [0, 0, 0, 0, 1, 0], [1, 1, 1, 0, 1, 0], [0, 0, 0, 0, 0, 0], + [1, 1, 1, 0, 1, 1]]) + self.assertEqual(us.universal_sink(data), 5) + data = numpy.array( + [[0, 1, 1, 0, 1, 1], [0, 0, 1, 0, 1, 1], [0, 0, 0, 0, 1, 1], [1, 1, 1, 0, 1, 1], [0, 0, 0, 0, 0, 1], + [0, 0, 0, 0, 0, 0]]) + self.assertEqual(us.universal_sink(data), 6) diff --git a/vEB_tree.py b/vEB_tree.py index 08ab25c..fa12f96 100644 --- a/vEB_tree.py +++ b/vEB_tree.py @@ -2,6 +2,7 @@ import math + class vEB_node(object): def __init__(self, u): '''u must be exact power of 2, as required by CLRS; otherwise, the behavior is undefined''' @@ -12,14 +13,18 @@ def __init__(self, u): self.root = int(math.sqrt(u)) self.cluster = [0] * self.root self.summary = vEB_node(self.root) - for i in range(0, self.root): + for i in range(self.root): self.cluster[i] = vEB_node(self.root) + def high(self, x): - return x / self.root + return x // self.root + def low(self, x): return x % self.root + def index(self, x, y): return x * self.root + y + def member(self, x): if self.min == x or self.max == x: return True @@ -27,6 +32,7 @@ def member(self, x): return False else: return self.cluster[self.high(x)].member(self.low(x)) + def successor(self, x): if self.u == 2: if x == 0 and self.max == 1: @@ -47,17 +53,19 @@ def successor(self, x): else: offset = self.cluster[succ_cluster].min return self.index(succ_cluster, offset) + def empty_tree_insert(self, x): self.min = x self.max = x + def insert(self, x): - if self.min == None: + if self.min is None: self.empty_tree_insert(x) elif (x == self.min) or (x == self.max): return else: if x < self.min: - x,self.min = self.min,x + x, self.min = self.min, x if self.u > 2: if self.cluster[self.high(x)].min == None: self.summary.insert(self.high(x)) @@ -66,10 +74,11 @@ def insert(self, x): self.cluster[self.high(x)].insert(self.low(x)) if x > self.max: self.max = x + def delete(self, x): -# print "u = {}, x = {}".format(self.u, x) + # print( "u = {}, x = {}".format(self.u, x)) if self.min == self.max: - # print "min = {}, max = {}".format(self.min, self.max) + # print( "min = {}, max = {}".format(self.min, self.max)) if x == self.min: self.min = None self.max = None @@ -96,14 +105,15 @@ def delete(self, x): self.max = self.index(summary_max, self.cluster[summary_max].max) elif x == self.max: self.max = self.index(self.high(x), self.cluster[self.high(x)].max) + def print_veb(self): if self.u == 2: - print "u = {}, min = {}, max = {}".format(self.u, self.min, self.max) + print("u = {}, min = {}, max = {}".format(self.u, self.min, self.max)) else: - print "u = {}, min = {}, max = {}".format(self.u, self.min, self.max) - print "Summary: \t", + print("u = {}, min = {}, max = {}".format(self.u, self.min, self.max)) + print("Summary: \t", ) self.summary.print_veb() - print - for i in range(0, self.root): + print() + for i in range(self.root): self.cluster[i].print_veb() - print + print() diff --git a/vEB_tree_test.py b/vEB_tree_test.py index ec3dbc9..63bb4b8 100644 --- a/vEB_tree_test.py +++ b/vEB_tree_test.py @@ -3,6 +3,7 @@ import unittest from vEB_tree import vEB_node + class testVEB(unittest.TestCase): def test_vEB(self): v = vEB_node(2 ** 8) @@ -10,10 +11,10 @@ def test_vEB(self): for i in l: v.insert(i) for i in l: - self.assertEquals(v.member(i), True) - self.assertEquals(v.member(2), False) - self.assertEquals(v.member(3), False) + self.assertEqual(v.member(i), True) + self.assertEqual(v.member(2), False) + self.assertEqual(v.member(3), False) v.delete(1) - self.assertEquals(v.member(1), False) + self.assertEqual(v.member(1), False) v.delete(100) - self.assertEquals(v.member(100), False) + self.assertEqual(v.member(100), False) From fdf1080ad86511dddf3aecea673853334524296f Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 20 May 2018 15:53:09 +0800 Subject: [PATCH 03/49] Add some sort algorithms --- BubbleSort.c | 33 ------------------------- InsSort.c | 24 ------------------ MergeSort.c | 54 ----------------------------------------- b_tree.py | 3 ++- bh_tree_test.py | 2 +- binary_search.py | 19 +++++++++++++++ binary_search_test.py | 16 ++++++++++++ bubble_sort.py | 11 +++++++++ bubble_sort_test.py | 14 +++++++++++ insertion-sort-noninc.c | 16 ------------ insertion-sort-rec.c | 48 ------------------------------------ insertion-sort.c | 26 -------------------- insertion_sort.py | 43 +++++++++++++++++++++++++++----- insertion_sort_test.py | 20 +++++++++++++++ merge-sort.c | 47 ----------------------------------- merge_sort.py | 47 +++++++++++++++++++---------------- merge_sort_test.py | 14 +++++++++++ 17 files changed, 160 insertions(+), 277 deletions(-) delete mode 100644 BubbleSort.c delete mode 100644 InsSort.c delete mode 100644 MergeSort.c create mode 100644 binary_search.py create mode 100644 binary_search_test.py create mode 100644 bubble_sort.py create mode 100644 bubble_sort_test.py delete mode 100644 insertion-sort-noninc.c delete mode 100644 insertion-sort-rec.c delete mode 100644 insertion-sort.c create mode 100644 insertion_sort_test.py delete mode 100644 merge-sort.c create mode 100644 merge_sort_test.py diff --git a/BubbleSort.c b/BubbleSort.c deleted file mode 100644 index 7ab898a..0000000 --- a/BubbleSort.c +++ /dev/null @@ -1,33 +0,0 @@ -//BubbleSort(A) -//for i = 1 to A.length - 1 -// for j = A.length downto i + 1 -// if A[j] < A[j - 1] -// swap(A[j], A[j - 1]) - -#include - -void BubbleSort(int A[], int n) { - int i, j; - - for (i = 0; i < n - 1; i++) - for (j = n - 1; j > i; j--) - if (A[j] < A[j - 1]) { - int tmp = A[j]; - - A[j] = A[j - 1]; - A[j - 1] = tmp; - } -} - -int main() { - int a[1000]; - int i; - - for (i = 0; i < 1000; i++) - a[i] = 1000 - i; - BubbleSort(a, 1000); - for (i = 0; i < 1000; i++) - printf("%d\t", a[i]); - printf("\n"); - return 0; -} diff --git a/InsSort.c b/InsSort.c deleted file mode 100644 index fee77ba..0000000 --- a/InsSort.c +++ /dev/null @@ -1,24 +0,0 @@ -#include - -void InsSort(int a[], int n) -{ - int i, j; - int key; - for (i = 1; i < n; i++) - { - key = a[i]; - for (j = i - 1; j >= 0 && a[j] > key; j--) - { - a[j + 1] = a[j]; - a[j] = key; - } - } -} - -void main() -{ - int a[6] = { 31, 41, 59, 26, 61, 58 }; - - InsSort(a, 6); - printf("%d,%d,%d,%d,%d,%d", a[0], a[1], a[2], a[3], a[4], a[5]); -} \ No newline at end of file diff --git a/MergeSort.c b/MergeSort.c deleted file mode 100644 index 03ea825..0000000 --- a/MergeSort.c +++ /dev/null @@ -1,54 +0,0 @@ -#include -#include - -//A version of merge procedure that stops once either array L or R has had //all its elements copied back to A -void Combine(int A[], int first, int inter, int end) { - int len1 = inter - first + 1; - int len2 = end - inter; - int i; - int j; - int k; - int *L; - int *R; - - L = (int *) calloc(len1, sizeof(int)); - R = (int *) calloc(len2, sizeof(int)); - for (i = 0; i < len1; i++) - L[i] = A[first + i]; - for (j = 0; j < len2; j++) - R[j] = A[inter + j + 1]; - - i = 0; - j = 0; - k = first; - while (i < len1 && j < len2) - if (L[i] <= R[j]) - A[k++] = L[i++]; - else - A[k++] = R[j++]; - if (i == len1) - while (j < len2) - A[k++] = R[j++]; - else if (j = len2) - while (i < len1) - A[k++] = L[i++]; - free(L); - free(R); -} - -void MergeSort(int A[], int first, int end) { - int middle = (first + end) / 2; - - if (end == first) - return; - MergeSort(A, first, middle); - MergeSort(A, middle + 1, end); - Combine(A, first, middle, end); - return; -} - -void main() { - int a[8] = {1,3,4,5,2,6,0,10}; - MergeSort(a, 0, 7); - printf("%d, %d, %d, %d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); -} diff --git a/b_tree.py b/b_tree.py index 7909ed8..6056654 100644 --- a/b_tree.py +++ b/b_tree.py @@ -1,5 +1,6 @@ #!/usr/bin/env ipython + class b_tree_node(object): def __init__(self, t, leaf, n): self.leaf = leaf @@ -50,7 +51,7 @@ def search(self, k): while i <= self.n and k > self.key[i - 1]: i = i + 1 if i <= self.n and k == self.key[i - 1]: - return (self, i) + return self, i elif self.leaf: return None else: diff --git a/bh_tree_test.py b/bh_tree_test.py index a7c44d4..040bf64 100755 --- a/bh_tree_test.py +++ b/bh_tree_test.py @@ -3,7 +3,7 @@ from bh_tree import bh_tree, bh_node -class TestRbtree(unittest.TestCase): +class TestRbTree(unittest.TestCase): def test_insert_one(self): T = bh_tree([41]) self.wrap(T, 41, 1) diff --git a/binary_search.py b/binary_search.py new file mode 100644 index 0000000..f9d38b3 --- /dev/null +++ b/binary_search.py @@ -0,0 +1,19 @@ +def binary_search(target, array): + """ + find target in sorted array. + If found, return the index, otherwise return -1. + :param target: + :param array: list + :return: + """ + low = 0 + high = len(array) - 1 + while low <= high: + mid = (low + high) // 2 + if target < array[mid]: + high = mid - 1 + elif target > array[mid]: + low = mid + 1 + else: + return mid + return -1 diff --git a/binary_search_test.py b/binary_search_test.py new file mode 100644 index 0000000..734a9f3 --- /dev/null +++ b/binary_search_test.py @@ -0,0 +1,16 @@ +#!/usr/bin/env ipython +import unittest +import random +from binary_search import binary_search + + +class TestBinarySearch(unittest.TestCase): + def test_binary_search(self): + for _ in range(100): + array = sorted([random.randint(1, 10000) for _ in range(0, 100)]) + target = random.randint(1, 10000) + index = binary_search(target, array) + if index == -1: + self.assertNotIn(target, array) + else: + self.assertEqual(target, array[index]) diff --git a/bubble_sort.py b/bubble_sort.py new file mode 100644 index 0000000..bb0686f --- /dev/null +++ b/bubble_sort.py @@ -0,0 +1,11 @@ +def bubble_sort(array): + """ + O(n ^ 2) inplace sort + :param array: + :return: + """ + n = len(array) + for i in range(n): + for j in range(n - 1, i, -1): + if array[j] < array[j - 1]: + array[j], array[j - 1] = array[j - 1], array[j] diff --git a/bubble_sort_test.py b/bubble_sort_test.py new file mode 100644 index 0000000..15b5f61 --- /dev/null +++ b/bubble_sort_test.py @@ -0,0 +1,14 @@ +#!/usr/bin/env ipython +import unittest +import random +from bubble_sort import bubble_sort + + +class TestBubbleSort(unittest.TestCase): + def test_bubble_sort(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + bubble_sort(array) + self.assertEqual(array, sorted(array_copy)) + diff --git a/insertion-sort-noninc.c b/insertion-sort-noninc.c deleted file mode 100644 index 5056843..0000000 --- a/insertion-sort-noninc.c +++ /dev/null @@ -1,16 +0,0 @@ -#include -//Sort into nonincreasing order -void insertionsort(int s[], int length) { - int j, i; - int key; - - for (j = 1; j < length; j++) { - key = s[j]; - for (i = j - 1; i >= 0 && s[i] < key; i--) - s[i+1] = s[i]; - s[i+1] = key; - for (i = 0; i < length; i++) - printf("%d ", s[i]); - printf("\n"); - } -} diff --git a/insertion-sort-rec.c b/insertion-sort-rec.c deleted file mode 100644 index cd91cde..0000000 --- a/insertion-sort-rec.c +++ /dev/null @@ -1,48 +0,0 @@ -#include -// recursive version of insertion sort - -void swap(int *a, int *b) -{ - int tmp = *a; - - *a = *b; - *b = tmp; -} - -void Insert(int A[], int n) -{ - int i; - - for (i = n - 1; i >= 0; i--) - if (A[i] > A[i + 1]) - swap(A + i, A + i + 1); - else - return; -} - -void InsSort(int A[], int n) -{ - if (n > 1) - { - InsSort(A, n - 1); - Insert(A, n); - } - else if (n == 1) - { - if (A[0] > A[1]) - swap(A, A + 1); - return; - } - else if (n == 0) - return; -} - -int main() -{ - int a[8] = { 8, 8, 3, 65, 500, 3, -1, 3 }; - - InsSort(a, 7); - printf("%d,%d,%d,%d,%d,%d,%d, %d\n", a[0], a[1], a[2], a[3], a[4], a[5], - a[6], a[7]); - return 0; -} diff --git a/insertion-sort.c b/insertion-sort.c deleted file mode 100644 index 870d9ff..0000000 --- a/insertion-sort.c +++ /dev/null @@ -1,26 +0,0 @@ -#include -//INSERTION-SORT(A) - //for j = 2 to A.length - //key = A[j] - ////Insert A[j] into the sorted sequence A[1..j - 1]. - //i = j - 1 - //while i > 0 and A[i] > key - //A[i + 1] = A[i] - //i = i - 1 - //A[i + 1] = key - -//Sort into nondecreasing order -void insertionsort(int s[], int length) { - int j, i; - int key; - - for (j = 1; j < length; j++) { - key = s[j]; - for (i = j - 1; i >= 0 && s[i] > key; i--) - s[i+1] = s[i]; - s[i+1] = key; -// for (i = 0; i < length; i++) -// printf("%d ", s[i]); -// printf("\n"); - } -} diff --git a/insertion_sort.py b/insertion_sort.py index 75b9716..2aed92b 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -1,9 +1,40 @@ -def insertion_sort(A): - for j in range(1, len(A)): - key = A[j] +def insertion_sort(array): + """ + inplace sort O(n ^ 2) sort + :param array: + :return: + """ + for j in range(1, len(array)): + key = array[j] i = j - 1 - while i >= 0 and key < A[i]: - A[i + 1] = A[i] + while i >= 0 and key < array[i]: + array[i + 1] = array[i] i = i - 1 - A[i + 1] = key + array[i + 1] = key + +def insertion_sort_recursive(array): + """ + recursive version of insertion sort + :param array: + :return: + """ + _insertion_sort_recursive_aux(array, len(array)) + + +def _insertion_sort_recursive_aux(array, length): + if length > 1: + _insertion_sort_recursive_aux(array, length - 1) + _insert(array, length) + elif length == 1: + if array[1] > array[0]: + array[1], array[0] = array[0], array[1] + + +def _insert(array, length): + key = array[length - 1] + i = length - 2 + while i >= 0 and key < array[i]: + array[i + 1] = array[i] + i = i - 1 + array[i + 1] = key diff --git a/insertion_sort_test.py b/insertion_sort_test.py new file mode 100644 index 0000000..39ecdf0 --- /dev/null +++ b/insertion_sort_test.py @@ -0,0 +1,20 @@ +#!/usr/bin/env ipython +import unittest +import random +from insertion_sort import insertion_sort, insertion_sort_recursive + + +class TestInsertionSort(unittest.TestCase): + def test_insertion_sort(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + insertion_sort(array) + self.assertEqual(array, sorted(array_copy)) + + def test_insertion_sort_recursive(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + insertion_sort_recursive(array) + self.assertEqual(array, sorted(array_copy)) diff --git a/merge-sort.c b/merge-sort.c deleted file mode 100644 index b46723d..0000000 --- a/merge-sort.c +++ /dev/null @@ -1,47 +0,0 @@ -// implemention of algorithm merge sort - -#include -#include -// A version of merge procedure that uses sentinels -void merge(int a[], int begin, int middle, int end) { - int n1 = middle - begin + 1; - int n2 = end - middle; -// What's this? - int l[n1 + 1], r[n2 + 1]; - int i, j, k; - - for (i=0; i < n1; i++) - l[i] = a[begin + i]; - for (j=0; j < n2; j++) - r[j] = a[middle + j + 1]; - l[n1] = INT_MAX; - r[n2] = INT_MAX; - i = 0, j = 0; - for (k = begin; k <= end; k++) { - if (l[i] <= r[j]) { - a[k] = l[i]; - i++; - } - else { - a[k] = r[j]; - j++; - } - } -} - -void merge_sort(int a[], int start, int end) { - if (start < end) { - int middle = (start + end) / 2; - merge_sort(a, start, middle); - merge_sort(a, middle+1, end); - merge(a, start, middle, end); - } -} - -int main() { - int a[8] = {1,3,4,5,2,6,0,10}; - - merge_sort(a, 0, 7); - printf("%d, %d, %d, %d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7]); - return 0; -} diff --git a/merge_sort.py b/merge_sort.py index 5435558..9f3ffa1 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -1,26 +1,31 @@ -def merge(A, p, q, r): - n1 = q - p + 1 - n2 = r - q - L = [0] * (n1 + 1) - R = [0] * (n2 + 1) - for i in range(0, n1): - L[i] = A[p + i] - for j in range(0, n2): - R[j] = A[q + j + 1] - L[n1] = float("Inf") - R[n2] = float("Inf") +def merge_sort(array): + """ + inplace O(nlgn) sort + :param array: + :return: + """ + _merge_sort(array, 0, len(array) - 1) + + +def _merge_sort(array, left, right): + if left < right: + mid = (left + right) // 2 + _merge_sort(array, left, mid) + _merge_sort(array, mid + 1, right) + _merge(array, left, mid, right) + + +def _merge(array, left, mid, right): + left_part = array[left: mid + 1] + left_part.append(float("Inf")) + right_part = array[mid + 1: right + 1] + right_part.append(float("Inf")) i = 0 j = 0 - for k in range(p, r + 1): - if L[i] <= R[j]: - A[k] = L[i] + for k in range(left, right + 1): + if left_part[i] <= right_part[j]: + array[k] = left_part[i] i = i + 1 else: - A[k] = R[j] + array[k] = right_part[j] j = j + 1 -def merge_sort(A, p, r): - if p < r: - q = (p + r) / 2 - merge_sort(A, p, q) - merge_sort(A, q + 1, r) - merge(A, p, q, r) diff --git a/merge_sort_test.py b/merge_sort_test.py new file mode 100644 index 0000000..6af46ed --- /dev/null +++ b/merge_sort_test.py @@ -0,0 +1,14 @@ +#!/usr/bin/env ipython +import unittest +import random +from merge_sort import merge_sort + + +class TestMergeSort(unittest.TestCase): + def test_merge_sort(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + merge_sort(array) + self.assertEqual(array, sorted(array_copy)) + From eb22dd564dcbd7e13522790c9de055644eb68d85 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 20 May 2018 19:42:55 +0800 Subject: [PATCH 04/49] Some insertion sort and merge sort variations --- BinSearch.c | 34 ---------------------- bubble_sort.py | 2 +- insertion_sort.py | 30 +++++++++++++------- merge_sort.py | 70 ++++++++++++++++++++++++++++++++++++---------- merge_sort_test.py | 12 ++++++-- two_sum.py | 20 +++++++++++++ two_sum_test.py | 17 +++++++++++ 7 files changed, 123 insertions(+), 62 deletions(-) delete mode 100644 BinSearch.c create mode 100644 two_sum.py create mode 100644 two_sum_test.py diff --git a/BinSearch.c b/BinSearch.c deleted file mode 100644 index e096370..0000000 --- a/BinSearch.c +++ /dev/null @@ -1,34 +0,0 @@ -//BinSearch(A, first, end, x) -// while length >= 0 -// inter = (first + end) / 2 -// if x == A[inter] -// return inter + 1 -// else if x < A[inter] -// end = inter - 1 -// else -// first = inter + 1 -// length = end - first -// return -1 - -int BinSearch(int A[], int first, int end, int x) { - int length = end - first; - int inter; - - while (length >= 0) { - inter = (first + end) / 2; - if (x == A[inter] ) - return inter + 1; - else if (x < A[inter]) - end = inter - 1; - else - first = inter + 1; - length = end - first; - } - return -1; -} - -void main() { - int A[10] = {0,1,2,3,4,5,6,7,8,9}; - - printf("%d\n", BinSearch(A, 0, 9, 9)); -} diff --git a/bubble_sort.py b/bubble_sort.py index bb0686f..f9d6ae6 100644 --- a/bubble_sort.py +++ b/bubble_sort.py @@ -1,7 +1,7 @@ def bubble_sort(array): """ O(n ^ 2) inplace sort - :param array: + :param array: list :return: """ n = len(array) diff --git a/insertion_sort.py b/insertion_sort.py index 2aed92b..9e8dfe7 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -1,16 +1,14 @@ +from binary_search import binary_search + + def insertion_sort(array): """ inplace sort O(n ^ 2) sort :param array: :return: """ - for j in range(1, len(array)): - key = array[j] - i = j - 1 - while i >= 0 and key < array[i]: - array[i + 1] = array[i] - i = i - 1 - array[i + 1] = key + for j in range(2, len(array) + 1): + _insert(array, j) def insertion_sort_recursive(array): @@ -22,16 +20,28 @@ def insertion_sort_recursive(array): _insertion_sort_recursive_aux(array, len(array)) +def insertion_sort_with_binary_search(array): + """ + + :param array: + :return: + """ + + def _insertion_sort_recursive_aux(array, length): if length > 1: _insertion_sort_recursive_aux(array, length - 1) _insert(array, length) - elif length == 1: - if array[1] > array[0]: - array[1], array[0] = array[0], array[1] def _insert(array, length): + """ + insert array[length] into already sorted subarray array[1: length - 1], + making array[1: length] a sorted array. + :param array: + :param length: length > 0 + :return: + """ key = array[length - 1] i = length - 2 while i >= 0 and key < array[i]: diff --git a/merge_sort.py b/merge_sort.py index 9f3ffa1..0522dd0 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -1,21 +1,12 @@ -def merge_sort(array): +def merge_with_sentinel(array, left, mid, right): """ - inplace O(nlgn) sort + merge procedure with sentinels :param array: + :param left: + :param mid: + :param right: :return: """ - _merge_sort(array, 0, len(array) - 1) - - -def _merge_sort(array, left, right): - if left < right: - mid = (left + right) // 2 - _merge_sort(array, left, mid) - _merge_sort(array, mid + 1, right) - _merge(array, left, mid, right) - - -def _merge(array, left, mid, right): left_part = array[left: mid + 1] left_part.append(float("Inf")) right_part = array[mid + 1: right + 1] @@ -29,3 +20,54 @@ def _merge(array, left, mid, right): else: array[k] = right_part[j] j = j + 1 + + +def merge_without_sentinel(array, left, mid, right): + """ + merge procedure without sentinels + A merge procedure without sentinels that stops once either array `left_part` or `right_part` has had all its elements + copied back to `array` and then copying the remainder of the other array back into `array` + :param array: + :param left: + :param mid: + :param right: + :return: + """ + left_part = array[left: mid + 1] + right_part = array[mid + 1: right + 1] + i = 0 + j = 0 + k = left + left_length = mid - left + 1 + right_length = right - mid + while i < left_length and j < right_length: + if left_part[i] <= right_part[j]: + array[k] = left_part[i] + k = k + 1 + i = i + 1 + else: + array[k] = right_part[j] + k = k + 1 + j = j + 1 + if i < left_length: + array[k: right + 1] = left_part[i: left_length] + else: + array[k: right + 1] = right_part[j: right_length] + + +def _merge_sort(array, left, right, merge_method): + if left < right: + mid = (left + right) // 2 + _merge_sort(array, left, mid, merge_method) + _merge_sort(array, mid + 1, right, merge_method) + merge_method(array, left, mid, right) + + +def merge_sort(array, merge_method=merge_with_sentinel): + """ + inplace O(nlgn) sort + :param array: + :param merge_method: + :return: + """ + _merge_sort(array, 0, len(array) - 1, merge_method) diff --git a/merge_sort_test.py b/merge_sort_test.py index 6af46ed..9f110bc 100644 --- a/merge_sort_test.py +++ b/merge_sort_test.py @@ -1,14 +1,20 @@ #!/usr/bin/env ipython import unittest import random -from merge_sort import merge_sort +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel class TestMergeSort(unittest.TestCase): - def test_merge_sort(self): + def test_merge_sort_with_sentinel(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - merge_sort(array) + merge_sort(array, merge_with_sentinel) self.assertEqual(array, sorted(array_copy)) + def test_merge_sort_without_sentinel(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + merge_sort(array, merge_without_sentinel) + self.assertEqual(array, sorted(array_copy)) diff --git a/two_sum.py b/two_sum.py new file mode 100644 index 0000000..78c2b6c --- /dev/null +++ b/two_sum.py @@ -0,0 +1,20 @@ +def two_sum(x, array): + """ + an algorithm that, given a set S of n integers and another integer x, + determines whether or not there exist two elements in S whose sum is exactly x. + :param x: + :param array: + :return: + """ + sorted_array = sorted(array) + i = 0 + j = len(array) - 1 + while i < j: + sum = sorted_array[i] + sorted_array[j] + if sum == x: + return True + elif sum < x: + i = i + 1 + else: + j = j - 1 + return False diff --git a/two_sum_test.py b/two_sum_test.py new file mode 100644 index 0000000..1ffcad1 --- /dev/null +++ b/two_sum_test.py @@ -0,0 +1,17 @@ +import unittest +import random +from two_sum import two_sum + + +class TestInsertionSort(unittest.TestCase): + def test_two_sum(self): + for _ in range(1000): + array = [random.randint(1, 20) for _ in range(10)] + x = random.randint(1, 100) + n = len(array) + result = False + for i in range(n): + for j in range(i + 1, n): + if array[i] + array[j] == x: + result = True + self.assertEqual(two_sum(x, array), result) From ad3ee4667f77ec34809307ae91938d2bbdae0da5 Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 24 May 2018 23:35:40 +0800 Subject: [PATCH 05/49] add bisect_left --- binary_search.py | 28 ++++++++++++++++++++++++++++ binary_search_test.py | 12 ++++++++++-- binsearch.c | 25 ------------------------- 3 files changed, 38 insertions(+), 27 deletions(-) delete mode 100644 binsearch.c diff --git a/binary_search.py b/binary_search.py index f9d38b3..b58e52f 100644 --- a/binary_search.py +++ b/binary_search.py @@ -17,3 +17,31 @@ def binary_search(target, array): else: return mid return -1 + + +def bisect_left(array, x, low=0, high=None): + """ + Locate the insertion point for x in a to maintain sorted order. + The parameters lo and hi may be used to specify a subset of the list which should be considered; + by default the entire list is used. If x is already present in a, + the insertion point will be before (to the left of) any existing entries. + The return value is suitable for use as the first parameter to list.insert() assuming that a is already sorted. + + The returned insertion point i partitions the array a into two halves so that all(val < x for val in a[lo:i]) + for the left side and all(val >= x for val in a[i:hi]) for the right side. + :param array: sorted list + :param x: + :param low: + :param high: + :return: + """ + if high is None: + high = len(array) + assert low <= high + while low < high: + mid = (low + high) // 2 + if array[mid] < x: + low = mid + 1 + else: + high = mid + return low diff --git a/binary_search_test.py b/binary_search_test.py index 734a9f3..46bd2af 100644 --- a/binary_search_test.py +++ b/binary_search_test.py @@ -1,16 +1,24 @@ #!/usr/bin/env ipython import unittest import random -from binary_search import binary_search +from binary_search import binary_search, bisect_left class TestBinarySearch(unittest.TestCase): def test_binary_search(self): for _ in range(100): - array = sorted([random.randint(1, 10000) for _ in range(0, 100)]) + array = sorted([random.randint(1, 10000) for _ in range(100)]) target = random.randint(1, 10000) index = binary_search(target, array) if index == -1: self.assertNotIn(target, array) else: self.assertEqual(target, array[index]) + + def test_bisect_left(self): + for length in range(10): + array = sorted([random.randint(1, 10) for _ in range(length)]) + target = random.randint(0, 15) + index = bisect_left(array, target) + self.assertTrue(all(val < target for val in array[:index])) + self.assertTrue(all(val >= target for val in array[index:])) diff --git a/binsearch.c b/binsearch.c deleted file mode 100644 index 8f9c9f8..0000000 --- a/binsearch.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -/* binsearch: find x in v[0] <= v[1] <= ... <= v[n-1] */ -int binsearch(int x, int v[], int n) { - int low, high, mid; - - low = 0; - high = n - 1; - while (low <= high) { - mid = (high + low)/2; - if (x < v[mid]) - high = mid - 1; - else if (x > v[mid]) - low = mid + 1; - else /* found match */ - return mid; - } - return -1; /* no match */ -} - -void main() { - int A[10] = {0,1,2,3,4,5,6,7,8,9}; - - printf("%d\n", binsearch(9, A, 10)); -} - From 147cfc3f870fc5012092f180a9ee669b3e1fae74 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 9 Jun 2018 18:47:21 +0800 Subject: [PATCH 06/49] implement bisect right algorithm --- binary_search.py | 35 +++++++++++++++++++++--- binary_search_test.py | 10 ++++++- insertion_sort.py | 60 ++++++++++++++++++++++++------------------ insertion_sort_test.py | 19 ++++++++++--- 4 files changed, 90 insertions(+), 34 deletions(-) diff --git a/binary_search.py b/binary_search.py index b58e52f..f61f7b2 100644 --- a/binary_search.py +++ b/binary_search.py @@ -22,13 +22,12 @@ def binary_search(target, array): def bisect_left(array, x, low=0, high=None): """ Locate the insertion point for x in a to maintain sorted order. - The parameters lo and hi may be used to specify a subset of the list which should be considered; - by default the entire list is used. If x is already present in a, + If x is already present in a, the insertion point will be before (to the left of) any existing entries. The return value is suitable for use as the first parameter to list.insert() assuming that a is already sorted. + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. - The returned insertion point i partitions the array a into two halves so that all(val < x for val in a[lo:i]) - for the left side and all(val >= x for val in a[i:hi]) for the right side. :param array: sorted list :param x: :param low: @@ -45,3 +44,31 @@ def bisect_left(array, x, low=0, high=None): else: high = mid return low + + +def bisect_right(array, x, low=0, high=None): + """ + Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e <= x, and all e in + a[i:] have e > x. So if x already appears in the list, a.insert(x) will + insert just after the rightmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + :param array: + :param x: + :param low: + :param high: + :return: + """ + if high is None: + high = len(array) + assert low <= high + while low < high: + mid = (low + high) // 2 + if array[mid] <= x: + low = mid + 1 + else: + high = mid + return low diff --git a/binary_search_test.py b/binary_search_test.py index 46bd2af..62485cb 100644 --- a/binary_search_test.py +++ b/binary_search_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env ipython import unittest import random -from binary_search import binary_search, bisect_left +from binary_search import binary_search, bisect_left, bisect_right class TestBinarySearch(unittest.TestCase): @@ -22,3 +22,11 @@ def test_bisect_left(self): index = bisect_left(array, target) self.assertTrue(all(val < target for val in array[:index])) self.assertTrue(all(val >= target for val in array[index:])) + + def test_bisect_right(self): + for length in range(10): + array = sorted([random.randint(1, 10) for _ in range(length)]) + target = random.randint(0, 15) + index = bisect_right(array, target) + self.assertTrue(all(val <= target for val in array[:index])) + self.assertTrue(all(val > target for val in array[index:])) diff --git a/insertion_sort.py b/insertion_sort.py index 9e8dfe7..31718d9 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -1,50 +1,58 @@ -from binary_search import binary_search +from binary_search import bisect_right -def insertion_sort(array): +def insert_with_linear_search(array, length): """ - inplace sort O(n ^ 2) sort + Use linear search to find a position in already sorted array[1...length-1] to insert array[length] into, + making array[1: length] a sorted array. :param array: + :param length: length > 0 :return: """ - for j in range(2, len(array) + 1): - _insert(array, j) + key = array[length - 1] + i = length - 2 + while i >= 0 and key < array[i]: + array[i + 1] = array[i] + i = i - 1 + array[i + 1] = key -def insertion_sort_recursive(array): +def insert_with_binary_search(array, length): """ - recursive version of insertion sort + Use binary search to find a position in already sorted array[1...length-1] to insert array[length] into, + making array[1: length] a sorted array. :param array: + :param length: length > 0 :return: """ - _insertion_sort_recursive_aux(array, len(array)) + x = array[length - 1] + index = bisect_right(array, x, 0, length - 1) + array[index + 1: length] = array[index: length - 1] + array[index] = x -def insertion_sort_with_binary_search(array): - """ +def _insertion_sort_recursive_aux(array, length, insert_method): + if length > 1: + _insertion_sort_recursive_aux(array, length - 1, insert_method) + insert_method(array, length) + +def insertion_sort(array, insert_method=insert_with_linear_search): + """ + inplace sort O(n ^ 2) sort :param array: + :param insert_method: :return: """ + for j in range(2, len(array) + 1): + insert_method(array, j) -def _insertion_sort_recursive_aux(array, length): - if length > 1: - _insertion_sort_recursive_aux(array, length - 1) - _insert(array, length) - - -def _insert(array, length): +def insertion_sort_recursive(array, insert_method=insert_with_linear_search): """ - insert array[length] into already sorted subarray array[1: length - 1], - making array[1: length] a sorted array. + recursive version of insertion sort :param array: - :param length: length > 0 + :param insert_method: :return: """ - key = array[length - 1] - i = length - 2 - while i >= 0 and key < array[i]: - array[i + 1] = array[i] - i = i - 1 - array[i + 1] = key + _insertion_sort_recursive_aux(array, len(array), insert_method) diff --git a/insertion_sort_test.py b/insertion_sort_test.py index 39ecdf0..b2a0952 100644 --- a/insertion_sort_test.py +++ b/insertion_sort_test.py @@ -1,15 +1,23 @@ #!/usr/bin/env ipython import unittest import random -from insertion_sort import insertion_sort, insertion_sort_recursive +from insertion_sort import insertion_sort, insertion_sort_recursive, insert_with_linear_search, \ + insert_with_binary_search class TestInsertionSort(unittest.TestCase): - def test_insertion_sort(self): + def test_insertion_sort_with_linear_search(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - insertion_sort(array) + insertion_sort(array, insert_with_linear_search) + self.assertEqual(array, sorted(array_copy)) + + def test_insertion_sort_with_binary_search(self): + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + insertion_sort(array, insert_with_binary_search) self.assertEqual(array, sorted(array_copy)) def test_insertion_sort_recursive(self): @@ -18,3 +26,8 @@ def test_insertion_sort_recursive(self): array_copy = array[:] insertion_sort_recursive(array) self.assertEqual(array, sorted(array_copy)) + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(0, 100)] + array_copy = array[:] + insertion_sort_recursive(array, insert_with_binary_search) + self.assertEqual(array, sorted(array_copy)) From 0dcf0aa7102103ffae38ca246de6887cdf2f85ac Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 9 Jun 2018 22:58:08 +0800 Subject: [PATCH 07/49] Implement merge_ins_sort to use insertion sort within merge sort when subproblems become sufficiently small --- insertion_sort.py | 38 ++++++++++++++++++++++---------------- insertion_sort_test.py | 6 +++--- merge_sort.py | 33 +++++++++++++++++++++++++++++++++ merge_sort_test.py | 9 ++++++++- 4 files changed, 66 insertions(+), 20 deletions(-) diff --git a/insertion_sort.py b/insertion_sort.py index 31718d9..c717d5e 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -1,50 +1,56 @@ from binary_search import bisect_right -def insert_with_linear_search(array, length): +def insert_with_linear_search(array, right_index): """ - Use linear search to find a position in already sorted array[1...length-1] to insert array[length] into, - making array[1: length] a sorted array. + Use linear search to find a position in already sorted array[0...right_index-1] to insert array[right_index] into, + making array[0...right_index] a sorted array. :param array: - :param length: length > 0 + :param right_index: ridht_index > 0 :return: """ - key = array[length - 1] - i = length - 2 + key = array[right_index] + i = right_index - 1 while i >= 0 and key < array[i]: array[i + 1] = array[i] i = i - 1 array[i + 1] = key -def insert_with_binary_search(array, length): +def insert_with_binary_search(array, right_index): """ - Use binary search to find a position in already sorted array[1...length-1] to insert array[length] into, - making array[1: length] a sorted array. + Use binary search to find a position in already sorted array[0...right_index-1] to insert array[right_index] into, + making array[0...right_index] a sorted array. :param array: - :param length: length > 0 + :param right_index: right_index > 0 :return: """ - x = array[length - 1] - index = bisect_right(array, x, 0, length - 1) - array[index + 1: length] = array[index: length - 1] + x = array[right_index] + index = bisect_right(array, x, 0, right_index) + array[index + 1: right_index + 1] = array[index: right_index] array[index] = x def _insertion_sort_recursive_aux(array, length, insert_method): if length > 1: _insertion_sort_recursive_aux(array, length - 1, insert_method) - insert_method(array, length) + insert_method(array, length - 1) -def insertion_sort(array, insert_method=insert_with_linear_search): +def insertion_sort(array, left=0, right=None, insert_method=insert_with_linear_search): """ inplace sort O(n ^ 2) sort :param array: :param insert_method: + :param left: + :param right: :return: """ - for j in range(2, len(array) + 1): + if right is None: + right = len(array) + else: + right += 1 + for j in range(left, right): insert_method(array, j) diff --git a/insertion_sort_test.py b/insertion_sort_test.py index b2a0952..91e3db6 100644 --- a/insertion_sort_test.py +++ b/insertion_sort_test.py @@ -10,14 +10,14 @@ def test_insertion_sort_with_linear_search(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - insertion_sort(array, insert_with_linear_search) + insertion_sort(array, insert_method=insert_with_linear_search) self.assertEqual(array, sorted(array_copy)) def test_insertion_sort_with_binary_search(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - insertion_sort(array, insert_with_binary_search) + insertion_sort(array, insert_method=insert_with_binary_search) self.assertEqual(array, sorted(array_copy)) def test_insertion_sort_recursive(self): @@ -29,5 +29,5 @@ def test_insertion_sort_recursive(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - insertion_sort_recursive(array, insert_with_binary_search) + insertion_sort_recursive(array, insert_method=insert_with_binary_search) self.assertEqual(array, sorted(array_copy)) diff --git a/merge_sort.py b/merge_sort.py index 0522dd0..4108076 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -1,6 +1,12 @@ +from insertion_sort import insertion_sort +import math + + def merge_with_sentinel(array, left, mid, right): """ merge procedure with sentinels + + merge array[left...mid] and array[mid + 1...right] :param array: :param left: :param mid: @@ -71,3 +77,30 @@ def merge_sort(array, merge_method=merge_with_sentinel): :return: """ _merge_sort(array, 0, len(array) - 1, merge_method) + + +def merge_ins_sort(array, partition=2): + """ + Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make + it faster in practice for small problem sizes on many machines. + Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when + subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are + sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined. + :param array: + :param partition: number of sublists + :return: + """ + assert partition > 0 + n = len(array) + sublist_length = math.ceil(n / partition) + sublist_number = partition + for i in range(sublist_number): + left = sublist_length * i + right = min(sublist_length * (i + 1) - 1, n - 1) + insertion_sort(array, left, right) + while sublist_number > 1: + for i in range(0, sublist_number - 1, 2): + merge_with_sentinel(array, sublist_length * i, sublist_length * (i + 1) - 1, + min(sublist_length * (i + 2) - 1, n - 1)) + sublist_length *= 2 + sublist_number = math.ceil(sublist_number / 2) diff --git a/merge_sort_test.py b/merge_sort_test.py index 9f110bc..1eae077 100644 --- a/merge_sort_test.py +++ b/merge_sort_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env ipython import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort class TestMergeSort(unittest.TestCase): @@ -18,3 +18,10 @@ def test_merge_sort_without_sentinel(self): array_copy = array[:] merge_sort(array, merge_without_sentinel) self.assertEqual(array, sorted(array_copy)) + + def test_merge_ins_sort(self): + for length in range(100, 200): + array = [random.randint(1, 10000) for _ in range(length)] + array_copy = array[:] + merge_ins_sort(array, partition=1) + self.assertEqual(array, sorted(array_copy)) From 242c5ca1a3311d4652d0d52b2abc8c3658c730e8 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 10 Jun 2018 15:20:52 +0800 Subject: [PATCH 08/49] Count number of inversions of an array using insertion sort or merge sort --- Horner_rule.py | 13 +++++++ Horner_rule_test.py | 17 +++++++++ inversion.py | 84 +++++++++++++++++++++++++++++++++++++++++++++ inversion_test.py | 27 +++++++++++++++ merge_sort.py | 55 ++++++++++++++++++++++++----- merge_sort_test.py | 7 +++- 6 files changed, 194 insertions(+), 9 deletions(-) create mode 100644 Horner_rule.py create mode 100644 Horner_rule_test.py create mode 100644 inversion.py create mode 100644 inversion_test.py diff --git a/Horner_rule.py b/Horner_rule.py new file mode 100644 index 0000000..445940a --- /dev/null +++ b/Horner_rule.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# encoding: utf-8 +import functools + + +def Horner_rule(x, coefficients): + """ + Implements Horner's rule + :param x: + :param coefficients: + :return: + """ + return functools.reduce(lambda accumulate, coefficient: coefficient + accumulate * x, reversed(coefficients), 0) diff --git a/Horner_rule_test.py b/Horner_rule_test.py new file mode 100644 index 0000000..2e33809 --- /dev/null +++ b/Horner_rule_test.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import unittest +import random +from Horner_rule import Horner_rule + + +class TestHornerRule(unittest.TestCase): + def test_horner_rule(self): + for _ in range(100): + x = random.randint(1, 5) + coefficients = [random.randint(0, 100) for _ in range(11)] + expected_result = 0 + for index, coefficient in enumerate(coefficients): + expected_result += coefficient * x ** index + self.assertEqual(Horner_rule(x, coefficients), expected_result) diff --git a/inversion.py b/inversion.py new file mode 100644 index 0000000..8ebff46 --- /dev/null +++ b/inversion.py @@ -0,0 +1,84 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +def inversion_with_insertion_sort(array): + """ + Count number of inversions of an array using insertion sort + + Let A[1...n] be an array of n numbers. If i < j and A[i] > A[j] , + then the pair (i, j) is called an inversion_with_insertion_sort of A + :param array: + :return: + """ + array = array[:] + return _inversion_with_insertion_sort(array) + + +def _inversion_with_insertion_sort(array): + """ + :param array: + :return: + """ + inverse = 0 + for j in range(1, len(array)): + key = array[j] + i = j - 1 + while i >= 0 and key < array[i]: + inverse += 1 + array[i + 1] = array[i] + i = i - 1 + array[i + 1] = key + return inverse + + +def inversion_with_merge_sort(array): + """ + Count number of inversions of an array using merge sort + + Let A[1...n] be an array of n numbers. If i < j and A[i] > A[j] , + then the pair (i, j) is called an inversion_with_insertion_sort of A + :param array: + :return: + """ + array = array[:] + return _inversion_with_merge_sort(array, 0, len(array) - 1) + + +def _inversion_with_merge_sort(array, left, right): + if left < right: + mid = (left + right) // 2 + left_inverse = _inversion_with_merge_sort(array, left, mid) + right_inverse = _inversion_with_merge_sort(array, mid + 1, right) + inter_inverse = _merge(array, left, mid, right) + return left_inverse + right_inverse + inter_inverse + else: + return 0 + + +def _merge(array, left, mid, right): + """ + + :param array: + :param left: + :param mid: + :param right: + :return: + """ + left_part = array[left: mid + 1] + left_part.append(float("Inf")) + right_part = array[mid + 1: right + 1] + right_part.append(float("Inf")) + i = 0 + j = 0 + inverse = 0 + for k in range(left, right + 1): + if left_part[i] <= right_part[j]: + array[k] = left_part[i] + i = i + 1 + else: + array[k] = right_part[j] + j = j + 1 + inverse += (mid - left + 1 - i) + return inverse + diff --git a/inversion_test.py b/inversion_test.py new file mode 100644 index 0000000..b85bac9 --- /dev/null +++ b/inversion_test.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# encoding: utf-8 +import unittest +import random +from inversion import inversion_with_insertion_sort, inversion_with_merge_sort + + +class TestInversion(unittest.TestCase): + def test_inversion_with_insertion_sort(self): + for _ in range(100): + array = [random.randint(0, 100) for _ in range(100)] + expected_result = 0 + for i in range(len(array)): + for j in range(i + 1, len(array)): + if array[i] > array[j]: + expected_result += 1 + self.assertEqual(inversion_with_insertion_sort(array), expected_result) + + def test_inversion_with_merge_sort(self): + for _ in range(100): + array = [random.randint(0, 100) for _ in range(100)] + expected_result = 0 + for i in range(len(array)): + for j in range(i + 1, len(array)): + if array[i] > array[j]: + expected_result += 1 + self.assertEqual(inversion_with_merge_sort(array), expected_result) diff --git a/merge_sort.py b/merge_sort.py index 4108076..9e07bea 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -61,14 +61,6 @@ def merge_without_sentinel(array, left, mid, right): array[k: right + 1] = right_part[j: right_length] -def _merge_sort(array, left, right, merge_method): - if left < right: - mid = (left + right) // 2 - _merge_sort(array, left, mid, merge_method) - _merge_sort(array, mid + 1, right, merge_method) - merge_method(array, left, mid, right) - - def merge_sort(array, merge_method=merge_with_sentinel): """ inplace O(nlgn) sort @@ -79,6 +71,14 @@ def merge_sort(array, merge_method=merge_with_sentinel): _merge_sort(array, 0, len(array) - 1, merge_method) +def _merge_sort(array, left, right, merge_method): + if left < right: + mid = (left + right) // 2 + _merge_sort(array, left, mid, merge_method) + _merge_sort(array, mid + 1, right, merge_method) + merge_method(array, left, mid, right) + + def merge_ins_sort(array, partition=2): """ Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make @@ -86,6 +86,8 @@ def merge_ins_sort(array, partition=2): Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined. + + bottom to top version with number of sublists specified :param array: :param partition: number of sublists :return: @@ -104,3 +106,40 @@ def merge_ins_sort(array, partition=2): min(sublist_length * (i + 2) - 1, n - 1)) sublist_length *= 2 sublist_number = math.ceil(sublist_number / 2) + + +def merge_ins_sort2(array, sublist_length): + """ + Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make + it faster in practice for small problem sizes on many machines. + Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when + subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are + sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined. + + top to bottom version with sublist length specified + :param array: + :param sublist_length: + :return: + """ + n = len(array) + assert 0 < sublist_length < n + _merge_ins_sort2(array, 0, n - 1, sublist_length) + + +def _merge_ins_sort2(array, start, end, sublist_length): + """ + + :param array: + :param start: + :param end: + :param sublist_length: + :return: + """ + length = end - start + 1 + if length > sublist_length: + mid = (start + end) // 2 + _merge_ins_sort2(array, start, mid, sublist_length) + _merge_ins_sort2(array, mid + 1, end, sublist_length) + merge_with_sentinel(array, start, mid, end) + else: + insertion_sort(array, start, end) diff --git a/merge_sort_test.py b/merge_sort_test.py index 1eae077..1268d81 100644 --- a/merge_sort_test.py +++ b/merge_sort_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env ipython import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort, merge_ins_sort2 class TestMergeSort(unittest.TestCase): @@ -25,3 +25,8 @@ def test_merge_ins_sort(self): array_copy = array[:] merge_ins_sort(array, partition=1) self.assertEqual(array, sorted(array_copy)) + for length in range(100, 200): + array = [random.randint(1, 10000) for _ in range(length)] + array_copy = array[:] + merge_ins_sort2(array, sublist_length=15) + self.assertEqual(array, sorted(array_copy)) From 9fce055f0e5653f0f459c0c38da89b38c1c77a96 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 10 Jun 2018 15:22:55 +0800 Subject: [PATCH 09/49] remove some file written in c --- Horner.c | 34 ---------------- Ins-Merge.c | 98 --------------------------------------------- Ins-Merge2.c | 94 ------------------------------------------- InsSort-BinSearch.c | 51 ----------------------- inversion.c | 81 ------------------------------------- inversion2.c | 87 ---------------------------------------- 6 files changed, 445 deletions(-) delete mode 100644 Horner.c delete mode 100644 Ins-Merge.c delete mode 100644 Ins-Merge2.c delete mode 100644 InsSort-BinSearch.c delete mode 100644 inversion.c delete mode 100644 inversion2.c diff --git a/Horner.c b/Horner.c deleted file mode 100644 index d814262..0000000 --- a/Horner.c +++ /dev/null @@ -1,34 +0,0 @@ -//This procedure implements Horner's rule for evaluating -//a polynomial -#include -#include - -void Horner(int A[], int n, int x) { - int sum = 0; - int i; - - for (i = n; i >= 0; i--) - sum = A[i] + x * sum; - printf("%d\n", sum); -} - -//void Horner2(int A[], int n, int x) { - //int sum = 0; - //int i; -// - //for (i = n; i >= 0; i--) - //sum = A[i] * pow(x, i) + sum; - //printf("%d\n", sum); -//} - -int main() { - int a[10] = {1,2,30,4,5,6,7,8,9,0}; - - Horner(a, 9, 2); - //Horner2(a, 9, 2); - return 0; -} - - - - diff --git a/Ins-Merge.c b/Ins-Merge.c deleted file mode 100644 index 9710910..0000000 --- a/Ins-Merge.c +++ /dev/null @@ -1,98 +0,0 @@ -//* This program uses insertion sort within merge sort when subproblems -//* become sufficiently small - // MERGE(A, p, q, r) - // n1 = q - p + 1 - // n2 = r - q - // L[1...n1] = A[p...q] - // R[1...n2] = A[q+1...r] - // L[n1+1] = ∞ - // R[n2+1] = ∞ - // i = 1 - // j = 1 - // for k = p to r - // if L[i] <= R[j] - // A[k] = L[i] - // i = i + 1 - // else - // A[k] = R[j] - // j = j + 1 -#include -#include -#include - -void InsSort(int a[], int n) -{ - int i, j; - int key; - for (i = 1; i < n; i++) - { - key = a[i]; - for (j = i - 1; j >= 0 && a[j] > key; j--) - { - a[j + 1] = a[j]; - a[j] = key; - } - } -} - -void MERGE(int A[], int first, int inter, int end) -{ - int len1 = inter - first + 1; - int len2 = end - inter; - int i; - int j; - int k; - int *L; - int *R; - - L = (int *)calloc(len1 + 1, sizeof(int)); - R = (int *)calloc(len2 + 1, sizeof(int)); - for (i = 0; i < len1; i++) - L[i] = A[first + i]; - for (j = 0; j < len2; j++) - R[j] = A[inter + j + 1]; - L[len1] = INT_MAX; - R[len2] = INT_MAX; - - i = 0; - j = 0; - for (k = first; k <= end; k++) - { - if (L[i] <= R[j]) - A[k] = L[i++]; - else - A[k] = R[j++]; - } - free(L); - free(R); -} - -void MergeSort(int A[], int n, int length) -{ - int num = n / length; - int last_length = n - (num - 1) * length; - int i; - - for (i = 1; i < num; i++) - { - InsSort(A + (i - 1) * length, length); - if (i > 1) - MERGE(A, 0 , (i - 1) * length - 1, i * length - 1); - } - InsSort(A + (i - 1) * length, last_length); - MERGE(A, 0, (i - 1) * length - 1, n - 1); -} - -int main() -{ - int a[77]; - int i; - - for (i = 0; i < 77; i++) - a[i] = 77 - i; - MergeSort(a, 77, 9); - for (i = 0; i < 77; i++) - printf("%d\t", a[i]); - printf("\n"); - return 0; -} diff --git a/Ins-Merge2.c b/Ins-Merge2.c deleted file mode 100644 index d0ce4bc..0000000 --- a/Ins-Merge2.c +++ /dev/null @@ -1,94 +0,0 @@ -//* Divide and conquer version of Ins-Merge - // MERGE(A, p, q, r) - // n1 = q - p + 1 - // n2 = r - q - // L[1...n1] = A[p...q] - // R[1...n2] = A[q+1...r] - // L[n1+1] = ∞ - // R[n2+1] = ∞ - // i = 1 - // j = 1 - // for k = p to r - // if L[i] <= R[j] - // A[k] = L[i] - // i = i + 1 - // else - // A[k] = R[j] - // j = j + 1 -#include -#include -#include - -void InsSort(int a[], int n) -{ - int i, j; - int key; - for (i = 1; i < n; i++) - { - key = a[i]; - for (j = i - 1; j >= 0 && a[j] > key; j--) - { - a[j + 1] = a[j]; - a[j] = key; - } - } -} - -void MERGE(int A[], int first, int inter, int end) -{ - int len1 = inter - first + 1; - int len2 = end - inter; - int i; - int j; - int k; - int *L; - int *R; - - L = (int *)calloc(len1 + 1, sizeof(int)); - R = (int *)calloc(len2 + 1, sizeof(int)); - for (i = 0; i < len1; i++) - L[i] = A[first + i]; - for (j = 0; j < len2; j++) - R[j] = A[inter + j + 1]; - L[len1] = INT_MAX; - R[len2] = INT_MAX; - - i = 0; - j = 0; - for (k = first; k <= end; k++) - { - if (L[i] <= R[j]) - A[k] = L[i++]; - else - A[k] = R[j++]; - } - free(L); - free(R); -} - -void MergeSort(int A[], int start, int end, int length) -{ - if ((end - start + 1) > length) { - int middle = (start + end) / 2; - - MergeSort(A, start, middle, length); - MergeSort(A, middle + 1, end, length); - MERGE(A, start, middle, end); - } - else - InsSort(A + start, end - start + 1); -} - -int main() -{ - int a[77]; - int i; - - for (i = 0; i < 77; i++) - a[i] = 77 - i; - MergeSort(a, 1, 8, 9); - for (i = 0; i < 77; i++) - printf("%d\t", a[i]); - printf("\n"); - return 0; -} diff --git a/InsSort-BinSearch.c b/InsSort-BinSearch.c deleted file mode 100644 index a85159a..0000000 --- a/InsSort-BinSearch.c +++ /dev/null @@ -1,51 +0,0 @@ -#include - -void swap(int *a, int *b) -{ - int tmp = *a; - - *a = *b; - *b = tmp; -} -//Determine where x should be placed in array A -int BinSearch(int A[], int first, int end, int x) -{ - int length = end - first; - int inter; - - while (length >= 0) - { - inter = (first + end) / 2; - if (x == A[inter]) - return inter; - else if (x < A[inter]) - end = inter - 1; - else - first = inter + 1; - length = end - first; - } -// printf("%d, %d\n", first, end); - return first; -} - -void InsSort(int a[], int n) -{ - int i, j; - int pos; - - for (i = 1; i < n; i++) - { - pos = BinSearch(a, 0, i - 1, a[i]); - for (j = i; j > pos; j--) - swap(a + j, a + j - 1); - } -} - -int main() -{ - int a[7] = { 31, 101, 59, 26, 0, 61, 58 }; - - InsSort(a, 7); - printf("%d,%d,%d,%d,%d,%d,%d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6]); - return 0; -} diff --git a/inversion.c b/inversion.c deleted file mode 100644 index 0a96704..0000000 --- a/inversion.c +++ /dev/null @@ -1,81 +0,0 @@ -// This program determines the number of inversions in -// any permution on n elements using a global variable invs -#include -#include -#include - - // MERGE(A, p, q, r) - // n1 = q - p + 1 - // n2 = r - q - // L[1...n1] = A[p...q] - // R[1...n2] = A[q+1...r] - // L[n1+1] = ∞ - // R[n2+1] = ∞ - // i = 1 - // j = 1 - // for k = p to r - // if L[i] <= R[j] - // A[k] = L[i] - // i = i + 1 - // else - // A[k] = R[j] - // j = j + 1 -static int invs = 0; - -static void combine(int B[], int first, int inter, int end) -{ - int len1 = inter - first + 1; - int len2 = end - inter; - int i; - int j; - int k; - int *L; - int *R; - - L = (int *)calloc(len1 + 1, sizeof(int)); - R = (int *)calloc(len2 + 1, sizeof(int)); - for (i = 0; i < len1; i++) - L[i] = B[first + i]; - for (j = 0; j < len2; j++) - R[j] = B[inter + j + 1]; - L[len1] = INT_MAX; - R[len2] = INT_MAX; - - i = 0; - j = 0; - for (k = first; k <= end; k++) - { - if (L[i] <= R[j]) - B[k] = L[i++]; else { B[k] = R[j++]; - invs = invs + len1 - i; - } - - } - free(L); - free(R); -} - -static void divide(int B[], int first, int end) -{ - if (first < end) - { - int middle = (first + end) / 2; - - divide(B, first, middle); - divide(B, middle + 1, end); - combine(B, first, middle, end); - } -} - -int inversion(int A[], int first, int end) { - int i; - int *B = (int *) calloc(end - first + 1, sizeof(int)); - - for (i = first; i <= end; i++) - B[i] = A[i]; - divide(B, first, end); - free(B); - i = invs; - invs = 0; - return i; -} diff --git a/inversion2.c b/inversion2.c deleted file mode 100644 index a645192..0000000 --- a/inversion2.c +++ /dev/null @@ -1,87 +0,0 @@ -// This program determines the number of inversions in -// any permution on n elements -// This version no longer uses global variable. It is more 'divide and conquer' than inversion.c -#include -#include -#include - - // MERGE(A, p, q, r) - // n1 = q - p + 1 - // n2 = r - q - // L[1...n1] = A[p...q] - // R[1...n2] = A[q+1...r] - // L[n1+1] = ∞ - // R[n2+1] = ∞ - // i = 1 - // j = 1 - // for k = p to r - // if L[i] <= R[j] - // A[k] = L[i] - // i = i + 1 - // else - // A[k] = R[j] - // j = j + 1 - -static int combine(int B[], int first, int inter, int end) -{ - int len_left = inter - first + 1; - int len_right = end - inter; - int i; - int j; - int k; - int *L; - int *R; - int invs_cross = 0; - - L = (int *)calloc(len_left + 1, sizeof(int)); - R = (int *)calloc(len_right + 1, sizeof(int)); - for (i = 0; i < len_left; i++) - L[i] = B[first + i]; - for (j = 0; j < len_right; j++) - R[j] = B[inter + j + 1]; - L[len_left] = INT_MAX; - R[len_right] = INT_MAX; - - i = 0; - j = 0; - for (k = first; k <= end; k++) - { - if (L[i] <= R[j]) - B[k] = L[i++]; - else { - B[k] = R[j++]; - invs_cross = invs_cross + len_left - i; - } - - } - free(L); - free(R); - return invs_cross; -} - -int divide(int B[], int first, int end) -{ - int invs_left, invs_right, invs_cross; - - if (first < end) - { - int middle = (first + end) / 2; - - invs_left = divide(B, first, middle); - invs_right = divide(B, middle + 1, end); - invs_cross = combine(B, first, middle, end); - return invs_left + invs_right + invs_cross; - } - return 0; -} - -int inversion(int A[], int first, int end) { - int i; - int *B = (int *) calloc(end - first + 1, sizeof(int)); - - for (i = first; i <= end; i++) - B[i] = A[i]; - i = divide(B, first, end); - free(B); - return i; -} From 4bde396e376c81d18d938011078a7feb801dd850 Mon Sep 17 00:00:00 2001 From: wq Date: Tue, 7 Aug 2018 14:01:42 +0800 Subject: [PATCH 10/49] add selection sort --- selection-sort.c | 29 ----------------------------- selection_sort.py | 22 ++++++++++++++++++++++ selection_sort_test.py | 15 +++++++++++++++ 3 files changed, 37 insertions(+), 29 deletions(-) delete mode 100644 selection-sort.c create mode 100644 selection_sort.py create mode 100644 selection_sort_test.py diff --git a/selection-sort.c b/selection-sort.c deleted file mode 100644 index 1ed70eb..0000000 --- a/selection-sort.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -void SelectionSort(int *A, int n) { - int i, j; - int min, index; - int tmp; - - for (i = 0; i < n - 1; i++) { - min = A[i]; - index = i; - - for (j = i + 1; j < n; j++) - if (A[j] < min) { - min = A[j]; - index = j; - } - tmp = A[i]; - A[i] = A[index]; - A[index] = tmp; - } -} - -int main() { - int A[6] = {6, 5, 5, 3, 100, 1}; - - SelectionSort(A, 6); - printf("%d, %d, %d, %d, %d, %d\n", A[0], A[1], A[2], A[3], A[4], A[5]); - return 0; -} diff --git a/selection_sort.py b/selection_sort.py new file mode 100644 index 0000000..c0aa2e6 --- /dev/null +++ b/selection_sort.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +def selection_sort(array): + """ + Inplace sort + Consider sorting n numbers stored in array A by first finding the smallest element of A + and exchanging it with the element in A[1] . Then find the second smallest element of A, and exchange it with A[2]. + Continue in this manner for the first n - 1 elements of A. + :param array: + :return: + """ + n = len(array) + for i in range(n - 1): + minimum = array[i] + index = i + for j in range(i + 1, n): + if minimum > array[j]: + minimum = array[j] + index = j + array[i], array[index] = array[index], array[i] diff --git a/selection_sort_test.py b/selection_sort_test.py new file mode 100644 index 0000000..3cf6f7c --- /dev/null +++ b/selection_sort_test.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python +# encoding: utf-8 + +import unittest +import random +from selection_sort import selection_sort + + +class TestSelectionSort(unittest.TestCase): + def test_selection_sort(self): + for size in range(20): + array = [random.randint(1, 10000) for _ in range(size)] + sorted_array = sorted(array) + selection_sort(array) + self.assertEqual(array, sorted_array) From 35076fd22d33b20a394ad32cbdedf488506bf43e Mon Sep 17 00:00:00 2001 From: Firkraag Date: Thu, 14 Feb 2019 23:32:31 +0800 Subject: [PATCH 11/49] modify --- quicksort.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quicksort.py b/quicksort.py index e269c00..5417bec 100644 --- a/quicksort.py +++ b/quicksort.py @@ -1,9 +1,11 @@ from partition import partition, partition2, partition3, randomized_partition + def quicksort(A, p, r, partition_method = partition): if p < r: q = partition_method(A, p, r) quicksort(A, p, q - 1) quicksort(A, q+1, r) + def randomized_quicksort(A, p, r): if p < r: q = randomized_partition(A, p, r) From 806ea17928324b401bc04b2233ec2193b938fee8 Mon Sep 17 00:00:00 2001 From: wq Date: Fri, 15 Feb 2019 21:22:30 +0800 Subject: [PATCH 12/49] format quicksort --- linked_list.py => linkedlist.py | 0 quicksort.py | 10 +++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) rename linked_list.py => linkedlist.py (100%) diff --git a/linked_list.py b/linkedlist.py similarity index 100% rename from linked_list.py rename to linkedlist.py diff --git a/quicksort.py b/quicksort.py index e269c00..810560e 100644 --- a/quicksort.py +++ b/quicksort.py @@ -1,11 +1,15 @@ from partition import partition, partition2, partition3, randomized_partition -def quicksort(A, p, r, partition_method = partition): + + +def quicksort(A, p, r, partition_method=partition): if p < r: q = partition_method(A, p, r) quicksort(A, p, q - 1) - quicksort(A, q+1, r) + quicksort(A, q + 1, r) + + def randomized_quicksort(A, p, r): if p < r: q = randomized_partition(A, p, r) randomized_quicksort(A, p, q - 1) - randomized_quicksort(A, q+1, r) + randomized_quicksort(A, q + 1, r) From 5fae0eb019d4ddc0132938972695ab966c50d87b Mon Sep 17 00:00:00 2001 From: Firkraag Date: Sat, 16 Feb 2019 23:55:06 +0800 Subject: [PATCH 13/49] type annotation --- selection_sort.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selection_sort.py b/selection_sort.py index c0aa2e6..6bdf522 100644 --- a/selection_sort.py +++ b/selection_sort.py @@ -2,7 +2,7 @@ # encoding: utf-8 -def selection_sort(array): +def selection_sort(array:list): """ Inplace sort Consider sorting n numbers stored in array A by first finding the smallest element of A From 5159e9ddccab844ddb611851c56662e180bffa81 Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 18 Feb 2019 21:16:39 +0800 Subject: [PATCH 14/49] Some insertion sort and merge sort variations --- insertion_sort.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/insertion_sort.py b/insertion_sort.py index c717d5e..b149efc 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -6,7 +6,7 @@ def insert_with_linear_search(array, right_index): Use linear search to find a position in already sorted array[0...right_index-1] to insert array[right_index] into, making array[0...right_index] a sorted array. :param array: - :param right_index: ridht_index > 0 + :param right_index: right_index > 0 :return: """ key = array[right_index] @@ -31,9 +31,9 @@ def insert_with_binary_search(array, right_index): array[index] = x -def _insertion_sort_recursive_aux(array, length, insert_method): +def _insertion_sort_recursive(array, length, insert_method): if length > 1: - _insertion_sort_recursive_aux(array, length - 1, insert_method) + _insertion_sort_recursive(array, length - 1, insert_method) insert_method(array, length - 1) @@ -61,4 +61,4 @@ def insertion_sort_recursive(array, insert_method=insert_with_linear_search): :param insert_method: :return: """ - _insertion_sort_recursive_aux(array, len(array), insert_method) + _insertion_sort_recursive(array, len(array), insert_method) From 8d6ca770f5b1a96defb9e837d47fafc509e4af86 Mon Sep 17 00:00:00 2001 From: wq Date: Tue, 19 Feb 2019 21:31:16 +0800 Subject: [PATCH 15/49] linked list --- linkedlist.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/linkedlist.py b/linkedlist.py index c9eb281..f770f6d 100644 --- a/linkedlist.py +++ b/linkedlist.py @@ -1,8 +1,7 @@ -class linked_list(object): - def __init__(self, key=None): +class LinkedList(object): + def __init__(self): self.head = None self.size = 0 - self.key = key def empty(self): return self.size == 0 @@ -35,7 +34,7 @@ def extract(self, x): return x -class linked_list_node(object): +class LinkedListNode(object): def __init__(self, element): self.key = element self.prev = None From 3425c38e7f2b5c15a058142a4a58631fe821ebaf Mon Sep 17 00:00:00 2001 From: Firkraag Date: Fri, 1 Mar 2019 23:51:01 +0800 Subject: [PATCH 16/49] type annotation --- two_sum.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/two_sum.py b/two_sum.py index 78c2b6c..d6301e0 100644 --- a/two_sum.py +++ b/two_sum.py @@ -1,4 +1,4 @@ -def two_sum(x, array): +def two_sum(x:int, array:list): """ an algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x. From f91af9d74b98bb4b85725e7e69002a176c38756d Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 5 Aug 2019 14:37:51 +0800 Subject: [PATCH 17/49] conform heap.py to PEP8 --- gcd.c | 21 --------------------- gcd.py | 16 ++++++++++++++++ heap.py | 29 +++++++++++++++-------------- heap_test.py | 12 ++++++------ 4 files changed, 37 insertions(+), 41 deletions(-) delete mode 100644 gcd.c create mode 100644 gcd.py diff --git a/gcd.c b/gcd.c deleted file mode 100644 index 8dd5f52..0000000 --- a/gcd.c +++ /dev/null @@ -1,21 +0,0 @@ -#include - -/* gcd: compute the greatest common divisor of m and n; - return value: gcd */ - unsigned gcd(unsigned m, unsigned n) { - unsigned rem; - - while (n > 0) - { - rem = m % n; - m = n; - n = rem; - } - return m; -} - -int main() { - printf("%u\n", gcd(63 - 1194 + 1387, 1387)); - printf("%u\n", gcd(1273, 1387)); - return 0; -} diff --git a/gcd.py b/gcd.py new file mode 100644 index 0000000..ca4e42e --- /dev/null +++ b/gcd.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +def gcd(m: int, n: int): + """ + compute the greatest common divisor of m and n; + :param m: + :param n: + :return: + """ + while n > 0: + rem = m % n + m = n + n = rem + return m diff --git a/heap.py b/heap.py index 56804b4..0f0e3ed 100644 --- a/heap.py +++ b/heap.py @@ -1,20 +1,20 @@ -import math - - -class max_heap(list): +class MaxHeap(list): def __init__(self, data): list.__init__(self, data) self.length = len(data) self.heap_size = self.length self.build_max_heap() - def left(self, i): + @staticmethod + def left(i): return 2 * i + 1 - def right(self, i): + @staticmethod + def right(i): return 2 * i + 2 - def parent(self, i): + @staticmethod + def parent(i): return (i - 1) // 2 def max_heapify(self, i): @@ -32,7 +32,6 @@ def max_heapify(self, i): def build_max_heap(self): self.heap_size = self.length - print(self.length) for i in range(self.length // 2 - 1, -1, -1): self.max_heapify(i) @@ -44,8 +43,7 @@ def heapsort(self): self.max_heapify(0) -# print( self) -class min_heap(list): +class MinHeap(list): def __init__(self, data): list.__init__(self, data) self.length = len(data) @@ -53,15 +51,18 @@ def __init__(self, data): self.build_min_heap() def __contains__(self, y): - return y in self[0:self.heap_size] + return y in self[:self.heap_size] - def left(self, i): + @staticmethod + def left(i): return 2 * i + 1 - def right(self, i): + @staticmethod + def right(i): return 2 * i + 2 - def parent(self, i): + @staticmethod + def parent(i): return (i - 1) // 2 def min_heapify(self, i): diff --git a/heap_test.py b/heap_test.py index cfff113..9bf8d74 100644 --- a/heap_test.py +++ b/heap_test.py @@ -1,5 +1,5 @@ import unittest -from heap import max_heap, min_heap +from heap import MaxHeap, MinHeap class TestHeap(unittest.TestCase): @@ -10,30 +10,30 @@ class TestHeap(unittest.TestCase): # self.assertEqual(a.__heap_size, 10) def test_max_heapify(self): a = [16, 4, 10, 14, 7, 9, 3, 2, 8, 1] - h = max_heap(a) + h = MaxHeap(a) h.max_heapify(1) self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) def test_build_max_heap(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_heap(a) + h = MaxHeap(a) h.build_max_heap() self.assertEqual(h, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) def test_heapsort(self): a = [4, 1, 3, 3, 16, 9, 10, 14, 8, 7] - h = max_heap(a) + h = MaxHeap(a) h.heapsort() self.assertEqual(h, [1, 3, 3, 4, 7, 8, 9, 10, 14, 16]) def test_min_heapify(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - h = min_heap(a) + h = MinHeap(a) h.min_heapify(1) self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) def test_build_min_heap(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - h = min_heap(a) + h = MinHeap(a) h.build_min_heap() self.assertEqual(h, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) From 1c292573e812f2bd380f06b0def567f4ea848e30 Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 28 Aug 2019 09:51:59 +0800 Subject: [PATCH 18/49] python3 class is new-style class, so explicitly inheriting from object is not necessary --- Fibonacci.c | 22 ---------- fibonacci_heap.py => fibonacciheap.py | 6 +-- linkedlist.py | 63 ++++++++++++++------------- 3 files changed, 36 insertions(+), 55 deletions(-) delete mode 100644 Fibonacci.c rename fibonacci_heap.py => fibonacciheap.py (98%) diff --git a/Fibonacci.c b/Fibonacci.c deleted file mode 100644 index 181a626..0000000 --- a/Fibonacci.c +++ /dev/null @@ -1,22 +0,0 @@ -void swap(int *x, int *y) { - int temp; - - temp = *x; - *x = *y; - *y = temp; -} - -/* Compute Fibonacci number fib(n); fib(0) = 1, fib(1); fib(n) = fib(n-1) + fib(n-2); return fib(n) of int type */ - -int fib(int n) { - int fib1 = 1, fib2 = 1; - int i; - - for (i = 2; i <= n; i++) { - fib1 = fib1 + fib2; - swap(&fib1, &fib2); - } - return fib2; - -} - diff --git a/fibonacci_heap.py b/fibonacciheap.py similarity index 98% rename from fibonacci_heap.py rename to fibonacciheap.py index 0f7434b..6580321 100644 --- a/fibonacci_heap.py +++ b/fibonacciheap.py @@ -13,7 +13,7 @@ def __iter__(self): '''generate a list of children of the node for iteration''' self.children = [] self.index = 0 - if self.child != None: + if self.child is not None: child = self.child while True: self.children.append(child) @@ -203,8 +203,8 @@ def cut(self, x, y): def cascading_cut(self, y): z = y.p - if z != None: - if y.mark == False: + if z is not None: + if y.mark is False: y.mark = True else: self.cut(y, z) diff --git a/linkedlist.py b/linkedlist.py index f770f6d..7fe4130 100644 --- a/linkedlist.py +++ b/linkedlist.py @@ -1,41 +1,44 @@ -class LinkedList(object): +from typing import Any, Optional + + +class LinkedListNode: + def __init__(self, key: Any): + self.key: Any = key + self.prev: Optional[LinkedListNode] = None + self.next: Optional[LinkedListNode] = None + + +class LinkedList: def __init__(self): - self.head = None - self.size = 0 + self.head: Optional[LinkedListNode] = None + self.size: int = 0 - def empty(self): + def empty(self) -> bool: return self.size == 0 - def search(self, k): - x = self.head - while x and x.key != k: - x = x.next - return x + def search(self, key: Any) -> Optional[LinkedListNode]: + node = self.head + while node and node.key != key: + node = node.next + return node - def insert(self, x): + def insert(self, node: LinkedListNode) -> None: self.size = self.size + 1 - x.next = self.head + node.next = self.head if self.head: - self.head.prev = x - self.head = x - x.prev = None + self.head.prev = node + self.head = node + node.prev = None - def delete(self, x): + def delete(self, node: LinkedListNode) -> None: self.size = self.size - 1 - if x.prev: - x.prev.next = x.next + if node.prev: + node.prev.next = node.next else: - self.head = x.next - if x.next: - x.next.prev = x.prev - - def extract(self, x): - self.delete(x) - return x - + self.head = node.next + if node.next: + node.next.prev = node.prev -class LinkedListNode(object): - def __init__(self, element): - self.key = element - self.prev = None - self.next = None + def extract(self, node: LinkedListNode) -> LinkedListNode: + self.delete(node) + return node From 5916e7c528c69ba2ce9e2aa5210de737cd862a89 Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 28 Aug 2019 17:07:54 +0800 Subject: [PATCH 19/49] Some insertion sort and merge sort variations --- any_disks_intersect.py | 4 +- any_segments_intersect.py | 4 +- closest_points.py | 6 +- closest_points_l1_distance.py | 6 +- closest_points_l_infinite_distance.py | 17 +++- deque.py | 67 ++++++++------- euclid.py | 4 +- fft.py | 8 +- fibonacciheap.py | 58 ++++++++----- graph.py | 10 +-- hash.py | 3 +- k_way_merge.py | 6 +- linked_list_test.py | 38 ++++----- linkedlist.py | 1 + min_heap_with_linked_list.py | 2 +- min_heap_with_linked_list_test.py | 114 +++++++++++++------------- os_tree.py | 6 +- os_tree_test.py | 4 +- polar_angle.py | 27 ++++-- polygon_area.py | 1 + priority_queue.py | 20 +++-- priority_queue_test.py | 14 ++-- queue.py | 42 ---------- three_points_colinear.py | 4 +- wrestlers.py | 12 +-- 25 files changed, 252 insertions(+), 226 deletions(-) delete mode 100644 queue.py diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 3e35ad3..130d450 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -3,7 +3,7 @@ # we use 0 to mean red, 1 to mean black from tree import Node, Tree -from heap import max_heap +from heap import MaxHeap def comparable(a, b): @@ -271,7 +271,7 @@ def any_disks_intersect(S): y = center_point[1] point_list.append(point([x - radius, 0, y], s)) point_list.append(point([x + radius, 1, y], s)) - heap_point = max_heap(point_list) + heap_point = MaxHeap(point_list) heap_point.heapsort() print(heap_point) for p in heap_point: diff --git a/any_segments_intersect.py b/any_segments_intersect.py index 0c77e08..ffa2888 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -3,7 +3,7 @@ # we use 0 to mean red, 1 to mean black from tree import Node, Tree -from heap import max_heap +from heap import MaxHeap from segment_intersect import segments_intersect def vertical(a): @@ -276,7 +276,7 @@ def any_segments_intersect(S): for s in segment_list: point_list.append(point([s[0][0], 0, s[0][1]], s)) point_list.append(point([s[1][0], 1, s[1][1]], s)) - heap_point = max_heap(point_list) + heap_point = MaxHeap(point_list) heap_point.heapsort() for p in heap_point: if p[1] == 0: diff --git a/closest_points.py b/closest_points.py index e61bccb..123c264 100644 --- a/closest_points.py +++ b/closest_points.py @@ -1,17 +1,17 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): diff --git a/closest_points_l1_distance.py b/closest_points_l1_distance.py index 25361d5..6f20902 100644 --- a/closest_points_l1_distance.py +++ b/closest_points_l1_distance.py @@ -1,17 +1,17 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): diff --git a/closest_points_l_infinite_distance.py b/closest_points_l_infinite_distance.py index 0b1e1fc..5559e94 100644 --- a/closest_points_l_infinite_distance.py +++ b/closest_points_l_infinite_distance.py @@ -1,24 +1,31 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap + def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X + + def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): Y.append((YY[i][1], YY[i][0])) return Y + + def distance(p1, p2): return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1])) + + def brute_force(P): P = list(P) d = float("Inf") @@ -26,10 +33,14 @@ def brute_force(P): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d + + def closest_points(S): X = x_sort(S) Y = y_sort(S) return closest_points_aux(S, X, Y) + + def closest_points_aux(P, X, Y): length = len(P) half = int(ceil(length / 2)) diff --git a/deque.py b/deque.py index 61509a4..9590822 100644 --- a/deque.py +++ b/deque.py @@ -1,32 +1,37 @@ -from queue import queue, FullException, EmptyException - -def deque(queue): - ''' - whereas a queue allows insertion at one end and deletion at the other end, a deque(double-ended queue allows insertion and deletion at both ends - ''' - def __init__(self, size): - super(deque, self).__init__(size) - def enqueue_tail(self, x): - self.enqueue(x) - def dequeue_head(self): - return self.dequeue() - def enqueue_head(self, x): - if self.full(): - raise FullException("This double-ended queue is full") - else: - if self.head == 0: - self.head = self.length - 1 - else: - self.head = self.head - 1 - self[self.head] = x - def dequeue_tail(self): - if self.emtpy(): - raise EmptyException("This double-ended queue is empty") - else: - if self.tail == 0: - self.tail = self.length - 1 - else: - self.tail = self.tail - 1 - - return self[self.tail] +from Queue import Queue, FullException, EmptyException + +def deque(Queue): + """ + whereas a Queue allows insertion at one end and deletion at the other end, a deque(double-ended Queue allows insertion and deletion at both ends + """ + + def __init__(self, size): + super(deque, self).__init__(size) + + def enqueue_tail(self, x): + self.enqueue(x) + + def dequeue_head(self): + return self.dequeue() + + def enqueue_head(self, x): + if self.full(): + raise FullException("This double-ended Queue is full") + else: + if self.head == 0: + self.head = self.length - 1 + else: + self.head = self.head - 1 + self[self.head] = x + + def dequeue_tail(self): + if self.emtpy(): + raise EmptyException("This double-ended Queue is empty") + else: + if self.tail == 0: + self.tail = self.length - 1 + else: + self.tail = self.tail - 1 + + return self[self.tail] diff --git a/euclid.py b/euclid.py index e5f97bc..3d81b24 100644 --- a/euclid.py +++ b/euclid.py @@ -1,15 +1,17 @@ #!/usr/bin/env python # coding=utf-8 + def euclid(a, b): if b == 0: return a else: return euclid(b, a % b) + def extended_euclid(a, b): if b == 0: - return (a, 1, 0) + return a, 1, 0 else: d, x, y = extended_euclid(b, a % b) return d, y, x - (a / b) * y diff --git a/fft.py b/fft.py index dd5ee18..69db33a 100644 --- a/fft.py +++ b/fft.py @@ -2,6 +2,7 @@ import math + def recursive_fft(a): n = len(a) if n == 1: @@ -13,16 +14,19 @@ def recursive_fft(a): y0 = recursive_fft(a0) y1 = recursive_fft(a1) y = [0.0] * n - for k in range(0, n / 2): + for k in range(0, n // 2): y[k] = y0[k] + w * y1[k] y[k + n / 2] = y0[k] - w * y1[k] w = w * wn return y + def recursive_inverse_fft(y): n = len(y) result = recursive_inverse_fft_aux(y) return [result[i] / n for i in range(0, n)] + + def recursive_inverse_fft_aux(y): n = len(y) if n == 1: @@ -34,7 +38,7 @@ def recursive_inverse_fft_aux(y): a0 = recursive_inverse_fft_aux(y0) a1 = recursive_inverse_fft_aux(y1) a = [0.0] * n - for k in range(0, n / 2): + for k in range(0, n // 2): a[k] = (a0[k] + w * a1[k]) a[k + n / 2] = (a0[k] - w * a1[k]) w = w * wn diff --git a/fibonacciheap.py b/fibonacciheap.py index 6580321..a88df85 100644 --- a/fibonacciheap.py +++ b/fibonacciheap.py @@ -1,4 +1,4 @@ -class fibonacci_node(object): +class FibonacciNode: degree = 0 p = None child = None @@ -10,7 +10,9 @@ def __init__(self, k): self.key = k def __iter__(self): - '''generate a list of children of the node for iteration''' + """ + generate a list of children of the node for iteration + """ self.children = [] self.index = 0 if self.child is not None: @@ -31,15 +33,23 @@ def next(self): raise StopIteration def insert(self, x): - '''insert x to the left of node''' + """ + insert x to the left of node + :param x: + :return: + """ x.left = self.left x.right = self self.left.right = x self.left = x def concatenate(self, x): - '''concatenate two lists represented by the node and x, - x mustn't be None''' + """ + concatenate two lists represented by the node and x, + x mustn't be None + :param x: + :return: + """ self.left.right = x.right x.right.left = self.left self.left = x @@ -53,7 +63,7 @@ def add_child(self, y): self.degree = self.degree + 1 y.mark = False y.p = self - if self.child == None: + if self.child is None: self.child = y y.left = y y.right = y @@ -72,16 +82,19 @@ def remove_child(self, y): y.remove() -class fibonacci_heap(object): +class FibonacciHeap(object): def __init__(self): self.n = 0 self.minimum = None def __iter__(self): - '''generate a list of children of the node for iteration''' + """ + generate a list of children of the node for iteration + :return: + """ self.root_list = [] self.index = 0 - if self.minimum != None: + if self.minimum is not None: root = self.minimum while True: self.root_list.append(root) @@ -101,7 +114,7 @@ def next(self): def __repr__(self): s = '' x = self.minimum - if x != None: + if x is not None: while True: s = s + '\t' + str(x.key) if x == self.minimum.left: @@ -113,9 +126,13 @@ def __repr__(self): return '' def insert(self, x): - '''insert the node x into the root list of fibonacci heap''' + """ + insert the node x into the root list of fibonacci heap + :param x: + :return: + """ x.p = None - if self.minimum == None: + if self.minimum is None: self.minimum = x x.left = x x.right = x @@ -129,10 +146,10 @@ def minimum(self): return self.minimum def union(self, h): - cat = fibonacci_heap() - if self.minimum == None: + cat = FibonacciHeap() + if self.minimum is None: return h - elif h.minimum == None: + elif h.minimum is None: return self else: self.minimum.concatenate(h.minimum) @@ -145,7 +162,7 @@ def union(self, h): def extract_min(self): z = self.minimum - if z != None: + if z is not None: for child in z: self.insert(child) z.remove() @@ -167,7 +184,7 @@ def consolidate(self): d = x.degree print('w.key = {}'.format(w.key)) print('w.degree = {}'.format(w.degree)) - while A[d] != None: + while A[d] is not None: y = A[d] if x.key > y.key: x, y = y, x @@ -177,10 +194,11 @@ def consolidate(self): A[d] = x self.minimum = None for i in A: - if i != None: + if i is not None: self.insert(i) - def link(self, y, x): + @staticmethod + def link(y, x): y.remove() x.add_child(y) @@ -190,7 +208,7 @@ def decrease_key(self, x, k): return x.key = k y = x.p - if y != None and x.key < y.key: + if y is not None and x.key < y.key: self.cut(x, y) self.cascading_cut(y) if x.key < self.minimum.key: diff --git a/graph.py b/graph.py index 43e668d..be04060 100644 --- a/graph.py +++ b/graph.py @@ -1,4 +1,4 @@ -from queue import queue +from Queue import Queue import disjoint_sets_forest as dsf import sys @@ -11,11 +11,11 @@ def __repr__(self): return str(self.key) def print_path(self, v): - '''print( out the vertices on a shortest path from s to) - v, assuming that BFS has already computed a breadth-first tree''' + """print( out the vertices on a shortest path from s to) + v, assuming that BFS has already computed a breadth-first tree""" if self == v: print(self, ) - elif v.p == None: + elif v.p is None: print("No path from {} to {} exists".format(self.key, v.key)) else: self.print_path(v.p) @@ -80,7 +80,7 @@ def bfs(self, s): s.color = 1 s.d = 0 s.p = None - q = queue(2 * len(self.vertices)) + q = Queue(2 * len(self.vertices)) q.enqueue(s) while not q.empty(): u = q.dequeue() diff --git a/hash.py b/hash.py index 6b88130..9e547b4 100755 --- a/hash.py +++ b/hash.py @@ -1,10 +1,11 @@ #!/usr/bin/env ipython + def hash_insert(T, k, h): i = 0 while i < len(T): j = h(k, i) - if T[j] == None: + if T[j] is None: T[j] = k return j else: diff --git a/k_way_merge.py b/k_way_merge.py index c0d13af..1fc0a8a 100644 --- a/k_way_merge.py +++ b/k_way_merge.py @@ -28,7 +28,11 @@ def merge(list1, list2): def k_way_merge(lists): - '''Merge k sorted lists and return it as one sorted list''' + """ + Merge k sorted lists and return it as one sorted list + :param lists: + :return: + """ length = len(lists) if length == 1: return lists[0] diff --git a/linked_list_test.py b/linked_list_test.py index bbe6f4d..06779d2 100644 --- a/linked_list_test.py +++ b/linked_list_test.py @@ -1,15 +1,15 @@ import unittest -from linked_list import linked_list, linked_list_node +from linkedlist import LinkedList, LinkedListNode class TestLinkedList(unittest.TestCase): def test_insert(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) @@ -23,12 +23,12 @@ def test_insert(self): self.assertEqual(l, [e, d, c, b, a]) def test_search(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) @@ -37,12 +37,12 @@ def test_search(self): self.assertEqual(L.search(4), b) def test_delete(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) diff --git a/linkedlist.py b/linkedlist.py index 7fe4130..845c74a 100644 --- a/linkedlist.py +++ b/linkedlist.py @@ -1,4 +1,5 @@ from typing import Any, Optional +import gdb class LinkedListNode: diff --git a/min_heap_with_linked_list.py b/min_heap_with_linked_list.py index 35902ea..33f9ec1 100644 --- a/min_heap_with_linked_list.py +++ b/min_heap_with_linked_list.py @@ -1,4 +1,4 @@ -from linked_list import linked_list_node, linked_list +from linkedlist import LinkedListNode, LinkedList import sys diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py index 432b1a2..440bab1 100644 --- a/min_heap_with_linked_list_test.py +++ b/min_heap_with_linked_list_test.py @@ -1,76 +1,76 @@ import unittest from min_heap_with_linked_list import min_heap, min_priority_queue -from linked_list import linked_list, linked_list_node +from linkedlist import LinkedList, LinkedListNode class TestHeap(unittest.TestCase): def test_min_heapify(self): - L1 = linked_list(1) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) h = min_heap([L5, L1, L2, L3, L4]) h.min_heapify(0) self.assertEqual(h, [L1, L3, L2, L5, L4]) def test_build_min_heap(self): - L1 = linked_list(1) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) h = min_heap([L3, L4, L5, L2, L1]) h.build_min_heap() self.assertEqual(h, [L1, L2, L5, L3, L4]) def test_heap_minimum(self): - L1 = linked_list(1) - L1.insert(linked_list_node(1)) - L1.insert(linked_list_node(1)) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_minimum().key, 1) def test_heap_extract_min(self): - L1 = linked_list(1) - L1.insert(linked_list_node(1)) - L1.insert(linked_list_node(1)) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_extract_min().key, 1) self.assertEqual(q, [L1, L2, L3, L4, L5]) diff --git a/os_tree.py b/os_tree.py index de4ea05..71f2306 100755 --- a/os_tree.py +++ b/os_tree.py @@ -3,7 +3,7 @@ from rb_tree import rb_node, rb_tree -class os_node(rb_node): +class OSNode(rb_node): def __init__(self, key, p, left, right, color, size): rb_node.__init__(self, key, p, left, right, color) self.size = size @@ -55,13 +55,13 @@ def ith_successor(self, i): class os_tree(rb_tree): - nil = os_node(None, None, None, None, 1, 0) + nil = OSNode(None, None, None, None, 1, 0) root = nil def __init__(self, values): if isinstance(values, list): for i in values: - self.insert(os_node(i, None, None, None, 0, 1)) + self.insert(OSNode(i, None, None, None, 0, 1)) else: print("Not invalid argument") diff --git a/os_tree_test.py b/os_tree_test.py index bf84248..36ab2f9 100755 --- a/os_tree_test.py +++ b/os_tree_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env ipython import unittest -from os_tree import os_tree, os_node +from os_tree import os_tree, OSNode class TestOstree(unittest.TestCase): @@ -156,7 +156,7 @@ def test_ith_successor(self): # def test_insert_stack(self): # T = os_tree([]) # for i in 41, 38, 31, 12, 19, 9: - # T.insert_stack(os_node(i, None, None, None, 0)) + # T.insert_stack(OSNode(i, None, None, None, 0)) # self.assertEqual(T.root, T.iterative_tree_search(38)) # self.assertEqual(T.nil.color, 1) # self.wrap(T, 38, 19, 41, -1, 1) diff --git a/polar_angle.py b/polar_angle.py index 67f2b4a..1058ec6 100644 --- a/polar_angle.py +++ b/polar_angle.py @@ -1,33 +1,42 @@ #!/usr/bin/env ipython -from heap import max_heap +from heap import MaxHeap + class vector(object): - def __init__(self, p2, p1 = (0, 0)): + def __init__(self, p2, p1=(0, 0)): self.x = p2[0] - p1[0] self.y = p2[1] - p1[0] + def cross_product(self, v): return self.x * v.y - v.x * self.y + def __lt__(self, v): return self.cross_product(v) > 0 + def __gt__(self, v): return self.cross_product(v) < 0 + def __eq__(self, v): return self.cross_product(v) == 0 + def __le__(self, v): return self.cross_product(v) >= 0 + def __ge__(self, v): return self.cross_product(v) <= 0 + + def polar_angle(p0, point_list): '''sort a sequence of n points according to their polar angles with respect to a given origin point p0. ''' - v0 = vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 + v0 = vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 vector_list = [vector(p, p0) for p in point_list] - angle_0 = [] #list of vectors whose polar angles are 0 - angle_pi = [] #list of vectors whose polar angles are pi - angle_0_pi = [] #list of vectors whose polar angles are larger than 0 and smaller than pi - angle_pi_2pi = [] #list of vectors whose polar angles are larger than pi and smaller than 2pi + angle_0 = [] # list of vectors whose polar angles are 0 + angle_pi = [] # list of vectors whose polar angles are pi + angle_0_pi = [] # list of vectors whose polar angles are larger than 0 and smaller than pi + angle_pi_2pi = [] # list of vectors whose polar angles are larger than pi and smaller than 2pi for v in vector_list: if v == v0: if v.x > 0: @@ -38,8 +47,8 @@ def polar_angle(p0, point_list): angle_pi_2pi.append(v) elif v > v0: angle_0_pi.append(v) - heap_0_pi = max_heap(angle_0_pi) - heap_pi_2pi = max_heap(angle_pi_2pi) + heap_0_pi = MaxHeap(angle_0_pi) + heap_pi_2pi = MaxHeap(angle_pi_2pi) heap_0_pi.heapsort() heap_pi_2pi.heapsort() return [(v.x, v.y) for v in (angle_0 + heap_0_pi + angle_pi + heap_pi_2pi)] diff --git a/polygon_area.py b/polygon_area.py index 262f89c..ea2a9f0 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -1,5 +1,6 @@ #!/usr/bin/env ipython + def polygon_area(P): n = len(P) S = 0 diff --git a/priority_queue.py b/priority_queue.py index 7d9252b..118a370 100644 --- a/priority_queue.py +++ b/priority_queue.py @@ -1,9 +1,11 @@ import sys -from heap import max_heap, min_heap +from heap import MaxHeap, MinHeap -class max_priority_queue(max_heap): + +class MaxPriorityQueue(MaxHeap): def heap_maximum(self): return self[0] + def heap_extract_max(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -12,6 +14,7 @@ def heap_extract_max(self): self.heap_size = self.heap_size - 1 self.max_heapify(0) return maximum + def heap_increase_key(self, i, key): if key < self[i]: sys.exit("new key is smaller than current key") @@ -19,22 +22,27 @@ def heap_increase_key(self, i, key): while i > 0 and self[self.parent(i)] < self[i]: tmp = self[self.parent(i)] self[self.parent(i)] = self[i] - self[i] = tmp + self[i] = tmp i = self.parent(i) + def max_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") self.heap_size = self.heap_size + 1 self[self.heap_size - 1] = float("-Inf") self.heap_increase_key(self.heap_size - 1, key) + def heap_delete(self, i): self.heap_increase_key(i, float("Inf")) self[0], self[self.heap_size - 1] = self[self.heap_size - 1], self[0] self.heap_size = self.heap_size - 1 self.max_heapify(0) -class min_priority_queue(min_heap): + + +class min_priority_queue(MinHeap): def heap_minimum(self): return self[0] + def heap_extract_min(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -43,6 +51,7 @@ def heap_extract_min(self): self.heap_size = self.heap_size - 1 self.min_heapify(0) return minimum + def heap_decrease_key(self, i, key): if key > self[i]: sys.exit("new key is larger than current key") @@ -50,8 +59,9 @@ def heap_decrease_key(self, i, key): while i > 0 and self[self.parent(i)] > self[i]: tmp = self[self.parent(i)] self[self.parent(i)] = self[i] - self[i] = tmp + self[i] = tmp i = self.parent(i) + def min_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") diff --git a/priority_queue_test.py b/priority_queue_test.py index c556694..a5d3b55 100644 --- a/priority_queue_test.py +++ b/priority_queue_test.py @@ -1,39 +1,39 @@ import unittest -from priority_queue import max_priority_queue, min_priority_queue +from priority_queue import MaxPriorityQueue, min_priority_queue class TestMaxPriorityQueue(unittest.TestCase): def test_init(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - q = max_priority_queue(a) + q = MaxPriorityQueue(a) self.assertEqual(q, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) def test_heap_maximum(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - self.assertEqual(max_priority_queue(a).heap_maximum(), 16) + self.assertEqual(MaxPriorityQueue(a).heap_maximum(), 16) def test_heap_extract_max(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) self.assertEqual(h.heap_extract_max(), 16) self.assertEqual(h, [14, 8, 10, 4, 7, 9, 3, 2, 1, 1]) def test_heap_increase_key(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) h.heap_increase_key(8, 15) self.assertEqual(h, [16, 15, 10, 14, 7, 9, 3, 2, 8, 1]) def test_heap_insert(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - queue = max_priority_queue(a) + queue = MaxPriorityQueue(a) queue.heap_extract_max() queue.max_heap_insert(100) self.assertEqual(queue, [100, 14, 10, 4, 8, 9, 3, 2, 1, 7]) def test_heap_delete(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) h.heap_delete(4) self.assertEqual(h[0:h.heap_size], [16, 14, 10, 8, 1, 9, 3, 2, 4]) h.heap_delete(2) diff --git a/queue.py b/queue.py deleted file mode 100644 index 37ad81c..0000000 --- a/queue.py +++ /dev/null @@ -1,42 +0,0 @@ -class FullException(Exception): - def __init__(self): - Exception.__init__(self) - - -class EmptyException(Exception): - def __init__(self): - Exception.__init__(self) - - -class queue(object): - def __init__(self, size): - self.data = [0] * size - self.length = size - self.head = 0 - self.tail = 0 - - def enqueue(self, x): - if self.full(): - raise FullException() - self.data[self.tail] = x - if self.tail == self.length - 1: - self.tail = 0 - else: - self.tail = self.tail + 1 - - def dequeue(self): - if self.empty(): - raise EmptyException() - x = self.data[self.head] - if self.head == self.length - 1: - self.head = 0 - else: - self.head = self.head + 1 - return x - - def empty(self): - return self.tail == self.head - - def full(self): - # print( "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length)) - return (self.tail + 1) % self.length == self.head diff --git a/three_points_colinear.py b/three_points_colinear.py index 00d9274..e8b8b66 100644 --- a/three_points_colinear.py +++ b/three_points_colinear.py @@ -1,6 +1,6 @@ #!/usr/bin/env ipython -from heap import max_heap +from heap import MaxHeap class vector(object): @@ -47,7 +47,7 @@ def three_points_colinear(points_list): for j in range(i + 1, n): vectors_list.append(vector(points_list[i], points_list[j], i, j)) v0 = vector((1, 0), (0, 0)) - heap_vectors = max_heap(vectors_list) + heap_vectors = MaxHeap(vectors_list) heap_vectors.heapsort() status = [False] * n v = heap_vectors[0] diff --git a/wrestlers.py b/wrestlers.py index 19d1d2c..25be93a 100644 --- a/wrestlers.py +++ b/wrestlers.py @@ -1,8 +1,9 @@ -from queue import queue +from Queue import Queue from graph import Graph, Vertex + def wrestlers(wrestlersList, rivalriesList): - ''' + """ There are two types of professional wrestlers: "babyfaces" ("good guys") and "heels" ("bad guys"). Between any pair of professional wrestlers, there may or may not be a rivalry. @@ -11,7 +12,7 @@ def wrestlers(wrestlersList, rivalriesList): possible to designate some of the wrestlers as babyfaces and There remainder as heels such that each rivalry is between a babyfaces and a heel. - ''' + """ d = dict() vertices = [None] * len(wrestlersList) edges = [None] * len(rivalriesList) @@ -28,13 +29,14 @@ def wrestlers(wrestlersList, rivalriesList): u.type = 0 for u in g.vertices: if u.type == 0: - if _bfs(g, u) == False: + if not _bfs(g, u): return False return True + def _bfs(g, s): s.type = 1 - q = queue(2 * len(g.vertices)) + q = Queue(2 * len(g.vertices)) q.enqueue(s) while not q.empty(): u = q.dequeue() From c92f1929a3c2544470916c1e69ab8d20fae30aba Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 6 Apr 2020 16:56:48 +0800 Subject: [PATCH 20/49] move testcase to tests folder --- .idea/.gitignore | 2 + README.md | 2 +- b_tree_test.py => b_tree_example.py | 0 graph.py | 12 +- linkedlist.py | 1 - min_heap_with_linked_list.py | 4 +- min_heap_with_linked_list_test.py | 17 ++- .../Bellman_Ford_matrix_test.py | 0 .../Horner_rule_test.py | 0 Johnson_test.py => tests/Johnson_test.py | 0 .../all_pairs_shortest_paths_test.py | 0 bh_tree_test.py => tests/bh_tree_test.py | 0 .../binary_search_test.py | 0 .../bubble_sort_test.py | 1 - .../constraints_test.py | 0 contains_test.py => tests/contains_test.py | 0 .../counting_sort_test.py | 0 cut_rod_test.py => tests/cut_rod_test.py | 0 .../depth_tree_test.py | 0 .../disjoint_sets_forest_test.py | 0 .../disjoint_sets_test.py | 0 graph_test.py => tests/graph_test.py | 131 ++++++++++++------ .../hamiltonian_path_test.py | 0 heap_test.py => tests/heap_test.py | 0 .../insertion_sort_test.py | 0 .../interval_tree_test.py | 0 inversion_test.py => tests/inversion_test.py | 0 .../k_way_merge_test.py | 0 .../linked_list_test.py | 0 .../longest_common_subsequence_test.py | 0 ...notonically_increasing_subsequence_test.py | 0 .../merge_sort_test.py | 0 .../min_gap_tree_test.py | 0 tests/min_heap_with_linked_list_test.py | 94 +++++++++++++ .../min_priority_queue_using_rb_tree_test.py | 0 .../most_reliable_path_test.py | 0 os_tree_test.py => tests/os_tree_test.py | 0 partition_test.py => tests/partition_test.py | 0 .../pointer_tree_test.py | 0 .../priority_queue_test.py | 0 quicksort_test.py => tests/quicksort_test.py | 0 .../randomized_select_test.py | 0 rank_tree_test.py => tests/rank_tree_test.py | 0 rb_tree_test.py => tests/rb_tree_test.py | 0 .../selection_sort_test.py | 0 two_sum_test.py => tests/two_sum_test.py | 0 .../universal_sink_test.py | 0 vEB_tree_test.py => tests/vEB_tree_test.py | 0 wrestlers_test.py => tests/wrestlers_test.py | 10 +- wrestlers.py | 8 +- 50 files changed, 215 insertions(+), 67 deletions(-) create mode 100644 .idea/.gitignore rename b_tree_test.py => b_tree_example.py (100%) rename Bellman_Ford_matrix_test.py => tests/Bellman_Ford_matrix_test.py (100%) rename Horner_rule_test.py => tests/Horner_rule_test.py (100%) rename Johnson_test.py => tests/Johnson_test.py (100%) rename all_pairs_shortest_paths_test.py => tests/all_pairs_shortest_paths_test.py (100%) rename bh_tree_test.py => tests/bh_tree_test.py (100%) rename binary_search_test.py => tests/binary_search_test.py (100%) rename bubble_sort_test.py => tests/bubble_sort_test.py (99%) rename constraints_test.py => tests/constraints_test.py (100%) rename contains_test.py => tests/contains_test.py (100%) rename counting_sort_test.py => tests/counting_sort_test.py (100%) rename cut_rod_test.py => tests/cut_rod_test.py (100%) rename depth_tree_test.py => tests/depth_tree_test.py (100%) rename disjoint_sets_forest_test.py => tests/disjoint_sets_forest_test.py (100%) rename disjoint_sets_test.py => tests/disjoint_sets_test.py (100%) rename graph_test.py => tests/graph_test.py (84%) rename hamiltonian_path_test.py => tests/hamiltonian_path_test.py (100%) rename heap_test.py => tests/heap_test.py (100%) rename insertion_sort_test.py => tests/insertion_sort_test.py (100%) rename interval_tree_test.py => tests/interval_tree_test.py (100%) rename inversion_test.py => tests/inversion_test.py (100%) rename k_way_merge_test.py => tests/k_way_merge_test.py (100%) rename linked_list_test.py => tests/linked_list_test.py (100%) rename longest_common_subsequence_test.py => tests/longest_common_subsequence_test.py (100%) rename longest_monotonically_increasing_subsequence_test.py => tests/longest_monotonically_increasing_subsequence_test.py (100%) rename merge_sort_test.py => tests/merge_sort_test.py (100%) rename min_gap_tree_test.py => tests/min_gap_tree_test.py (100%) create mode 100644 tests/min_heap_with_linked_list_test.py rename min_priority_queue_using_rb_tree_test.py => tests/min_priority_queue_using_rb_tree_test.py (100%) rename most_reliable_path_test.py => tests/most_reliable_path_test.py (100%) rename os_tree_test.py => tests/os_tree_test.py (100%) rename partition_test.py => tests/partition_test.py (100%) rename pointer_tree_test.py => tests/pointer_tree_test.py (100%) rename priority_queue_test.py => tests/priority_queue_test.py (100%) rename quicksort_test.py => tests/quicksort_test.py (100%) rename randomized_select_test.py => tests/randomized_select_test.py (100%) rename rank_tree_test.py => tests/rank_tree_test.py (100%) rename rb_tree_test.py => tests/rb_tree_test.py (100%) rename selection_sort_test.py => tests/selection_sort_test.py (100%) rename two_sum_test.py => tests/two_sum_test.py (100%) rename universal_sink_test.py => tests/universal_sink_test.py (100%) rename vEB_tree_test.py => tests/vEB_tree_test.py (100%) rename wrestlers_test.py => tests/wrestlers_test.py (60%) diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..e7e9d11 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/README.md b/README.md index 3f2d8c0..784d417 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,4 @@ Since python2 is outdated, the original python2.7 code is moved to python2.7 bra The master branch support python3 only. ## test -test.sh is the shell script to run all the testcases +Run testcase in tests folder diff --git a/b_tree_test.py b/b_tree_example.py similarity index 100% rename from b_tree_test.py rename to b_tree_example.py diff --git a/graph.py b/graph.py index be04060..afc3a27 100644 --- a/graph.py +++ b/graph.py @@ -1,4 +1,4 @@ -from Queue import Queue +from queue import Queue import disjoint_sets_forest as dsf import sys @@ -81,15 +81,15 @@ def bfs(self, s): s.d = 0 s.p = None q = Queue(2 * len(self.vertices)) - q.enqueue(s) + q.put(s) while not q.empty(): - u = q.dequeue() + u = q.get() for v in self.adj[u]: if v.color == 0: v.color = 1 v.d = u.d + 1 v.p = u - q.enqueue(v) + q.put(v) u.color = 2 def dfs(self): @@ -319,7 +319,9 @@ def component_graph_dfs_visit(self, u): st = status[(v.cc, u.cc)] except KeyError: status[(v.cc, u.cc)] = 1 - cg._addEdge(vertices_list[v.cc - 1], vertices_list[u.cc - 1]) + cg._addEdge( + vertices_list[v.cc - 1], + vertices_list[u.cc - 1]) u.color = 2 time = time + 1 u.f = time diff --git a/linkedlist.py b/linkedlist.py index 845c74a..7fe4130 100644 --- a/linkedlist.py +++ b/linkedlist.py @@ -1,5 +1,4 @@ from typing import Any, Optional -import gdb class LinkedListNode: diff --git a/min_heap_with_linked_list.py b/min_heap_with_linked_list.py index 33f9ec1..d23a3a7 100644 --- a/min_heap_with_linked_list.py +++ b/min_heap_with_linked_list.py @@ -2,7 +2,7 @@ import sys -class min_heap(list): +class MinHeap(list): def __init__(self, data): list.__init__(self, data) self.length = len(data) @@ -40,7 +40,7 @@ def build_min_heap(self): self.min_heapify(i) -class min_priority_queue(min_heap): +class MinPriorityQueue(MinHeap): def heap_minimum(self): return self[0].head diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py index 440bab1..b81a39e 100644 --- a/min_heap_with_linked_list_test.py +++ b/min_heap_with_linked_list_test.py @@ -1,6 +1,8 @@ import unittest -from min_heap_with_linked_list import min_heap, min_priority_queue + from linkedlist import LinkedList, LinkedListNode +from min_heap_with_linked_list import MinHeap, MinPriorityQueue + class TestHeap(unittest.TestCase): def test_min_heapify(self): @@ -17,9 +19,10 @@ def test_min_heapify(self): L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) - h = min_heap([L5, L1, L2, L3, L4]) + h = MinHeap([L5, L1, L2, L3, L4]) h.min_heapify(0) self.assertEqual(h, [L1, L3, L2, L5, L4]) + def test_build_min_heap(self): L1 = LinkedList(1) L2 = LinkedList(2) @@ -34,9 +37,10 @@ def test_build_min_heap(self): L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) - h = min_heap([L3, L4, L5, L2, L1]) + h = MinHeap([L3, L4, L5, L2, L1]) h.build_min_heap() self.assertEqual(h, [L1, L2, L5, L3, L4]) + def test_heap_minimum(self): L1 = LinkedList(1) L1.insert(LinkedListNode(1)) @@ -53,8 +57,9 @@ def test_heap_minimum(self): L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) - q = min_priority_queue([L1, L2, L3, L4, L5]) + q = MinPriorityQueue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_minimum().key, 1) + def test_heap_extract_min(self): L1 = LinkedList(1) L1.insert(LinkedListNode(1)) @@ -71,14 +76,14 @@ def test_heap_extract_min(self): L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) L3.insert(LinkedListNode(5)) - q = min_priority_queue([L1, L2, L3, L4, L5]) + q = MinPriorityQueue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_extract_min().key, 1) self.assertEqual(q, [L1, L2, L3, L4, L5]) self.assertEqual(q.heap_extract_min().key, 1) self.assertEqual(q, [L2, L4, L3, L5, L5]) # def test_heap_decrease_key(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) +# q = min_priority_queue(a) # q.heap_decrease_key(8, 1) # self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) # def test_heap_insert(self): diff --git a/Bellman_Ford_matrix_test.py b/tests/Bellman_Ford_matrix_test.py similarity index 100% rename from Bellman_Ford_matrix_test.py rename to tests/Bellman_Ford_matrix_test.py diff --git a/Horner_rule_test.py b/tests/Horner_rule_test.py similarity index 100% rename from Horner_rule_test.py rename to tests/Horner_rule_test.py diff --git a/Johnson_test.py b/tests/Johnson_test.py similarity index 100% rename from Johnson_test.py rename to tests/Johnson_test.py diff --git a/all_pairs_shortest_paths_test.py b/tests/all_pairs_shortest_paths_test.py similarity index 100% rename from all_pairs_shortest_paths_test.py rename to tests/all_pairs_shortest_paths_test.py diff --git a/bh_tree_test.py b/tests/bh_tree_test.py similarity index 100% rename from bh_tree_test.py rename to tests/bh_tree_test.py diff --git a/binary_search_test.py b/tests/binary_search_test.py similarity index 100% rename from binary_search_test.py rename to tests/binary_search_test.py diff --git a/bubble_sort_test.py b/tests/bubble_sort_test.py similarity index 99% rename from bubble_sort_test.py rename to tests/bubble_sort_test.py index 15b5f61..6369e0d 100644 --- a/bubble_sort_test.py +++ b/tests/bubble_sort_test.py @@ -11,4 +11,3 @@ def test_bubble_sort(self): array_copy = array[:] bubble_sort(array) self.assertEqual(array, sorted(array_copy)) - diff --git a/constraints_test.py b/tests/constraints_test.py similarity index 100% rename from constraints_test.py rename to tests/constraints_test.py diff --git a/contains_test.py b/tests/contains_test.py similarity index 100% rename from contains_test.py rename to tests/contains_test.py diff --git a/counting_sort_test.py b/tests/counting_sort_test.py similarity index 100% rename from counting_sort_test.py rename to tests/counting_sort_test.py diff --git a/cut_rod_test.py b/tests/cut_rod_test.py similarity index 100% rename from cut_rod_test.py rename to tests/cut_rod_test.py diff --git a/depth_tree_test.py b/tests/depth_tree_test.py similarity index 100% rename from depth_tree_test.py rename to tests/depth_tree_test.py diff --git a/disjoint_sets_forest_test.py b/tests/disjoint_sets_forest_test.py similarity index 100% rename from disjoint_sets_forest_test.py rename to tests/disjoint_sets_forest_test.py diff --git a/disjoint_sets_test.py b/tests/disjoint_sets_test.py similarity index 100% rename from disjoint_sets_test.py rename to tests/disjoint_sets_test.py diff --git a/graph_test.py b/tests/graph_test.py similarity index 84% rename from graph_test.py rename to tests/graph_test.py index 65b920a..a03e6b7 100644 --- a/graph_test.py +++ b/tests/graph_test.py @@ -19,9 +19,11 @@ def setUp(self): self.v5 = v5 self.v6 = v6 vertices = [v1, v2, v3, v4, v5, v6] - edges = [(v1, v2), (v1, v3), (v2, v3), (v2, v4), (v2, v5), (v3, v4), (v3, v6), (v4, v5), (v5, v6)] + edges = [(v1, v2), (v1, v3), (v2, v3), (v2, v4), (v2, v5), (v3, v4), + (v3, v6), (v4, v5), (v5, v6)] self.graphs.append(Graph(vertices, edges)) - edges = [(v1, v2), (v2, v3), (v3, v4), (v4, v2), (v3, v5), (v2, v4), (v4, v3), (v1, v6)] + edges = [(v1, v2), (v2, v3), (v3, v4), (v4, v2), (v3, v5), (v2, v4), + (v4, v3), (v1, v6)] self.graphs.append(Graph([v1, v2, v3, v4, v5, v6], edges)) def tearDown(self): @@ -51,7 +53,8 @@ def testBfs(self): y = Vertex('y') z = Vertex('z') vertices = [v, r, s, w, t, x, u, y, z] - edges = [(s, r), (s, w), (r, v), (r, s), (v, r), (w, s), (w, t), (w, x), (t, w), (t, x), (t, u), (u, t), (u, x), + edges = [(s, r), (s, w), (r, v), (r, s), (v, r), (w, s), (w, t), + (w, x), (t, w), (t, x), (t, u), (u, t), (u, x), (u, y), (x, w), (x, t), (x, u), (x, y), (y, x), (y, u)] g = Graph(vertices, edges) # g.print(AllEdges()) @@ -78,19 +81,28 @@ def testDfs(self): x = Vertex('x') t = Vertex('t') u = Vertex('u') - # edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] + # edges_list = [(z, w), (s, w), (y, w), + # (x, ), (x, ), (z, ), (v, u), (v, t)] # vertices = (s, v, z, w, y, x, t, u) - # map(lambda vertex, edges: map(lambda vertex, edge: vertex.addEdge(edge), zip([vertex] * len(edges) , edges)), zip(vertices, edges_list)) + # map( + # lambda vertex, edges: + # map(lambda vertex, edge: + # vertex.addEdge(edge), + # zip([vertex] * len(edges) , edges)), + # zip(vertices, edges_list)) vertices = [s, v, z, w, y, x, t, u] - edges = [(y, x), (x, z), (z, y), (z, w), (w, x), (s, z), (s, w), (v, w), (v, s), (t, v), (t, u), (u, v), (u, t)] + edges = [(y, x), (x, z), (z, y), (z, w), (w, x), (s, z), + (s, w), (v, w), (v, s), (t, v), (t, u), (u, v), (u, t)] g = Graph(vertices, edges) g.dfs() vertices = (s, v, z, w, y, x, t, u) # for u in vertices: # print( u, u.d, u.f) - # df = [(1, 10), (12, 13), (2, 9), (7, 8), (3, 6), (4, 5), (11, 16), (14, 15)] - # edges_list = [(z, w), (s, w), (y, w), (x, ), (x, ), (z, ), (v, u), (v, t)] + # df = [(1, 10), (12, 13), (2, 9), (7, 8), + # (3, 6), (4, 5), (11, 16), (14, 15)] + # edges_list = [(z, w), (s, w), (y, w), + # (x, ), (x, ), (z, ), (v, u), (v, t)] def testPathNum(self): m = Vertex('m') n = Vertex('n') @@ -107,8 +119,10 @@ def testPathNum(self): y = Vertex('y') z = Vertex('z') vertices = [m, n, o, p, q, r, s, t, u, v, w, x, y, z] - edges = [(m, q), (m, r), (m, x), (n, q), (n, o), (n, u), (o, r), (o, s), (o, v), (p, o), (p, s), (p, z), (q, t), - (r, u), (r, y), (s, r), (u, t), (v, w), (v, x), (w, z), (y, v)] + edges = [(m, q), (m, r), (m, x), (n, q), (n, o), (n, u), + (o, r), (o, s), (o, v), (p, o), (p, s), (p, z), (q, t), + (r, u), (r, y), (s, r), (u, t), (v, w), + (v, x), (w, z), (y, v)] g = Graph(vertices, edges) self.assertEqual(g.path_num(m, v), 1) self.assertEqual(g.path_num(n, v), 3) @@ -149,7 +163,8 @@ def testSCC(self): g = Vertex('g') h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), + (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) G.strongly_connected_components() self.assertEqual(a.cc, 1) @@ -171,8 +186,11 @@ def testSimplified(self): g = Vertex('g') h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - # edges = [(a, c), (b, a), (d, h), (d, f), (e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] + # edges = [(a, c), (b, a), (d, h), (d, f), (e, a), (a, b), (b, c), + # (d, c), (c, d), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), + # (g, h), (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (b, e), + (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) s = G.simplified() # for u in s.vertices: @@ -185,7 +203,8 @@ def testSimplified(self): e = Vertex('e') f = Vertex('f') vertices = [a, b, c, d, e, f] - edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] + edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), + (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) s = G.simplified() # for u in s.vertices: @@ -202,8 +221,8 @@ def testComponentGraph(self): g = Vertex('g') h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), - (h, h)] + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), + (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) cg = G.component_graph() # print() @@ -217,7 +236,8 @@ def testComponentGraph(self): e = Vertex('e') f = Vertex('f') vertices = [a, b, c, d, e, f] - edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] + edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), + (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) cg = G.component_graph() @@ -236,7 +256,8 @@ def testSemiconnected(self): g = Vertex('g') h = Vertex('h') vertices = [a, b, c, d, e, f, g, h] - edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), + edges = [(e, a), (a, b), (b, c), (d, c), (c, d), (d, h), (b, e), + (e, f), (b, f), (g, f), (f, g), (c, g), (g, h), (h, h)] G = Graph(vertices, edges) self.assertEqual(G.semiconnected(), True) @@ -247,7 +268,8 @@ def testSemiconnected(self): e = Vertex('e') f = Vertex('f') vertices = [a, b, c, d, e, f] - edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (c, e), (b, e), (d, f), (e, f), (f, e)] + edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), + (c, e), (b, e), (d, f), (e, f), (f, e)] G = Graph(vertices, edges) self.assertEqual(G.semiconnected(), True) edges = [(a, b), (b, a), (b, c), (b, d), (c, b), (d, b), (e, f)] @@ -285,8 +307,8 @@ def testCut(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), - (h, i)] + edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), + (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), (h, i)] G = Graph(vertices, edges, directed=False) # weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 2, 1, 8, 7] weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 1, 6, 8, 7] @@ -322,11 +344,14 @@ def testKruskal(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), - (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), + edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), + (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), + (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), + (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), (i, h), (i, g)] G = Graph(vertices, edges) - weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] + weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, + 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] z = dict() for x, y in zip(edges, weight): z[x] = y @@ -349,10 +374,14 @@ def testPrim(self): h = Vertex('h') i = Vertex('i') vertices = [a, b, c, d, e, f, g, h, i] - # edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), (e, f), (f, d), (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), (h, i), (h, g), (i, c), (i, h), (i, g)] - # weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] - edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), - (h, i)] + # edges = [(a, b), (a, h), (b, a), (b, c), (b, h), (c, b), (c, i), + # (c, f), (c, d), (d, c), (d, e), (d, f), (e, d), (e, f), (f, d), + # (f, e), (f, c), (f, g), (g, f), (g, h), (g, i), (h, a), (h, b), + # (h, i), (h, g), (i, c), (i, h), (i, g)] + # weight = [4, 8, 4, 8, 11, 8, 2, 4, 7, 7, 9, 14, 9, 10, 14, 10, 4, 2, + # 2, 1, 6, 8, 11, 7, 1, 2, 7, 6] + edges = [(a, b), (b, c), (b, h), (c, i), (d, c), (e, d), (f, d), + (f, e), (f, c), (g, f), (g, h), (g, i), (h, a), (h, i)] weight = [4, 8, 11, 2, 7, 9, 14, 10, 4, 2, 1, 6, 8, 7] G = Graph(vertices, edges, False) z = dict() @@ -368,7 +397,8 @@ def w(x, y): s = set() for u in G.vertices: s.add((u.p, u)) - # self.assertEqual(s, set([(g, h), (f, g), (None, i), (c, d), (c, f), (i, c), (h, a), (d, e), (a, b)])) + # self.assertEqual(s, set([(g, h), (f, g), (None, i), (c, d), + # (c, f), (i, c), (h, a), (d, e), (a, b)])) def testBellmanFord(self): s = Vertex('s') @@ -377,7 +407,8 @@ def testBellmanFord(self): x = Vertex('x') z = Vertex('z') vertices = [s, t, y, x, z] - edges = [(s, t), (s, y), (t, y), (t, x), (t, z), (y, x), (y, z), (x, t), (z, s), (z, x)] + edges = [(s, t), (s, y), (t, y), (t, x), (t, z), + (y, x), (y, z), (x, t), (z, s), (z, x)] weight = [6, 7, 8, 5, -4, -3, 9, -2, 2, 7] G = Graph(vertices, edges) we = dict() @@ -418,7 +449,8 @@ def w(x, y): y = Vertex('y') z = Vertex('z') vertices = [r, s, t, x, y, z] - edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] + edges = [(r, s), (r, t), (s, t), (s, x), (t, x), + (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) we = dict() @@ -430,7 +462,8 @@ def w(x, y): G.Bellman_Ford_modified(w, s) self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) - self.assertEqual([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) + self.assertEqual([i.d for i in vertices], [ + float("Inf"), 0, 2, 6, 5, 3]) def testTopologicalSort(self): r = Vertex('r') @@ -440,7 +473,8 @@ def testTopologicalSort(self): y = Vertex('y') z = Vertex('z') vertices = [r, s, t, x, y, z] - edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] + edges = [(r, s), (r, t), (s, t), (s, x), (t, x), + (t, y), (t, z), (x, y), (x, z), (y, z)] G = Graph(vertices, edges) l = G.topological_sort() self.assertEqual(l, [r, s, t, x, y, z]) @@ -459,7 +493,8 @@ def testDagShortestPaths(self): y = Vertex('y') z = Vertex('z') vertices = [r, s, t, x, y, z] - edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] + edges = [(r, s), (r, t), (s, t), (s, x), (t, x), + (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) we = dict() @@ -471,7 +506,8 @@ def w(x, y): G.dag_shortest_paths(w, s) self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) - self.assertEqual([i.d for i in vertices], [float("Inf"), 0, 2, 6, 5, 3]) + self.assertEqual([i.d for i in vertices], [ + float("Inf"), 0, 2, 6, 5, 3]) G.dag_shortest_paths(w, r) self.assertEqual([i.p for i in vertices], [None, r, r, t, t, t]) self.assertEqual([i.d for i in vertices], [0, 5, 3, 10, 7, 5]) @@ -498,7 +534,8 @@ def testTotalPathNumber(self): y = Vertex('y') z = Vertex('z') vertices = [r, s, t, x, y, z] - edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] + edges = [(r, s), (r, t), (s, t), (s, x), (t, x), + (t, y), (t, z), (x, y), (x, z), (y, z)] weight = [5, 3, 2, 6, 7, 4, 2, -1, 1, -2] G = Graph(vertices, edges) number = G.total_path_number() @@ -512,7 +549,8 @@ def testDijkstra(self): y = Vertex('y') z = Vertex('z') vertices = [s, t, x, y, z] - edges = [(s, t), (s, y), (t, x), (t, y), (x, z), (y, t), (y, x), (y, z), (z, s), (z, x)] + edges = [(s, t), (s, y), (t, x), (t, y), (x, z), + (y, t), (y, x), (y, z), (z, s), (z, x)] g = Graph(vertices, edges) weight = [10, 5, 1, 2, 4, 3, 9, 2, 7, 6] we = dict() @@ -531,7 +569,8 @@ def w(x, y): y = Vertex('y') z = Vertex('z') vertices = [s, t, x, y, z] - edges = [(s, t), (s, y), (t, x), (t, y), (x, z), (y, t), (y, x), (y, z), (z, s), (z, x)] + edges = [(s, t), (s, y), (t, x), (t, y), (x, z), + (y, t), (y, x), (y, z), (z, s), (z, x)] g = Graph(vertices, edges) weight = [3, 5, 6, 2, 2, 1, 4, 6, 3, 7] we = dict() @@ -555,7 +594,8 @@ def testDijkstraModified(self): y = Vertex('y') z = Vertex('z') vertices = [s, t, x, y, z] - edges = [(s, t), (s, y), (t, x), (t, y), (x, z), (y, t), (y, x), (y, z), (z, s), (z, x)] + edges = [(s, t), (s, y), (t, x), (t, y), (x, z), + (y, t), (y, x), (y, z), (z, s), (z, x)] g = Graph(vertices, edges) weight = [10, 5, 1, 2, 4, 3, 9, 2, 7, 6] we = dict() @@ -574,7 +614,8 @@ def w(x, y): y = Vertex('y') z = Vertex('z') vertices = [s, t, x, y, z] - edges = [(s, t), (s, y), (t, x), (t, y), (x, z), (y, t), (y, x), (y, z), (z, s), (z, x)] + edges = [(s, t), (s, y), (t, x), (t, y), (x, z), + (y, t), (y, x), (y, z), (z, s), (z, x)] g = Graph(vertices, edges) weight = [3, 5, 6, 2, 2, 1, 4, 6, 3, 7] we = dict() @@ -627,7 +668,8 @@ def testUnion(self): G2 = Graph([c, d], [(c, d)], directed=False) G3 = G1.union(G2) self.assertEqual(G3.vertices, {a, b, c, d}) - self.assertEqual(G3.edges, {(a, b), (b, a), (a, c), (c, a), (c, d), (d, c)}) + self.assertEqual( + G3.edges, {(a, b), (b, a), (a, c), (c, a), (c, d), (d, c)}) self.assertEqual(G3.adj[a], {b, c}) self.assertEqual(G3.adj[b], {a}) self.assertEqual(G3.adj[c], {d, a}) @@ -686,12 +728,13 @@ def testMht(self): # a4 = Vertex(4) # a5 = Vertex(5) # vertices = [a1, a2, a3, a4, a5] -# edges = [(a1, a2), (a1, a3), (a1, a5), (a2, a4), (a2, a5), (a3, a2), (a4, a1), (a4, a3), (a5, a4)] +# edges = [(a1, a2), (a1, a3), (a1, a5), (a2, a4), (a2, a5), (a3, a2), +# (a4, a1), (a4, a3), (a5, a4)] # g = Graph(vertices, edges) # weight = [3, 8, -4, 1, 7, 4, 2, -5, 6] # we = dict() # for i,j in zip(edges, weight): -# we[i] = j +# we[i] = j # def w(x, y): -# return we[(x, y)] +# return we[(x, y)] # g.Johnson(w) diff --git a/hamiltonian_path_test.py b/tests/hamiltonian_path_test.py similarity index 100% rename from hamiltonian_path_test.py rename to tests/hamiltonian_path_test.py diff --git a/heap_test.py b/tests/heap_test.py similarity index 100% rename from heap_test.py rename to tests/heap_test.py diff --git a/insertion_sort_test.py b/tests/insertion_sort_test.py similarity index 100% rename from insertion_sort_test.py rename to tests/insertion_sort_test.py diff --git a/interval_tree_test.py b/tests/interval_tree_test.py similarity index 100% rename from interval_tree_test.py rename to tests/interval_tree_test.py diff --git a/inversion_test.py b/tests/inversion_test.py similarity index 100% rename from inversion_test.py rename to tests/inversion_test.py diff --git a/k_way_merge_test.py b/tests/k_way_merge_test.py similarity index 100% rename from k_way_merge_test.py rename to tests/k_way_merge_test.py diff --git a/linked_list_test.py b/tests/linked_list_test.py similarity index 100% rename from linked_list_test.py rename to tests/linked_list_test.py diff --git a/longest_common_subsequence_test.py b/tests/longest_common_subsequence_test.py similarity index 100% rename from longest_common_subsequence_test.py rename to tests/longest_common_subsequence_test.py diff --git a/longest_monotonically_increasing_subsequence_test.py b/tests/longest_monotonically_increasing_subsequence_test.py similarity index 100% rename from longest_monotonically_increasing_subsequence_test.py rename to tests/longest_monotonically_increasing_subsequence_test.py diff --git a/merge_sort_test.py b/tests/merge_sort_test.py similarity index 100% rename from merge_sort_test.py rename to tests/merge_sort_test.py diff --git a/min_gap_tree_test.py b/tests/min_gap_tree_test.py similarity index 100% rename from min_gap_tree_test.py rename to tests/min_gap_tree_test.py diff --git a/tests/min_heap_with_linked_list_test.py b/tests/min_heap_with_linked_list_test.py new file mode 100644 index 0000000..b81a39e --- /dev/null +++ b/tests/min_heap_with_linked_list_test.py @@ -0,0 +1,94 @@ +import unittest + +from linkedlist import LinkedList, LinkedListNode +from min_heap_with_linked_list import MinHeap, MinPriorityQueue + + +class TestHeap(unittest.TestCase): + def test_min_heapify(self): + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + h = MinHeap([L5, L1, L2, L3, L4]) + h.min_heapify(0) + self.assertEqual(h, [L1, L3, L2, L5, L4]) + + def test_build_min_heap(self): + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + h = MinHeap([L3, L4, L5, L2, L1]) + h.build_min_heap() + self.assertEqual(h, [L1, L2, L5, L3, L4]) + + def test_heap_minimum(self): + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + q = MinPriorityQueue([L1, L2, L3, L4, L5]) + self.assertEqual(q.heap_minimum().key, 1) + + def test_heap_extract_min(self): + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + q = MinPriorityQueue([L1, L2, L3, L4, L5]) + self.assertEqual(q.heap_extract_min().key, 1) + self.assertEqual(q, [L1, L2, L3, L4, L5]) + self.assertEqual(q.heap_extract_min().key, 1) + self.assertEqual(q, [L2, L4, L3, L5, L5]) +# def test_heap_decrease_key(self): +# a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] +# q = min_priority_queue(a) +# q.heap_decrease_key(8, 1) +# self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) +# def test_heap_insert(self): +# a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] +# q = min_priority_queue(a) +# q.heap_extract_min() +# q.min_heap_insert(0) +# self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/min_priority_queue_using_rb_tree_test.py b/tests/min_priority_queue_using_rb_tree_test.py similarity index 100% rename from min_priority_queue_using_rb_tree_test.py rename to tests/min_priority_queue_using_rb_tree_test.py diff --git a/most_reliable_path_test.py b/tests/most_reliable_path_test.py similarity index 100% rename from most_reliable_path_test.py rename to tests/most_reliable_path_test.py diff --git a/os_tree_test.py b/tests/os_tree_test.py similarity index 100% rename from os_tree_test.py rename to tests/os_tree_test.py diff --git a/partition_test.py b/tests/partition_test.py similarity index 100% rename from partition_test.py rename to tests/partition_test.py diff --git a/pointer_tree_test.py b/tests/pointer_tree_test.py similarity index 100% rename from pointer_tree_test.py rename to tests/pointer_tree_test.py diff --git a/priority_queue_test.py b/tests/priority_queue_test.py similarity index 100% rename from priority_queue_test.py rename to tests/priority_queue_test.py diff --git a/quicksort_test.py b/tests/quicksort_test.py similarity index 100% rename from quicksort_test.py rename to tests/quicksort_test.py diff --git a/randomized_select_test.py b/tests/randomized_select_test.py similarity index 100% rename from randomized_select_test.py rename to tests/randomized_select_test.py diff --git a/rank_tree_test.py b/tests/rank_tree_test.py similarity index 100% rename from rank_tree_test.py rename to tests/rank_tree_test.py diff --git a/rb_tree_test.py b/tests/rb_tree_test.py similarity index 100% rename from rb_tree_test.py rename to tests/rb_tree_test.py diff --git a/selection_sort_test.py b/tests/selection_sort_test.py similarity index 100% rename from selection_sort_test.py rename to tests/selection_sort_test.py diff --git a/two_sum_test.py b/tests/two_sum_test.py similarity index 100% rename from two_sum_test.py rename to tests/two_sum_test.py diff --git a/universal_sink_test.py b/tests/universal_sink_test.py similarity index 100% rename from universal_sink_test.py rename to tests/universal_sink_test.py diff --git a/vEB_tree_test.py b/tests/vEB_tree_test.py similarity index 100% rename from vEB_tree_test.py rename to tests/vEB_tree_test.py diff --git a/wrestlers_test.py b/tests/wrestlers_test.py similarity index 60% rename from wrestlers_test.py rename to tests/wrestlers_test.py index 78cf83c..20d545b 100644 --- a/wrestlers_test.py +++ b/tests/wrestlers_test.py @@ -2,12 +2,16 @@ import unittest from wrestlers import wrestlers + class TestWrestler(unittest.TestCase): def testBfs(self): wrestlersList = [1, 2, 3, 4, 5, 6, 7, 8] - rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), (5, 6), (5, 7), (5, 8), (6, 8), (7, 8)] + rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), + (5, 6), (5, 7), (5, 8), (6, 8), (7, 8)] self.assertEqual(wrestlers(wrestlersList, rivalriesList), False) - rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), (5, 7), (5, 8), (6, 8), (7, 8)] + rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), + (3, 6), (5, 7), (5, 8), (6, 8), (7, 8)] self.assertEqual(wrestlers(wrestlersList, rivalriesList), False) - rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), (3, 6), (5, 7), (5, 8), (6, 8)] + rivalriesList = [(1, 2), (1, 3), (2, 4), (3, 5), + (3, 6), (5, 7), (5, 8), (6, 8)] self.assertEqual(wrestlers(wrestlersList, rivalriesList), True) diff --git a/wrestlers.py b/wrestlers.py index 25be93a..fca182c 100644 --- a/wrestlers.py +++ b/wrestlers.py @@ -1,4 +1,4 @@ -from Queue import Queue +from queue import Queue from graph import Graph, Vertex @@ -37,9 +37,9 @@ def wrestlers(wrestlersList, rivalriesList): def _bfs(g, s): s.type = 1 q = Queue(2 * len(g.vertices)) - q.enqueue(s) + q.put(s) while not q.empty(): - u = q.dequeue() + u = q.get() for v in g.adj[u]: if u.type == v.type: return False @@ -48,5 +48,5 @@ def _bfs(g, s): v.type = 2 else: v.type = 1 - q.enqueue(v) + q.put(v) return True From 11bc7f4ae6218147c779eb3f0362c7de041dd866 Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 6 Apr 2020 17:24:41 +0800 Subject: [PATCH 21/49] debug --- linkedlist.py | 3 +- min_heap_with_linked_list_test.py | 94 ------------------------------- test.sh | 1 - 3 files changed, 2 insertions(+), 96 deletions(-) delete mode 100644 min_heap_with_linked_list_test.py delete mode 100644 test.sh diff --git a/linkedlist.py b/linkedlist.py index 7fe4130..a4d9b41 100644 --- a/linkedlist.py +++ b/linkedlist.py @@ -9,9 +9,10 @@ def __init__(self, key: Any): class LinkedList: - def __init__(self): + def __init__(self, key=None): self.head: Optional[LinkedListNode] = None self.size: int = 0 + self.key = key def empty(self) -> bool: return self.size == 0 diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py deleted file mode 100644 index b81a39e..0000000 --- a/min_heap_with_linked_list_test.py +++ /dev/null @@ -1,94 +0,0 @@ -import unittest - -from linkedlist import LinkedList, LinkedListNode -from min_heap_with_linked_list import MinHeap, MinPriorityQueue - - -class TestHeap(unittest.TestCase): - def test_min_heapify(self): - L1 = LinkedList(1) - L2 = LinkedList(2) - L2.insert(LinkedListNode(2)) - L2.insert(LinkedListNode(2)) - L3 = LinkedList(3) - L3.insert(LinkedListNode(3)) - L3.insert(LinkedListNode(3)) - L4 = LinkedList(4) - L4.insert(LinkedListNode(4)) - L5 = LinkedList(5) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - h = MinHeap([L5, L1, L2, L3, L4]) - h.min_heapify(0) - self.assertEqual(h, [L1, L3, L2, L5, L4]) - - def test_build_min_heap(self): - L1 = LinkedList(1) - L2 = LinkedList(2) - L2.insert(LinkedListNode(2)) - L2.insert(LinkedListNode(2)) - L3 = LinkedList(3) - L3.insert(LinkedListNode(3)) - L3.insert(LinkedListNode(3)) - L4 = LinkedList(4) - L4.insert(LinkedListNode(4)) - L5 = LinkedList(5) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - h = MinHeap([L3, L4, L5, L2, L1]) - h.build_min_heap() - self.assertEqual(h, [L1, L2, L5, L3, L4]) - - def test_heap_minimum(self): - L1 = LinkedList(1) - L1.insert(LinkedListNode(1)) - L1.insert(LinkedListNode(1)) - L2 = LinkedList(2) - L2.insert(LinkedListNode(2)) - L2.insert(LinkedListNode(2)) - L3 = LinkedList(3) - L3.insert(LinkedListNode(3)) - L3.insert(LinkedListNode(3)) - L4 = LinkedList(4) - L4.insert(LinkedListNode(4)) - L5 = LinkedList(5) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - q = MinPriorityQueue([L1, L2, L3, L4, L5]) - self.assertEqual(q.heap_minimum().key, 1) - - def test_heap_extract_min(self): - L1 = LinkedList(1) - L1.insert(LinkedListNode(1)) - L1.insert(LinkedListNode(1)) - L2 = LinkedList(2) - L2.insert(LinkedListNode(2)) - L2.insert(LinkedListNode(2)) - L3 = LinkedList(3) - L3.insert(LinkedListNode(3)) - L3.insert(LinkedListNode(3)) - L4 = LinkedList(4) - L4.insert(LinkedListNode(4)) - L5 = LinkedList(5) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - L3.insert(LinkedListNode(5)) - q = MinPriorityQueue([L1, L2, L3, L4, L5]) - self.assertEqual(q.heap_extract_min().key, 1) - self.assertEqual(q, [L1, L2, L3, L4, L5]) - self.assertEqual(q.heap_extract_min().key, 1) - self.assertEqual(q, [L2, L4, L3, L5, L5]) -# def test_heap_decrease_key(self): -# a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) -# q.heap_decrease_key(8, 1) -# self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) -# def test_heap_insert(self): -# a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) -# q.heap_extract_min() -# q.min_heap_insert(0) -# self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/test.sh b/test.sh deleted file mode 100644 index 09612dd..0000000 --- a/test.sh +++ /dev/null @@ -1 +0,0 @@ -for f in $(ls *test.py | cut -d '.' -f1); do python3 -m unittest $f;done From a580f28c4890f8643b5012228c0b07b7285ce400 Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 6 Apr 2020 17:40:47 +0800 Subject: [PATCH 22/49] split long lines --- polar_angle.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/polar_angle.py b/polar_angle.py index 1058ec6..fe52378 100644 --- a/polar_angle.py +++ b/polar_angle.py @@ -3,7 +3,7 @@ from heap import MaxHeap -class vector(object): +class Vector(object): def __init__(self, p2, p1=(0, 0)): self.x = p2[0] - p1[0] self.y = p2[1] - p1[0] @@ -31,12 +31,15 @@ def polar_angle(p0, point_list): '''sort a sequence of n points according to their polar angles with respect to a given origin point p0. ''' - v0 = vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 - vector_list = [vector(p, p0) for p in point_list] + v0 = Vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 + vector_list = [Vector(p, p0) for p in point_list] angle_0 = [] # list of vectors whose polar angles are 0 angle_pi = [] # list of vectors whose polar angles are pi - angle_0_pi = [] # list of vectors whose polar angles are larger than 0 and smaller than pi - angle_pi_2pi = [] # list of vectors whose polar angles are larger than pi and smaller than 2pi + # list of vectors whose polar angles are larger than 0 and smaller than pi + angle_0_pi = [] + # list of vectors whose polar angles are larger than pi and + # smaller than 2pi + angle_pi_2pi = [] for v in vector_list: if v == v0: if v.x > 0: From 8d91b88eec3a01743474ab933a7dfc978d97e434 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 2 Jan 2021 00:39:01 +0800 Subject: [PATCH 23/49] change ipython to python --- any_disks_intersect.py | 2 +- any_segments_intersect.py | 38 ++++++++++++++++--- automaton_string_match.py | 2 +- b_tree.py | 2 +- b_tree_example.py | 2 +- bh_tree.py | 2 +- closest_points.py | 13 ++++++- closest_points_l1_distance.py | 13 ++++++- closest_points_l_infinite_distance.py | 2 +- comparable.py | 2 +- contains.py | 2 +- depth_tree.py | 2 +- disjoint_sets_forest.py | 2 +- disjoint_sets_linked_list.py | 10 ++++- fft.py | 2 +- hamiltonian_path.py | 7 ++-- hash.py | 2 +- interpolation.py | 2 +- interval_tree.py | 8 ++-- kleene_star.py | 3 +- kth-Quantiles.py | 2 +- matrix_chain_order.py | 5 ++- min_gap_tree.py | 38 +++++++++++++------ os_tree.py | 2 +- pointer_tree.py | 16 +++++--- polar_angle.py | 2 +- polygon_area.py | 2 +- rank_tree.py | 2 +- rb_tree.py | 2 +- right_horizontal_ray_intersect.py | 6 ++- segment_intersect.py | 2 +- simplex.py | 2 +- single_edge.py | 2 +- synthetic_division.py | 2 +- tests/__init__.py | 0 tests/bh_tree_test.py | 2 +- tests/binary_search_test.py | 2 +- tests/bubble_sort_test.py | 2 +- tests/contains_test.py | 8 ++-- tests/cut_rod_test.py | 29 +++++++++----- tests/depth_tree_test.py | 2 +- tests/disjoint_sets_forest_test.py | 8 ++-- tests/disjoint_sets_test.py | 2 +- tests/graph_test.py | 2 +- tests/hamiltonian_path_test.py | 2 +- tests/insertion_sort_test.py | 5 ++- tests/interval_tree_test.py | 8 ++-- tests/k_way_merge_test.py | 2 +- tests/longest_common_subsequence_test.py | 2 +- tests/merge_sort_test.py | 2 +- tests/min_gap_tree_test.py | 2 +- .../min_priority_queue_using_rb_tree_test.py | 2 +- tests/os_tree_test.py | 11 ++++-- tests/pointer_tree_test.py | 8 ++-- tests/rank_tree_test.py | 11 ++++-- tests/rb_tree_test.py | 11 ++++-- tests/test_gcd.py | 12 ++++++ tests/vEB_tree_test.py | 2 +- tests/wrestlers_test.py | 2 +- three_points_colinear.py | 2 +- tree.py | 2 +- universal_sink.py | 4 +- vEB_tree.py | 14 ++++--- 63 files changed, 246 insertions(+), 118 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_gcd.py diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 130d450..5938d7d 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python # we use 0 to mean red, 1 to mean black diff --git a/any_segments_intersect.py b/any_segments_intersect.py index ffa2888..a17367d 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python # we use 0 to mean red, 1 to mean black @@ -6,8 +6,11 @@ from heap import MaxHeap from segment_intersect import segments_intersect + def vertical(a): return a[0][0] == a[1][0] + + def comparable(a, b, x): '''Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical ''' p1 = a[0] @@ -43,7 +46,8 @@ def comparable(a, b, x): return False else: v1 = (p2[0] - p1[0], p2[1] - p1[1]) - v2 = ((x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]), (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1])) + v2 = ((x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]), + (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1])) result = v1[0] * v2[1] - v2[0] * v1[1] # a is above b if result >= 0: @@ -51,20 +55,27 @@ def comparable(a, b, x): # a is below b else: return False + + class segment(tuple): def __init__(self, seg): super(segment, self).__init__(seg) self.pointer = None + + class point(list): def __init__(self, info, segment): super(point, self).__init__(info) self.segment = segment + + class rb_node(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color if key != None: key.pointer = self + def minimum(self, nil): x = self y = x @@ -72,16 +83,21 @@ def minimum(self, nil): y = x x = x.left return y + def maximum(self, nil): x = self while x.right != nil: x = x.right return x + + class rb_tree(Tree): nil = rb_node(None, None, None, None, 1) root = nil + def __init__(self): pass + def above(self, s): x = s.pointer if x.right != self.nil: @@ -90,6 +106,7 @@ def above(self, s): while x.p != self.nil and x.p.right == x: x = x.p return x.p.key + def below(self, s): x = s.pointer if x.left != self.nil: @@ -98,10 +115,13 @@ def below(self, s): while x.p != self.nil and x.p.left == x: x = x.p return x.p.key + def minimum(self): return self.root.minimum(self.nil) + def __getitem__(self, key): return self.iterative_tree_search(key) + def left_rotate(self, x): y = x.right x.right = y.left @@ -116,6 +136,7 @@ def left_rotate(self, x): x.p.right = y y.left = x x.p = y + def right_rotate(self, y): x = y.left y.left = x.right @@ -130,6 +151,7 @@ def right_rotate(self, y): y.p.left = x x.right = y y.p = x + def insert(self, z): ''' the segment z will only be inserted when the left endpoint of z is being processed''' # this is the x_coordinate of the left endpoint of z @@ -152,8 +174,9 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red self.insert_fixed(z) + def insert_fixed(self, z): while z.p.color == 0: if z.p.p.left == z.p: @@ -187,6 +210,7 @@ def insert_fixed(self, z): z.color = 0 z.p.color = 1 self.root.color = 1 + def transplant(self, u, v): if u.p == self.nil: self.root = v @@ -195,6 +219,7 @@ def transplant(self, u, v): else: u.p.right = v v.p = u.p + def delete(self, z): z = z.pointer y = z @@ -221,6 +246,7 @@ def delete(self, z): y.color = z.color if y_original_color == 1: self.delete_fixup(x) + def delete_fixup(self, x): while x != self.root and x.color == 1: if x == x.p.left: @@ -266,6 +292,8 @@ def delete_fixup(self, x): self.right_rotate(x.p) x = self.root x.color = 1 + + def any_segments_intersect(S): '''This algorithm takes as input a set S of n line segments, returning the boolean value TRUE if any pair of segments in S intersects, and FALSE otherwise.''' T = rb_tree() @@ -274,8 +302,8 @@ def any_segments_intersect(S): for s in S: segment_list.append(segment(s)) for s in segment_list: - point_list.append(point([s[0][0], 0, s[0][1]], s)) - point_list.append(point([s[1][0], 1, s[1][1]], s)) + point_list.append(point([s[0][0], 0, s[0][1]], s)) + point_list.append(point([s[1][0], 1, s[1][1]], s)) heap_point = MaxHeap(point_list) heap_point.heapsort() for p in heap_point: diff --git a/automaton_string_match.py b/automaton_string_match.py index 1fc2118..7de7ac1 100644 --- a/automaton_string_match.py +++ b/automaton_string_match.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def finite_automaton_matcher(T, s, m): diff --git a/b_tree.py b/b_tree.py index 6056654..11d3496 100644 --- a/b_tree.py +++ b/b_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python class b_tree_node(object): diff --git a/b_tree_example.py b/b_tree_example.py index f271526..a6d0cfd 100755 --- a/b_tree_example.py +++ b/b_tree_example.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import b_tree as bt diff --git a/bh_tree.py b/bh_tree.py index 6685618..4e916c3 100644 --- a/bh_tree.py +++ b/bh_tree.py @@ -1,5 +1,5 @@ # A variant of red black tree that has black_height attribute -# !/usr/bin/env ipython +# !/usr/bin/env python from rb_tree import rb_node, rb_tree diff --git a/closest_points.py b/closest_points.py index 123c264..7aec8da 100644 --- a/closest_points.py +++ b/closest_points.py @@ -1,12 +1,15 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from math import ceil, sqrt from heap import MaxHeap + def x_sort(S): X = MaxHeap(S) X.heapsort() return X + + def y_sort(S): Y = [] for p in S: @@ -17,8 +20,12 @@ def y_sort(S): for i in range(0, len(YY)): Y.append((YY[i][1], YY[i][0])) return Y + + def distance(p1, p2): return sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2) + + def brute_force(P): P = list(P) d = float("Inf") @@ -26,10 +33,14 @@ def brute_force(P): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d + + def closest_points(S): X = x_sort(S) Y = y_sort(S) return closest_points_aux(S, X, Y) + + def closest_points_aux(P, X, Y): length = len(P) half = int(ceil(length / 2)) diff --git a/closest_points_l1_distance.py b/closest_points_l1_distance.py index 6f20902..4a2bf7c 100644 --- a/closest_points_l1_distance.py +++ b/closest_points_l1_distance.py @@ -1,12 +1,15 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from math import ceil, sqrt from heap import MaxHeap + def x_sort(S): X = MaxHeap(S) X.heapsort() return X + + def y_sort(S): Y = [] for p in S: @@ -17,8 +20,12 @@ def y_sort(S): for i in range(0, len(YY)): Y.append((YY[i][1], YY[i][0])) return Y + + def distance(p1, p2): return abs(p1[0] - p2[0]) + abs(p1[1] - p2[1]) + + def brute_force(P): P = list(P) d = float("Inf") @@ -26,10 +33,14 @@ def brute_force(P): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d + + def closest_points(S): X = x_sort(S) Y = y_sort(S) return closest_points_aux(S, X, Y) + + def closest_points_aux(P, X, Y): length = len(P) half = int(ceil(length / 2)) diff --git a/closest_points_l_infinite_distance.py b/closest_points_l_infinite_distance.py index 5559e94..e1e00eb 100644 --- a/closest_points_l_infinite_distance.py +++ b/closest_points_l_infinite_distance.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from math import ceil, sqrt from heap import MaxHeap diff --git a/comparable.py b/comparable.py index 31f1461..87307e1 100644 --- a/comparable.py +++ b/comparable.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def comparable(a, b, x): """ diff --git a/contains.py b/contains.py index c65d90c..87b3fa4 100644 --- a/contains.py +++ b/contains.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def contains(x, n): """ diff --git a/depth_tree.py b/depth_tree.py index 7feb09e..c69b2d3 100644 --- a/depth_tree.py +++ b/depth_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python # A variant of red black tree that has depth attribute diff --git a/disjoint_sets_forest.py b/disjoint_sets_forest.py index 28f5ee7..1d42623 100644 --- a/disjoint_sets_forest.py +++ b/disjoint_sets_forest.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python class node(object): diff --git a/disjoint_sets_linked_list.py b/disjoint_sets_linked_list.py index af279c0..072631a 100644 --- a/disjoint_sets_linked_list.py +++ b/disjoint_sets_linked_list.py @@ -1,12 +1,14 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python class node(object): def __init__(self, key): self.key = key self.set = None self.next = None + def find_set(self): return self.set.head + def union(self, y): if self.set.length < y.set.length: x = y @@ -23,12 +25,16 @@ def union(self, y): xs.tail = ys.tail xs.length = xs.length + ys.length return x + + class header(object): def __init__(self, element): self.length = 1 self.head = element element.set = self self.tail = self.head + + class node_notail(node): def union(self, y): if self.set.length < y.set.length: @@ -47,6 +53,8 @@ def union(self, y): xs.head = ys.head xs.length = xs.length + ys.length return y + + class header_notail(object): def __init__(self, element): self.length = 1 diff --git a/fft.py b/fft.py index 69db33a..46b2393 100644 --- a/fft.py +++ b/fft.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import math diff --git a/hamiltonian_path.py b/hamiltonian_path.py index 019db66..e02e201 100644 --- a/hamiltonian_path.py +++ b/hamiltonian_path.py @@ -1,12 +1,13 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def hamiltonian_path(G, u, v): '''An algorithm to the hamiltonian-path problem on directed acyclic graphs''' we = dict() for i in G.edges: - we[i] = -1 + we[i] = -1 + def w(x, y): - return we[(x, y)] + return we[(x, y)] G.dag_shortest_paths(w, u) if abs(v.d) == len(G.vertices) - 1: return True diff --git a/hash.py b/hash.py index 9e547b4..f5cb46f 100755 --- a/hash.py +++ b/hash.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def hash_insert(T, k, h): diff --git a/interpolation.py b/interpolation.py index 956798b..97e7f76 100644 --- a/interpolation.py +++ b/interpolation.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import synthetic_division as di diff --git a/interval_tree.py b/interval_tree.py index c3e6b64..2ddb448 100755 --- a/interval_tree.py +++ b/interval_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from rb_tree import rb_node, rb_tree @@ -47,7 +47,8 @@ class interval_tree(rb_tree): def __init__(self, intervals): if isinstance(intervals, list): for i in intervals: - self.insert(interval_node(i.low, None, None, None, 0, i, i.high)) + self.insert(interval_node( + i.low, None, None, None, 0, i, i.high)) else: print("Not invalid argument") @@ -133,7 +134,8 @@ def delete(self, z): y.color = z.color traverse = x.p while traverse != self.nil: - traverse.maximum = max(traverse.left.maximum, traverse.interval.high, traverse.right.maximum) + traverse.maximum = max( + traverse.left.maximum, traverse.interval.high, traverse.right.maximum) traverse = traverse.p if y_original_color == 1: self.delete_fixup(x) diff --git a/kleene_star.py b/kleene_star.py index 8a21a21..8cd4ff9 100644 --- a/kleene_star.py +++ b/kleene_star.py @@ -1,7 +1,8 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from numpy import zeros + def kleene_star(x, L, A): length = len(x) m = zeros((length, length)) diff --git a/kth-Quantiles.py b/kth-Quantiles.py index 8d7c0bb..d24053f 100755 --- a/kth-Quantiles.py +++ b/kth-Quantiles.py @@ -1,4 +1,4 @@ -#! /usr/bin/env ipython +#! /usr/bin/env python import math import random diff --git a/matrix_chain_order.py b/matrix_chain_order.py index 5de6f1e..e32d7ab 100644 --- a/matrix_chain_order.py +++ b/matrix_chain_order.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from numpy import zeros @@ -35,7 +35,8 @@ def lookup_chain(m, p, i, j): m[i, j] = 0 else: for k in range(i, j): - q = lookup_chain(m, p, i, k) + lookup_chain(m, p, k + 1, j) + p[i - 1] * p[k] * p[j] + q = lookup_chain(m, p, i, k) + lookup_chain(m, p, + k + 1, j) + p[i - 1] * p[k] * p[j] if q < m[i, j]: m[i, j] = q return m[i, j] diff --git a/min_gap_tree.py b/min_gap_tree.py index 77d4925..afc7157 100644 --- a/min_gap_tree.py +++ b/min_gap_tree.py @@ -1,22 +1,29 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from rb_tree import rb_node, rb_tree + class min_gap_node(rb_node): def __init__(self, key, p, left, right, color, successor, min_gap): rb_node.__init__(self, key, p, left, right, color) self.successor = successor self.min_gap = min_gap + + class min_gap_tree(rb_tree): - positive_infinity = min_gap_node(float("Inf"), None, None, None, 1, None, float("Inf")) - nil = min_gap_node(None, None, None, None, 1, positive_infinity, float("Inf")) + positive_infinity = min_gap_node( + float("Inf"), None, None, None, 1, None, float("Inf")) + nil = min_gap_node(None, None, None, None, 1, + positive_infinity, float("Inf")) root = nil + def __init__(self, values): if isinstance(values, list): for i in values: self.insert(min_gap_node(i, None, None, None, 0, None, None)) else: - print( "Not invalid argument") + print("Not invalid argument") + def insert(self, z): y = self.nil x = self.root @@ -43,12 +50,14 @@ def insert(self, z): z.p = y z.left = self.nil z.right = self.nil - z.color = 0 #red + z.color = 0 # red traverse = z while traverse != self.nil: - traverse.min_gap = min(traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) + traverse.min_gap = min( + traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) traverse = traverse.p self.insert_fixed(z) + def delete(self, z): traverse = self.predecessor(z) y = z @@ -73,17 +82,20 @@ def delete(self, z): y.left = z.left y.left.p = y y.color = z.color - # After we delete z, the only nodes whose successor attributes need to be updated are z's successor and z's predecessor + # After we delete z, the only nodes whose successor attributes need to be updated are z's successor and z's predecessor traverse.successor = z.successor while traverse != self.nil: - traverse.min_gap = min(traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) + traverse.min_gap = min( + traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) traverse = traverse.p traverse = x.p while traverse != self.nil: - traverse.min_gap = min(traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) + traverse.min_gap = min( + traverse.left.min_gap, traverse.successor.key - traverse.key, traverse.right.min_gap) traverse = traverse.p if y_original_color == 1: self.delete_fixup(x) + def left_rotate(self, x): y = x.right x.right = y.left @@ -99,7 +111,9 @@ def left_rotate(self, x): y.left = x x.p = y y.min_gap = x.min_gap - x.min_gap = min(x.left.min_gap, x.successor.key - x.key, x.right.min_gap) + x.min_gap = min(x.left.min_gap, x.successor.key - + x.key, x.right.min_gap) + def right_rotate(self, y): x = y.left y.left = x.right @@ -115,7 +129,9 @@ def right_rotate(self, y): x.right = y y.p = x x.min_gap = y.min_gap - y.min_gap = min(y.left.min_gap, y.successor.key - y.key, y.right.min_gap) + y.min_gap = min(y.left.min_gap, y.successor.key - + y.key, y.right.min_gap) + def predecessor(self, x): if x.left != self.nil: return x.left.maximum() diff --git a/os_tree.py b/os_tree.py index 71f2306..45cbc07 100755 --- a/os_tree.py +++ b/os_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from rb_tree import rb_node, rb_tree diff --git a/pointer_tree.py b/pointer_tree.py index 72ad12d..01df858 100644 --- a/pointer_tree.py +++ b/pointer_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from rb_tree import rb_node, rb_tree @@ -13,15 +13,19 @@ def __init__(self, key, p, left, right, color, minimum, maximum, predecessor, su class pointer_tree(rb_tree): - negative_infinity = pointer_node(float("-Inf"), None, None, None, 1, None, None, None, None) - positive_infinity = pointer_node(float("Inf"), None, None, None, 1, None, None, None, None) - nil = pointer_node(None, None, None, None, 1, negative_infinity, positive_infinity, None, None) + negative_infinity = pointer_node( + float("-Inf"), None, None, None, 1, None, None, None, None) + positive_infinity = pointer_node( + float("Inf"), None, None, None, 1, None, None, None, None) + nil = pointer_node(None, None, None, None, 1, + negative_infinity, positive_infinity, None, None) root = nil def __init__(self, values): if isinstance(values, list): for i in values: - self.insert(pointer_node(i, None, None, None, 0, None, None, None, None)) + self.insert(pointer_node(i, None, None, + None, 0, None, None, None, None)) else: print("Not invalid argument") @@ -132,7 +136,7 @@ def delete(self, z): y.left = z.left y.left.p = y y.color = z.color - # After we delete z, the only nodes whose predecessor and successor attributes need to be updated are z's successor and z's predecessor + # After we delete z, the only nodes whose predecessor and successor attributes need to be updated are z's successor and z's predecessor z.predecessor.successor = z.successor z.successor.predecessor = z.predecessor traverse = x.p diff --git a/polar_angle.py b/polar_angle.py index fe52378..fbdf2b5 100644 --- a/polar_angle.py +++ b/polar_angle.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from heap import MaxHeap diff --git a/polygon_area.py b/polygon_area.py index ea2a9f0..c793f27 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def polygon_area(P): diff --git a/rank_tree.py b/rank_tree.py index 3ba8f09..ea48257 100644 --- a/rank_tree.py +++ b/rank_tree.py @@ -1,5 +1,5 @@ # The variant of os_tree that use rank instead of size -# !/usr/bin/env ipython +# !/usr/bin/env python from rb_tree import rb_node, rb_tree diff --git a/rb_tree.py b/rb_tree.py index e7ec3e0..aaa9153 100644 --- a/rb_tree.py +++ b/rb_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python # we use 0 to mean red, 1 to mean black diff --git a/right_horizontal_ray_intersect.py b/right_horizontal_ray_intersect.py index 9ba42d5..9316ffb 100644 --- a/right_horizontal_ray_intersect.py +++ b/right_horizontal_ray_intersect.py @@ -1,7 +1,8 @@ -#!/usr/bin/ipython +#!/usr/bin/python from segment_intersect import segments_intersect + def right_horizontal_ray_intersect(p0, p1, p2): '''An algorithm to determine whether a given right horizontal ray from p0 intersects a line segment p1p2''' max_x = max(p1[0], p2[0]) @@ -15,6 +16,7 @@ def right_horizontal_ray_intersect(p0, p1, p2): return equal(p0, p1) or equal(p0, p2) else: return segments_intersect(p1, p2, p0, (max_x, p0[1])) - + + def equal(p1, p2): return p1[0] == p2[0] and p1[1] == p2[1] diff --git a/segment_intersect.py b/segment_intersect.py index a8d1864..8559da4 100644 --- a/segment_intersect.py +++ b/segment_intersect.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def segments_intersect(p1, p2, p3, p4): diff --git a/simplex.py b/simplex.py index 8f4b922..68a9e19 100644 --- a/simplex.py +++ b/simplex.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import sys diff --git a/single_edge.py b/single_edge.py index 5f42ddf..5b2ee2d 100644 --- a/single_edge.py +++ b/single_edge.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python class node(object): def __init__(self, key, right): diff --git a/synthetic_division.py b/synthetic_division.py index 0f4b483..d3b84a9 100644 --- a/synthetic_division.py +++ b/synthetic_division.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def synthetic_division(A, n, x): diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/bh_tree_test.py b/tests/bh_tree_test.py index 040bf64..24bf74d 100755 --- a/tests/bh_tree_test.py +++ b/tests/bh_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from bh_tree import bh_tree, bh_node diff --git a/tests/binary_search_test.py b/tests/binary_search_test.py index 62485cb..999d173 100644 --- a/tests/binary_search_test.py +++ b/tests/binary_search_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import random from binary_search import binary_search, bisect_left, bisect_right diff --git a/tests/bubble_sort_test.py b/tests/bubble_sort_test.py index 6369e0d..68f7d94 100644 --- a/tests/bubble_sort_test.py +++ b/tests/bubble_sort_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import random from bubble_sort import bubble_sort diff --git a/tests/contains_test.py b/tests/contains_test.py index 1647566..dee5f30 100644 --- a/tests/contains_test.py +++ b/tests/contains_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from contains import contains @@ -7,6 +7,8 @@ class TestContains(unittest.TestCase): def test_contains(self): x = [1, 1.5, 3.5, 2.3, 10.01] - self.assertEqual(contains(x, 5), {(1, 2), (2.3, 3.3), (3.5, 4.5), (10.01, 11.01)}) + self.assertEqual(contains(x, 5), { + (1, 2), (2.3, 3.3), (3.5, 4.5), (10.01, 11.01)}) x = [3.5, 5.2, -1.1, -4, -12, -11.33] - self.assertEqual(contains(x, 6), {(-12, -11), (-4, -3), (-1.1, -0.10000000000000009), (3.5, 4.5), (5.2, 6.2)}) + self.assertEqual(contains(x, 6), { + (-12, -11), (-4, -3), (-1.1, -0.10000000000000009), (3.5, 4.5), (5.2, 6.2)}) diff --git a/tests/cut_rod_test.py b/tests/cut_rod_test.py index 1ddff11..c496dcd 100755 --- a/tests/cut_rod_test.py +++ b/tests/cut_rod_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from cut_rod import bottom_up_cut_rod, bottom_up_cut_rod_two_subproblem, memoized_cut_rod, print_cut_rod_solution, \ @@ -8,32 +8,41 @@ class TestCutRod(unittest.TestCase): def test_bottom_up_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] + values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, + 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): self.assertEqual(bottom_up_cut_rod(p, values[i]), values[i + 1]) def test_bottom_up_cut_rod_two_subproblem(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] + values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, + 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): - self.assertEqual(bottom_up_cut_rod_two_subproblem(p, values[i]), values[i + 1]) + self.assertEqual(bottom_up_cut_rod_two_subproblem( + p, values[i]), values[i + 1]) def test_memoized_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] + values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, + 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] for i in range(0, len(values), 2): self.assertEqual(memoized_cut_rod(p, values[i]), values[i + 1]) def test_bottom_up_cut_rod_with_fixed_cut_cost(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11, 6, 17, 7, 17, 8, 20, 9, 24, 10, 30] + values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11, + 6, 17, 7, 17, 8, 20, 9, 24, 10, 30] for i in range(0, len(values), 2): - self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 2), values[i + 1]) - values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11.5, 6, 17, 7, 17, 8, 20.5, 9, 24, 10, 30] + self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost( + p, values[i], 2), values[i + 1]) + values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11.5, + 6, 17, 7, 17, 8, 20.5, 9, 24, 10, 30] for i in range(0, len(values), 2): - self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost(p, values[i], 1.5), values[i + 1]) + self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost( + p, values[i], 1.5), values[i + 1]) def test_print_rod_solution(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] - values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] + values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, + 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] print_cut_rod_solution(p, 9, extended_memoized_cut_rod) diff --git a/tests/depth_tree_test.py b/tests/depth_tree_test.py index f37db6e..1e5f13b 100755 --- a/tests/depth_tree_test.py +++ b/tests/depth_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from depth_tree import depth_tree, depth_node diff --git a/tests/disjoint_sets_forest_test.py b/tests/disjoint_sets_forest_test.py index 8dac3ce..5d431ce 100644 --- a/tests/disjoint_sets_forest_test.py +++ b/tests/disjoint_sets_forest_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import disjoint_sets_forest as ds @@ -34,10 +34,12 @@ def test_forest(self): for i in range(1, 17): self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) self.assertTrue(pool[2].find_set() == pool[16]) - parent_list = [8, 16, 4, 16, 8, 8, 8, 16, 10, 16, 12, 16, 16, 16, 16, 16] + parent_list = [8, 16, 4, 16, 8, 8, 8, + 16, 10, 16, 12, 16, 16, 16, 16, 16] for i in range(1, 17): self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) self.assertTrue(pool[9].find_set() == pool[16]) - parent_list = [8, 16, 4, 16, 8, 8, 8, 16, 16, 16, 12, 16, 16, 16, 16, 16] + parent_list = [8, 16, 4, 16, 8, 8, 8, + 16, 16, 16, 12, 16, 16, 16, 16, 16] for i in range(1, 17): self.assertEqual(pool[i].p, pool[parent_list[i - 1]]) diff --git a/tests/disjoint_sets_test.py b/tests/disjoint_sets_test.py index 6026884..9fa89ca 100644 --- a/tests/disjoint_sets_test.py +++ b/tests/disjoint_sets_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import disjoint_sets_linked_list as ds diff --git a/tests/graph_test.py b/tests/graph_test.py index a03e6b7..f0e4d40 100644 --- a/tests/graph_test.py +++ b/tests/graph_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from graph import Vertex, Graph diff --git a/tests/hamiltonian_path_test.py b/tests/hamiltonian_path_test.py index 3541bd3..ab7eb9d 100644 --- a/tests/hamiltonian_path_test.py +++ b/tests/hamiltonian_path_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from graph import Vertex, Graph from hamiltonian_path import hamiltonian_path diff --git a/tests/insertion_sort_test.py b/tests/insertion_sort_test.py index 91e3db6..c8dc791 100644 --- a/tests/insertion_sort_test.py +++ b/tests/insertion_sort_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import random from insertion_sort import insertion_sort, insertion_sort_recursive, insert_with_linear_search, \ @@ -29,5 +29,6 @@ def test_insertion_sort_recursive(self): for _ in range(100): array = [random.randint(1, 10000) for _ in range(0, 100)] array_copy = array[:] - insertion_sort_recursive(array, insert_method=insert_with_binary_search) + insertion_sort_recursive( + array, insert_method=insert_with_binary_search) self.assertEqual(array, sorted(array_copy)) diff --git a/tests/interval_tree_test.py b/tests/interval_tree_test.py index 96f6648..b5dc140 100755 --- a/tests/interval_tree_test.py +++ b/tests/interval_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from interval_tree import interval, interval_tree, interval_node @@ -6,11 +6,13 @@ class TestIntervalTree(unittest.TestCase): def test_insert_one(self): intervals = [] - values = [16, 21, 8, 9, 25, 30, 5, 8, 15, 23, 17, 19, 26, 26, 0, 3, 6, 10, 19, 20] + values = [16, 21, 8, 9, 25, 30, 5, 8, 15, + 23, 17, 19, 26, 26, 0, 3, 6, 10, 19, 20] for i in range(0, len(values), 2): intervals.append(interval(values[i], values[i + 1])) T = interval_tree(intervals) - values = [16, 30, 8, 23, 25, 30, 5, 10, 15, 23, 17, 20, 26, 26, 0, 3, 6, 10, 19, 20] + values = [16, 30, 8, 23, 25, 30, 5, 10, 15, + 23, 17, 20, 26, 26, 0, 3, 6, 10, 19, 20] for i in range(0, len(values), 2): self.wrap(T, values[i], values[i + 1]) values = [41, 41, 38, 42, 31, 35, 12, 45, 19, 23, 9, 21] diff --git a/tests/k_way_merge_test.py b/tests/k_way_merge_test.py index a9d8051..36c5126 100644 --- a/tests/k_way_merge_test.py +++ b/tests/k_way_merge_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import random from k_way_merge import k_way_merge diff --git a/tests/longest_common_subsequence_test.py b/tests/longest_common_subsequence_test.py index 79b8962..3aaa4ec 100644 --- a/tests/longest_common_subsequence_test.py +++ b/tests/longest_common_subsequence_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from longest_common_subsequence import lcs_length_one_row, lcs_length diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 1268d81..2b09e49 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest import random from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort, merge_ins_sort2 diff --git a/tests/min_gap_tree_test.py b/tests/min_gap_tree_test.py index 776db14..ea1b5e1 100755 --- a/tests/min_gap_tree_test.py +++ b/tests/min_gap_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from min_gap_tree import min_gap_tree, min_gap_node diff --git a/tests/min_priority_queue_using_rb_tree_test.py b/tests/min_priority_queue_using_rb_tree_test.py index 6ebf788..1e1238b 100644 --- a/tests/min_priority_queue_using_rb_tree_test.py +++ b/tests/min_priority_queue_using_rb_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from min_priority_queue_using_rb_tree import min_priority_queue from rb_tree import rb_node diff --git a/tests/os_tree_test.py b/tests/os_tree_test.py index 36ab2f9..4d99ede 100755 --- a/tests/os_tree_test.py +++ b/tests/os_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from os_tree import os_tree, OSNode @@ -166,9 +166,12 @@ def test_ith_successor(self): # self.wrap(T, 31, -1, -1, 19, 1) # self.wrap(T, 9, -1, -1, 12, 0) def wrap(self, tree, node, left, right, p, color, size): - self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search( + node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search( + node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search( + node).p, tree.iterative_tree_search(p)) self.assertEqual(tree.iterative_tree_search(node).color, color) self.assertEqual(tree.iterative_tree_search(node).size, size) diff --git a/tests/pointer_tree_test.py b/tests/pointer_tree_test.py index a682d74..925b129 100755 --- a/tests/pointer_tree_test.py +++ b/tests/pointer_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from pointer_tree import pointer_tree, pointer_node @@ -101,8 +101,10 @@ def test_delete_six(self): def wrap(self, tree, node, minimum, maximum, predecessor, successor): self.assertEqual(tree.iterative_tree_search(node).minimum.key, minimum) self.assertEqual(tree.iterative_tree_search(node).maximum.key, maximum) - self.assertEqual(tree.iterative_tree_search(node).predecessor.key, predecessor) - self.assertEqual(tree.iterative_tree_search(node).successor.key, successor) + self.assertEqual(tree.iterative_tree_search( + node).predecessor.key, predecessor) + self.assertEqual(tree.iterative_tree_search( + node).successor.key, successor) if __name__ == '__main__': diff --git a/tests/rank_tree_test.py b/tests/rank_tree_test.py index d68c842..6c8c484 100755 --- a/tests/rank_tree_test.py +++ b/tests/rank_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from rank_tree import rank_tree, rank_node @@ -113,9 +113,12 @@ def test_delete_six(self): self.assertEqual(T.nil.rank, 0) def wrap(self, tree, node, left, right, p, color, rank): - self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search( + node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search( + node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search( + node).p, tree.iterative_tree_search(p)) self.assertEqual(tree.iterative_tree_search(node).color, color) self.assertEqual(tree.iterative_tree_search(node).rank, rank) diff --git a/tests/rb_tree_test.py b/tests/rb_tree_test.py index 4d22e1c..76e9fa7 100755 --- a/tests/rb_tree_test.py +++ b/tests/rb_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from rb_tree import rb_tree, rb_node @@ -112,9 +112,12 @@ def test_delete_six(self): self.assertEqual(T.root, T.nil) def wrap(self, tree, node, left, right, p, color): - self.assertEqual(tree.iterative_tree_search(node).left, tree.iterative_tree_search(left)) - self.assertEqual(tree.iterative_tree_search(node).right, tree.iterative_tree_search(right)) - self.assertEqual(tree.iterative_tree_search(node).p, tree.iterative_tree_search(p)) + self.assertEqual(tree.iterative_tree_search( + node).left, tree.iterative_tree_search(left)) + self.assertEqual(tree.iterative_tree_search( + node).right, tree.iterative_tree_search(right)) + self.assertEqual(tree.iterative_tree_search( + node).p, tree.iterative_tree_search(p)) self.assertEqual(tree.iterative_tree_search(node).color, color) diff --git a/tests/test_gcd.py b/tests/test_gcd.py new file mode 100644 index 0000000..1829945 --- /dev/null +++ b/tests/test_gcd.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# encoding: utf-8 +from unittest import TestCase + +from gcd import gcd + + +class TestGcd(TestCase): + def test_gcd(self): + self.assertEqual(gcd(10, 3), 1) + self.assertEqual(gcd(10, 4), 2) + self.assertEqual(gcd(10, 1), 1) diff --git a/tests/vEB_tree_test.py b/tests/vEB_tree_test.py index 63bb4b8..a1fb46e 100644 --- a/tests/vEB_tree_test.py +++ b/tests/vEB_tree_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from vEB_tree import vEB_node diff --git a/tests/wrestlers_test.py b/tests/wrestlers_test.py index 20d545b..a3fa9d1 100644 --- a/tests/wrestlers_test.py +++ b/tests/wrestlers_test.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import unittest from wrestlers import wrestlers diff --git a/three_points_colinear.py b/three_points_colinear.py index e8b8b66..ba33024 100644 --- a/three_points_colinear.py +++ b/three_points_colinear.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python from heap import MaxHeap diff --git a/tree.py b/tree.py index 28313f4..5ea2034 100755 --- a/tree.py +++ b/tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import random diff --git a/universal_sink.py b/universal_sink.py index bc56b0c..2768126 100644 --- a/universal_sink.py +++ b/universal_sink.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python def universal_sink(M): @@ -6,7 +6,7 @@ def universal_sink(M): An algorithm to determine whether a directed graph G contains a universal sink---a vertex with in-degree |V| - 1 and out-degree 0---in time O(V), given an adjacency matrix for G - + M: numpy matrix, the adjacency matrix for the graph rtype: vertex index if G contains a universal sink, otherwise, return None """ diff --git a/vEB_tree.py b/vEB_tree.py index fa12f96..357e318 100644 --- a/vEB_tree.py +++ b/vEB_tree.py @@ -1,4 +1,4 @@ -#!/usr/bin/env ipython +#!/usr/bin/env python import math @@ -102,15 +102,19 @@ def delete(self, x): if summary_max == None: self.max = self.min else: - self.max = self.index(summary_max, self.cluster[summary_max].max) + self.max = self.index( + summary_max, self.cluster[summary_max].max) elif x == self.max: - self.max = self.index(self.high(x), self.cluster[self.high(x)].max) + self.max = self.index( + self.high(x), self.cluster[self.high(x)].max) def print_veb(self): if self.u == 2: - print("u = {}, min = {}, max = {}".format(self.u, self.min, self.max)) + print("u = {}, min = {}, max = {}".format( + self.u, self.min, self.max)) else: - print("u = {}, min = {}, max = {}".format(self.u, self.min, self.max)) + print("u = {}, min = {}, max = {}".format( + self.u, self.min, self.max)) print("Summary: \t", ) self.summary.print_veb() print() From da5541ccba2cd5acb5872249ee6d3f1341951053 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 2 Jan 2021 00:49:39 +0800 Subject: [PATCH 24/49] conform to PEP8 --- Fibonacci.c | 22 ----- any_disks_intersect.py | 6 +- any_segments_intersect.py | 4 +- closest_points.py | 6 +- closest_points_l1_distance.py | 6 +- closest_points_l_infinite_distance.py | 17 +++- deque.py | 67 ++++++++------- euclid.py | 4 +- fft.py | 12 ++- fibonacci_heap.py => fibonacciheap.py | 66 +++++++++------ graph.py | 10 +-- hash.py | 3 +- heap.py | 8 +- k_way_merge.py | 6 +- kth-Quantiles.py | 19 +++-- linked_list_test.py | 38 ++++----- min_heap_with_linked_list.py | 2 +- min_heap_with_linked_list_test.py | 114 +++++++++++++------------- os_tree.py | 6 +- os_tree_test.py | 4 +- polar_angle.py | 35 +++++--- polygon_area.py | 1 + priority_queue.py | 20 +++-- priority_queue_test.py | 14 ++-- queue.py | 42 ---------- three_points_colinear.py | 8 +- wrestlers.py | 12 +-- 27 files changed, 278 insertions(+), 274 deletions(-) delete mode 100644 Fibonacci.c rename fibonacci_heap.py => fibonacciheap.py (81%) delete mode 100644 queue.py diff --git a/Fibonacci.c b/Fibonacci.c deleted file mode 100644 index 181a626..0000000 --- a/Fibonacci.c +++ /dev/null @@ -1,22 +0,0 @@ -void swap(int *x, int *y) { - int temp; - - temp = *x; - *x = *y; - *y = temp; -} - -/* Compute Fibonacci number fib(n); fib(0) = 1, fib(1); fib(n) = fib(n-1) + fib(n-2); return fib(n) of int type */ - -int fib(int n) { - int fib1 = 1, fib2 = 1; - int i; - - for (i = 2; i <= n; i++) { - fib1 = fib1 + fib2; - swap(&fib1, &fib2); - } - return fib2; - -} - diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 3e35ad3..6af5688 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -3,11 +3,11 @@ # we use 0 to mean red, 1 to mean black from tree import Node, Tree -from heap import max_heap +from heap import MaxHeap def comparable(a, b): - '''Given two disks a and b that are comparable at x, determine whether a is above b or not.''' + """Given two disks a and b that are comparable at x, determine whether a is above b or not.""" a_y = a[0][1] b_y = b[0][1] if a_y >= b_y: @@ -271,7 +271,7 @@ def any_disks_intersect(S): y = center_point[1] point_list.append(point([x - radius, 0, y], s)) point_list.append(point([x + radius, 1, y], s)) - heap_point = max_heap(point_list) + heap_point = MaxHeap(point_list) heap_point.heapsort() print(heap_point) for p in heap_point: diff --git a/any_segments_intersect.py b/any_segments_intersect.py index 0c77e08..ffa2888 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -3,7 +3,7 @@ # we use 0 to mean red, 1 to mean black from tree import Node, Tree -from heap import max_heap +from heap import MaxHeap from segment_intersect import segments_intersect def vertical(a): @@ -276,7 +276,7 @@ def any_segments_intersect(S): for s in segment_list: point_list.append(point([s[0][0], 0, s[0][1]], s)) point_list.append(point([s[1][0], 1, s[1][1]], s)) - heap_point = max_heap(point_list) + heap_point = MaxHeap(point_list) heap_point.heapsort() for p in heap_point: if p[1] == 0: diff --git a/closest_points.py b/closest_points.py index e61bccb..123c264 100644 --- a/closest_points.py +++ b/closest_points.py @@ -1,17 +1,17 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): diff --git a/closest_points_l1_distance.py b/closest_points_l1_distance.py index 25361d5..6f20902 100644 --- a/closest_points_l1_distance.py +++ b/closest_points_l1_distance.py @@ -1,17 +1,17 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): diff --git a/closest_points_l_infinite_distance.py b/closest_points_l_infinite_distance.py index 0b1e1fc..5559e94 100644 --- a/closest_points_l_infinite_distance.py +++ b/closest_points_l_infinite_distance.py @@ -1,24 +1,31 @@ #!/usr/bin/env ipython from math import ceil, sqrt -from heap import max_heap +from heap import MaxHeap + def x_sort(S): - X = max_heap(S) + X = MaxHeap(S) X.heapsort() return X + + def y_sort(S): Y = [] for p in S: Y.append((p[1], p[0])) - YY = max_heap(Y) + YY = MaxHeap(Y) YY.heapsort() Y = [] for i in range(0, len(YY)): Y.append((YY[i][1], YY[i][0])) return Y + + def distance(p1, p2): return max(abs(p1[0] - p2[0]), abs(p1[1] - p2[1])) + + def brute_force(P): P = list(P) d = float("Inf") @@ -26,10 +33,14 @@ def brute_force(P): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d + + def closest_points(S): X = x_sort(S) Y = y_sort(S) return closest_points_aux(S, X, Y) + + def closest_points_aux(P, X, Y): length = len(P) half = int(ceil(length / 2)) diff --git a/deque.py b/deque.py index 61509a4..9590822 100644 --- a/deque.py +++ b/deque.py @@ -1,32 +1,37 @@ -from queue import queue, FullException, EmptyException - -def deque(queue): - ''' - whereas a queue allows insertion at one end and deletion at the other end, a deque(double-ended queue allows insertion and deletion at both ends - ''' - def __init__(self, size): - super(deque, self).__init__(size) - def enqueue_tail(self, x): - self.enqueue(x) - def dequeue_head(self): - return self.dequeue() - def enqueue_head(self, x): - if self.full(): - raise FullException("This double-ended queue is full") - else: - if self.head == 0: - self.head = self.length - 1 - else: - self.head = self.head - 1 - self[self.head] = x - def dequeue_tail(self): - if self.emtpy(): - raise EmptyException("This double-ended queue is empty") - else: - if self.tail == 0: - self.tail = self.length - 1 - else: - self.tail = self.tail - 1 - - return self[self.tail] +from Queue import Queue, FullException, EmptyException + +def deque(Queue): + """ + whereas a Queue allows insertion at one end and deletion at the other end, a deque(double-ended Queue allows insertion and deletion at both ends + """ + + def __init__(self, size): + super(deque, self).__init__(size) + + def enqueue_tail(self, x): + self.enqueue(x) + + def dequeue_head(self): + return self.dequeue() + + def enqueue_head(self, x): + if self.full(): + raise FullException("This double-ended Queue is full") + else: + if self.head == 0: + self.head = self.length - 1 + else: + self.head = self.head - 1 + self[self.head] = x + + def dequeue_tail(self): + if self.emtpy(): + raise EmptyException("This double-ended Queue is empty") + else: + if self.tail == 0: + self.tail = self.length - 1 + else: + self.tail = self.tail - 1 + + return self[self.tail] diff --git a/euclid.py b/euclid.py index e5f97bc..3d81b24 100644 --- a/euclid.py +++ b/euclid.py @@ -1,15 +1,17 @@ #!/usr/bin/env python # coding=utf-8 + def euclid(a, b): if b == 0: return a else: return euclid(b, a % b) + def extended_euclid(a, b): if b == 0: - return (a, 1, 0) + return a, 1, 0 else: d, x, y = extended_euclid(b, a % b) return d, y, x - (a / b) * y diff --git a/fft.py b/fft.py index dd5ee18..94291d4 100644 --- a/fft.py +++ b/fft.py @@ -2,6 +2,7 @@ import math + def recursive_fft(a): n = len(a) if n == 1: @@ -13,16 +14,19 @@ def recursive_fft(a): y0 = recursive_fft(a0) y1 = recursive_fft(a1) y = [0.0] * n - for k in range(0, n / 2): + for k in range(0, n // 2): y[k] = y0[k] + w * y1[k] - y[k + n / 2] = y0[k] - w * y1[k] + y[k + n // 2] = y0[k] - w * y1[k] w = w * wn return y + def recursive_inverse_fft(y): n = len(y) result = recursive_inverse_fft_aux(y) return [result[i] / n for i in range(0, n)] + + def recursive_inverse_fft_aux(y): n = len(y) if n == 1: @@ -34,8 +38,8 @@ def recursive_inverse_fft_aux(y): a0 = recursive_inverse_fft_aux(y0) a1 = recursive_inverse_fft_aux(y1) a = [0.0] * n - for k in range(0, n / 2): + for k in range(0, n // 2): a[k] = (a0[k] + w * a1[k]) - a[k + n / 2] = (a0[k] - w * a1[k]) + a[k + n // 2] = (a0[k] - w * a1[k]) w = w * wn return a diff --git a/fibonacci_heap.py b/fibonacciheap.py similarity index 81% rename from fibonacci_heap.py rename to fibonacciheap.py index 0f7434b..bd3c242 100644 --- a/fibonacci_heap.py +++ b/fibonacciheap.py @@ -1,4 +1,4 @@ -class fibonacci_node(object): +class FibonacciNode: degree = 0 p = None child = None @@ -10,10 +10,12 @@ def __init__(self, k): self.key = k def __iter__(self): - '''generate a list of children of the node for iteration''' + """ + generate a list of children of the node for iteration + """ self.children = [] self.index = 0 - if self.child != None: + if self.child is not None: child = self.child while True: self.children.append(child) @@ -31,15 +33,23 @@ def next(self): raise StopIteration def insert(self, x): - '''insert x to the left of node''' + """ + insert x to the left of node + :param x: + :return: + """ x.left = self.left x.right = self self.left.right = x self.left = x def concatenate(self, x): - '''concatenate two lists represented by the node and x, - x mustn't be None''' + """ + concatenate two lists represented by the node and x, + x mustn't be None + :param x: + :return: + """ self.left.right = x.right x.right.left = self.left self.left = x @@ -53,7 +63,7 @@ def add_child(self, y): self.degree = self.degree + 1 y.mark = False y.p = self - if self.child == None: + if self.child is None: self.child = y y.left = y y.right = y @@ -72,16 +82,19 @@ def remove_child(self, y): y.remove() -class fibonacci_heap(object): +class FibonacciHeap(object): def __init__(self): self.n = 0 self.minimum = None def __iter__(self): - '''generate a list of children of the node for iteration''' + """ + generate a list of children of the node for iteration + :return: + """ self.root_list = [] self.index = 0 - if self.minimum != None: + if self.minimum is not None: root = self.minimum while True: self.root_list.append(root) @@ -101,7 +114,7 @@ def next(self): def __repr__(self): s = '' x = self.minimum - if x != None: + if x is not None: while True: s = s + '\t' + str(x.key) if x == self.minimum.left: @@ -113,9 +126,13 @@ def __repr__(self): return '' def insert(self, x): - '''insert the node x into the root list of fibonacci heap''' + """ + insert the node x into the root list of fibonacci heap + :param x: + :return: + """ x.p = None - if self.minimum == None: + if self.minimum is None: self.minimum = x x.left = x x.right = x @@ -129,10 +146,10 @@ def minimum(self): return self.minimum def union(self, h): - cat = fibonacci_heap() - if self.minimum == None: + cat = FibonacciHeap() + if self.minimum is None: return h - elif h.minimum == None: + elif h.minimum is None: return self else: self.minimum.concatenate(h.minimum) @@ -145,7 +162,7 @@ def union(self, h): def extract_min(self): z = self.minimum - if z != None: + if z is not None: for child in z: self.insert(child) z.remove() @@ -158,7 +175,7 @@ def extract_min(self): return z def consolidate(self): - D = self.n / 2 + D = self.n // 2 A = [None] * (D + 1) left = self.minimum.left w = self.minimum @@ -167,7 +184,7 @@ def consolidate(self): d = x.degree print('w.key = {}'.format(w.key)) print('w.degree = {}'.format(w.degree)) - while A[d] != None: + while A[d] is not None: y = A[d] if x.key > y.key: x, y = y, x @@ -177,10 +194,11 @@ def consolidate(self): A[d] = x self.minimum = None for i in A: - if i != None: + if i is not None: self.insert(i) - def link(self, y, x): + @staticmethod + def link(y, x): y.remove() x.add_child(y) @@ -190,7 +208,7 @@ def decrease_key(self, x, k): return x.key = k y = x.p - if y != None and x.key < y.key: + if y is not None and x.key < y.key: self.cut(x, y) self.cascading_cut(y) if x.key < self.minimum.key: @@ -203,8 +221,8 @@ def cut(self, x, y): def cascading_cut(self, y): z = y.p - if z != None: - if y.mark == False: + if z is not None: + if y.mark is False: y.mark = True else: self.cut(y, z) diff --git a/graph.py b/graph.py index 43e668d..be04060 100644 --- a/graph.py +++ b/graph.py @@ -1,4 +1,4 @@ -from queue import queue +from Queue import Queue import disjoint_sets_forest as dsf import sys @@ -11,11 +11,11 @@ def __repr__(self): return str(self.key) def print_path(self, v): - '''print( out the vertices on a shortest path from s to) - v, assuming that BFS has already computed a breadth-first tree''' + """print( out the vertices on a shortest path from s to) + v, assuming that BFS has already computed a breadth-first tree""" if self == v: print(self, ) - elif v.p == None: + elif v.p is None: print("No path from {} to {} exists".format(self.key, v.key)) else: self.print_path(v.p) @@ -80,7 +80,7 @@ def bfs(self, s): s.color = 1 s.d = 0 s.p = None - q = queue(2 * len(self.vertices)) + q = Queue(2 * len(self.vertices)) q.enqueue(s) while not q.empty(): u = q.dequeue() diff --git a/hash.py b/hash.py index 6b88130..9e547b4 100755 --- a/hash.py +++ b/hash.py @@ -1,10 +1,11 @@ #!/usr/bin/env ipython + def hash_insert(T, k, h): i = 0 while i < len(T): j = h(k, i) - if T[j] == None: + if T[j] is None: T[j] = k return j else: diff --git a/heap.py b/heap.py index 0f0e3ed..ee7d56a 100644 --- a/heap.py +++ b/heap.py @@ -1,7 +1,7 @@ class MaxHeap(list): def __init__(self, data): - list.__init__(self, data) - self.length = len(data) + super(MaxHeap, self).__init__(data) + self.length = len(self) self.heap_size = self.length self.build_max_heap() @@ -45,8 +45,8 @@ def heapsort(self): class MinHeap(list): def __init__(self, data): - list.__init__(self, data) - self.length = len(data) + super(MinHeap, self).__init__(data) + self.length = len(self) self.heap_size = self.length self.build_min_heap() diff --git a/k_way_merge.py b/k_way_merge.py index c0d13af..1fc0a8a 100644 --- a/k_way_merge.py +++ b/k_way_merge.py @@ -28,7 +28,11 @@ def merge(list1, list2): def k_way_merge(lists): - '''Merge k sorted lists and return it as one sorted list''' + """ + Merge k sorted lists and return it as one sorted list + :param lists: + :return: + """ length = len(lists) if length == 1: return lists[0] diff --git a/kth-Quantiles.py b/kth-Quantiles.py index 8d7c0bb..4af371a 100755 --- a/kth-Quantiles.py +++ b/kth-Quantiles.py @@ -32,15 +32,16 @@ def median_of_two_arrays(X, x_start, x_end, Y, y_start, y_end, size): math.floor(size / 2)) -A = [random.randint(1, 100) for i in range(0, 15)] -print(A) -randomized_quicksort(A, 0, 14) -print(A) -B = [random.randint(1, 100) for i in range(0, 15)] -print(B) -randomized_quicksort(B, 0, 14) -print(B) -print(median_of_two_arrays(A, 0, 14, B, 0, 14, 3.0)) +if __name__ == '__main__': + A = [random.randint(1, 100) for i in range(0, 15)] + print(A) + randomized_quicksort(A, 0, 14) + print(A) + B = [random.randint(1, 100) for i in range(0, 15)] + print(B) + randomized_quicksort(B, 0, 14) + print(B) + print(median_of_two_arrays(A, 0, 14, B, 0, 14, 3.0)) # randomized_select(A, 0, 14, 7) # print( A) # for i in range(1, 16): diff --git a/linked_list_test.py b/linked_list_test.py index bbe6f4d..06779d2 100644 --- a/linked_list_test.py +++ b/linked_list_test.py @@ -1,15 +1,15 @@ import unittest -from linked_list import linked_list, linked_list_node +from linkedlist import LinkedList, LinkedListNode class TestLinkedList(unittest.TestCase): def test_insert(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) @@ -23,12 +23,12 @@ def test_insert(self): self.assertEqual(l, [e, d, c, b, a]) def test_search(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) @@ -37,12 +37,12 @@ def test_search(self): self.assertEqual(L.search(4), b) def test_delete(self): - L = linked_list() - a = linked_list_node(1) - b = linked_list_node(4) - c = linked_list_node(16) - d = linked_list_node(9) - e = linked_list_node(25) + L = LinkedList() + a = LinkedListNode(1) + b = LinkedListNode(4) + c = LinkedListNode(16) + d = LinkedListNode(9) + e = LinkedListNode(25) L.insert(a) L.insert(b) L.insert(c) diff --git a/min_heap_with_linked_list.py b/min_heap_with_linked_list.py index 35902ea..33f9ec1 100644 --- a/min_heap_with_linked_list.py +++ b/min_heap_with_linked_list.py @@ -1,4 +1,4 @@ -from linked_list import linked_list_node, linked_list +from linkedlist import LinkedListNode, LinkedList import sys diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py index 432b1a2..440bab1 100644 --- a/min_heap_with_linked_list_test.py +++ b/min_heap_with_linked_list_test.py @@ -1,76 +1,76 @@ import unittest from min_heap_with_linked_list import min_heap, min_priority_queue -from linked_list import linked_list, linked_list_node +from linkedlist import LinkedList, LinkedListNode class TestHeap(unittest.TestCase): def test_min_heapify(self): - L1 = linked_list(1) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) h = min_heap([L5, L1, L2, L3, L4]) h.min_heapify(0) self.assertEqual(h, [L1, L3, L2, L5, L4]) def test_build_min_heap(self): - L1 = linked_list(1) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) h = min_heap([L3, L4, L5, L2, L1]) h.build_min_heap() self.assertEqual(h, [L1, L2, L5, L3, L4]) def test_heap_minimum(self): - L1 = linked_list(1) - L1.insert(linked_list_node(1)) - L1.insert(linked_list_node(1)) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_minimum().key, 1) def test_heap_extract_min(self): - L1 = linked_list(1) - L1.insert(linked_list_node(1)) - L1.insert(linked_list_node(1)) - L2 = linked_list(2) - L2.insert(linked_list_node(2)) - L2.insert(linked_list_node(2)) - L3 = linked_list(3) - L3.insert(linked_list_node(3)) - L3.insert(linked_list_node(3)) - L4 = linked_list(4) - L4.insert(linked_list_node(4)) - L5 = linked_list(5) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) - L3.insert(linked_list_node(5)) + L1 = LinkedList(1) + L1.insert(LinkedListNode(1)) + L1.insert(LinkedListNode(1)) + L2 = LinkedList(2) + L2.insert(LinkedListNode(2)) + L2.insert(LinkedListNode(2)) + L3 = LinkedList(3) + L3.insert(LinkedListNode(3)) + L3.insert(LinkedListNode(3)) + L4 = LinkedList(4) + L4.insert(LinkedListNode(4)) + L5 = LinkedList(5) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) + L3.insert(LinkedListNode(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_extract_min().key, 1) self.assertEqual(q, [L1, L2, L3, L4, L5]) diff --git a/os_tree.py b/os_tree.py index de4ea05..71f2306 100755 --- a/os_tree.py +++ b/os_tree.py @@ -3,7 +3,7 @@ from rb_tree import rb_node, rb_tree -class os_node(rb_node): +class OSNode(rb_node): def __init__(self, key, p, left, right, color, size): rb_node.__init__(self, key, p, left, right, color) self.size = size @@ -55,13 +55,13 @@ def ith_successor(self, i): class os_tree(rb_tree): - nil = os_node(None, None, None, None, 1, 0) + nil = OSNode(None, None, None, None, 1, 0) root = nil def __init__(self, values): if isinstance(values, list): for i in values: - self.insert(os_node(i, None, None, None, 0, 1)) + self.insert(OSNode(i, None, None, None, 0, 1)) else: print("Not invalid argument") diff --git a/os_tree_test.py b/os_tree_test.py index bf84248..36ab2f9 100755 --- a/os_tree_test.py +++ b/os_tree_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env ipython import unittest -from os_tree import os_tree, os_node +from os_tree import os_tree, OSNode class TestOstree(unittest.TestCase): @@ -156,7 +156,7 @@ def test_ith_successor(self): # def test_insert_stack(self): # T = os_tree([]) # for i in 41, 38, 31, 12, 19, 9: - # T.insert_stack(os_node(i, None, None, None, 0)) + # T.insert_stack(OSNode(i, None, None, None, 0)) # self.assertEqual(T.root, T.iterative_tree_search(38)) # self.assertEqual(T.nil.color, 1) # self.wrap(T, 38, 19, 41, -1, 1) diff --git a/polar_angle.py b/polar_angle.py index 67f2b4a..4eaf2c7 100644 --- a/polar_angle.py +++ b/polar_angle.py @@ -1,33 +1,42 @@ #!/usr/bin/env ipython -from heap import max_heap +from heap import MaxHeap -class vector(object): - def __init__(self, p2, p1 = (0, 0)): + +class Vector: + def __init__(self, p2, p1=(0, 0)): self.x = p2[0] - p1[0] self.y = p2[1] - p1[0] + def cross_product(self, v): return self.x * v.y - v.x * self.y + def __lt__(self, v): return self.cross_product(v) > 0 + def __gt__(self, v): return self.cross_product(v) < 0 + def __eq__(self, v): return self.cross_product(v) == 0 + def __le__(self, v): return self.cross_product(v) >= 0 + def __ge__(self, v): return self.cross_product(v) <= 0 + + def polar_angle(p0, point_list): - '''sort a sequence of n points according to + """sort a sequence of n points according to their polar angles with respect to a given origin point p0. - ''' - v0 = vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 - vector_list = [vector(p, p0) for p in point_list] - angle_0 = [] #list of vectors whose polar angles are 0 - angle_pi = [] #list of vectors whose polar angles are pi - angle_0_pi = [] #list of vectors whose polar angles are larger than 0 and smaller than pi - angle_pi_2pi = [] #list of vectors whose polar angles are larger than pi and smaller than 2pi + """ + v0 = Vector((p0[0] + 1, p0[1]), p0) # The polar angle of v0 is 0 + vector_list = [Vector(p, p0) for p in point_list] + angle_0 = [] # list of vectors whose polar angles are 0 + angle_pi = [] # list of vectors whose polar angles are pi + angle_0_pi = [] # list of vectors whose polar angles are larger than 0 and smaller than pi + angle_pi_2pi = [] # list of vectors whose polar angles are larger than pi and smaller than 2pi for v in vector_list: if v == v0: if v.x > 0: @@ -38,8 +47,8 @@ def polar_angle(p0, point_list): angle_pi_2pi.append(v) elif v > v0: angle_0_pi.append(v) - heap_0_pi = max_heap(angle_0_pi) - heap_pi_2pi = max_heap(angle_pi_2pi) + heap_0_pi = MaxHeap(angle_0_pi) + heap_pi_2pi = MaxHeap(angle_pi_2pi) heap_0_pi.heapsort() heap_pi_2pi.heapsort() return [(v.x, v.y) for v in (angle_0 + heap_0_pi + angle_pi + heap_pi_2pi)] diff --git a/polygon_area.py b/polygon_area.py index 262f89c..ea2a9f0 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -1,5 +1,6 @@ #!/usr/bin/env ipython + def polygon_area(P): n = len(P) S = 0 diff --git a/priority_queue.py b/priority_queue.py index 7d9252b..118a370 100644 --- a/priority_queue.py +++ b/priority_queue.py @@ -1,9 +1,11 @@ import sys -from heap import max_heap, min_heap +from heap import MaxHeap, MinHeap -class max_priority_queue(max_heap): + +class MaxPriorityQueue(MaxHeap): def heap_maximum(self): return self[0] + def heap_extract_max(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -12,6 +14,7 @@ def heap_extract_max(self): self.heap_size = self.heap_size - 1 self.max_heapify(0) return maximum + def heap_increase_key(self, i, key): if key < self[i]: sys.exit("new key is smaller than current key") @@ -19,22 +22,27 @@ def heap_increase_key(self, i, key): while i > 0 and self[self.parent(i)] < self[i]: tmp = self[self.parent(i)] self[self.parent(i)] = self[i] - self[i] = tmp + self[i] = tmp i = self.parent(i) + def max_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") self.heap_size = self.heap_size + 1 self[self.heap_size - 1] = float("-Inf") self.heap_increase_key(self.heap_size - 1, key) + def heap_delete(self, i): self.heap_increase_key(i, float("Inf")) self[0], self[self.heap_size - 1] = self[self.heap_size - 1], self[0] self.heap_size = self.heap_size - 1 self.max_heapify(0) -class min_priority_queue(min_heap): + + +class min_priority_queue(MinHeap): def heap_minimum(self): return self[0] + def heap_extract_min(self): if self.heap_size < 1: sys.exit("heap underflow") @@ -43,6 +51,7 @@ def heap_extract_min(self): self.heap_size = self.heap_size - 1 self.min_heapify(0) return minimum + def heap_decrease_key(self, i, key): if key > self[i]: sys.exit("new key is larger than current key") @@ -50,8 +59,9 @@ def heap_decrease_key(self, i, key): while i > 0 and self[self.parent(i)] > self[i]: tmp = self[self.parent(i)] self[self.parent(i)] = self[i] - self[i] = tmp + self[i] = tmp i = self.parent(i) + def min_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") diff --git a/priority_queue_test.py b/priority_queue_test.py index c556694..a5d3b55 100644 --- a/priority_queue_test.py +++ b/priority_queue_test.py @@ -1,39 +1,39 @@ import unittest -from priority_queue import max_priority_queue, min_priority_queue +from priority_queue import MaxPriorityQueue, min_priority_queue class TestMaxPriorityQueue(unittest.TestCase): def test_init(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - q = max_priority_queue(a) + q = MaxPriorityQueue(a) self.assertEqual(q, [16, 14, 10, 8, 7, 9, 3, 2, 4, 1]) def test_heap_maximum(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - self.assertEqual(max_priority_queue(a).heap_maximum(), 16) + self.assertEqual(MaxPriorityQueue(a).heap_maximum(), 16) def test_heap_extract_max(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) self.assertEqual(h.heap_extract_max(), 16) self.assertEqual(h, [14, 8, 10, 4, 7, 9, 3, 2, 1, 1]) def test_heap_increase_key(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) h.heap_increase_key(8, 15) self.assertEqual(h, [16, 15, 10, 14, 7, 9, 3, 2, 8, 1]) def test_heap_insert(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - queue = max_priority_queue(a) + queue = MaxPriorityQueue(a) queue.heap_extract_max() queue.max_heap_insert(100) self.assertEqual(queue, [100, 14, 10, 4, 8, 9, 3, 2, 1, 7]) def test_heap_delete(self): a = [4, 1, 3, 2, 16, 9, 10, 14, 8, 7] - h = max_priority_queue(a) + h = MaxPriorityQueue(a) h.heap_delete(4) self.assertEqual(h[0:h.heap_size], [16, 14, 10, 8, 1, 9, 3, 2, 4]) h.heap_delete(2) diff --git a/queue.py b/queue.py deleted file mode 100644 index 37ad81c..0000000 --- a/queue.py +++ /dev/null @@ -1,42 +0,0 @@ -class FullException(Exception): - def __init__(self): - Exception.__init__(self) - - -class EmptyException(Exception): - def __init__(self): - Exception.__init__(self) - - -class queue(object): - def __init__(self, size): - self.data = [0] * size - self.length = size - self.head = 0 - self.tail = 0 - - def enqueue(self, x): - if self.full(): - raise FullException() - self.data[self.tail] = x - if self.tail == self.length - 1: - self.tail = 0 - else: - self.tail = self.tail + 1 - - def dequeue(self): - if self.empty(): - raise EmptyException() - x = self.data[self.head] - if self.head == self.length - 1: - self.head = 0 - else: - self.head = self.head + 1 - return x - - def empty(self): - return self.tail == self.head - - def full(self): - # print( "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length)) - return (self.tail + 1) % self.length == self.head diff --git a/three_points_colinear.py b/three_points_colinear.py index 00d9274..5380b2f 100644 --- a/three_points_colinear.py +++ b/three_points_colinear.py @@ -1,11 +1,11 @@ #!/usr/bin/env ipython -from heap import max_heap +from heap import MaxHeap class vector(object): def __init__(self, p1, p2, p1_index=0, p2_index=0): - # gurantee that the polar angle of this vector with respect to the origin point is in the range [0, pi) + # gurantee that the polar angle of this Vector with respect to the origin point is in the range [0, pi) if p1[1] > p2[1]: self.x = p1[0] - p2[0] self.y = p1[1] - p2[1] @@ -40,14 +40,14 @@ def __ge__(self, v): def three_points_colinear(points_list): - '''An algorithm to determine whether any three points in a set of n points are colinear''' + """ to determine whether any three points in a set of n points are colinear""" n = len(points_list) vectors_list = [] for i in range(n): for j in range(i + 1, n): vectors_list.append(vector(points_list[i], points_list[j], i, j)) v0 = vector((1, 0), (0, 0)) - heap_vectors = max_heap(vectors_list) + heap_vectors = MaxHeap(vectors_list) heap_vectors.heapsort() status = [False] * n v = heap_vectors[0] diff --git a/wrestlers.py b/wrestlers.py index 19d1d2c..25be93a 100644 --- a/wrestlers.py +++ b/wrestlers.py @@ -1,8 +1,9 @@ -from queue import queue +from Queue import Queue from graph import Graph, Vertex + def wrestlers(wrestlersList, rivalriesList): - ''' + """ There are two types of professional wrestlers: "babyfaces" ("good guys") and "heels" ("bad guys"). Between any pair of professional wrestlers, there may or may not be a rivalry. @@ -11,7 +12,7 @@ def wrestlers(wrestlersList, rivalriesList): possible to designate some of the wrestlers as babyfaces and There remainder as heels such that each rivalry is between a babyfaces and a heel. - ''' + """ d = dict() vertices = [None] * len(wrestlersList) edges = [None] * len(rivalriesList) @@ -28,13 +29,14 @@ def wrestlers(wrestlersList, rivalriesList): u.type = 0 for u in g.vertices: if u.type == 0: - if _bfs(g, u) == False: + if not _bfs(g, u): return False return True + def _bfs(g, s): s.type = 1 - q = queue(2 * len(g.vertices)) + q = Queue(2 * len(g.vertices)) q.enqueue(s) while not q.empty(): u = q.dequeue() From 6c00e6245af6ead8b90678674d7eb9c78fd6e015 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 2 Jan 2021 01:49:38 +0800 Subject: [PATCH 25/49] conform to PEP8 --- Bellman_Ford_matrix.py | 2 -- BinaryAdd.c | 29 ------------------------- activity_selection.py | 11 ++++++---- huffman.py | 4 ++-- merge_sort.py | 24 ++++++++++---------- min_heap_with_linked_list_test.py | 8 +++++-- priority_queue.py | 2 +- quicksort.py | 18 +++++++-------- stack.py | 10 ++++----- tests/all_pairs_shortest_paths_test.py | 3 +-- tests/min_heap_with_linked_list_test.py | 4 ++-- tests/priority_queue_test.py | 12 +++++----- two_sum.py | 2 +- 13 files changed, 51 insertions(+), 78 deletions(-) delete mode 100644 BinaryAdd.c diff --git a/Bellman_Ford_matrix.py b/Bellman_Ford_matrix.py index 5dec80c..6867850 100644 --- a/Bellman_Ford_matrix.py +++ b/Bellman_Ford_matrix.py @@ -1,5 +1,3 @@ -import numpy as np - def Bellman_Ford_matrix(W, s): n = W.shape[0] diff --git a/BinaryAdd.c b/BinaryAdd.c deleted file mode 100644 index b2b7fa1..0000000 --- a/BinaryAdd.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -void BinaryAdd(int a[], int b[], int n,int c[]) { - int promote = 0; - int i; - int result; - - for (i = n - 1; i >= 0; i--) { - result = a[i] + b[i] + promote; - if (result >= 2) { - result = result - 2; - promote = 1; - } - else - promote = 0; - c[i + 1] = result; - } - c[0] = promote; -} - -int main() { - int a[4] = {1,0,1,1}; - int b[4] = {1,1,1,1}; - int c[5]; - - BinaryAdd(a, b, 4, c); - printf("%d%d%d%d + %d%d%d%d = %d%d%d%d%d\n", a[0], a[1], a[2], a[3], b[0], b[1], b[2], b[3], c[0], c[1], c[2], c[3], c[4]); - return 0; -} diff --git a/activity_selection.py b/activity_selection.py index 233b323..2e24de7 100644 --- a/activity_selection.py +++ b/activity_selection.py @@ -24,9 +24,11 @@ def activity_selection(s, f, n): def activity_selection_with_weight(s, f, v, n): - '''This is a modification to the activity-selection problem in which each activity has, + """ + This is a modification to the activity-selection problem in which each activity has, in addition to a start and finish time, a value v. Now the object is to maximize - the total value of the activies scheduled. It can be solved by dynamic programming method''' + the total value of the activies scheduled. It can be solved by dynamic programming method + """ c = zeros((n + 2, n + 2)) activities = zeros((n + 2, n + 2)) s = [float("-Inf")] + s[0:n] + [float("Inf")] @@ -70,9 +72,10 @@ def greedy_activity_selector(s, f): def greedy_activity_selector_last(s, f): - '''Instead of always selecting the first activity to finish, + """Instead of always selecting the first activity to finish, select the last activity to start that is compatible with all - previously selected activities''' + previously selected activities + """ n = len(s) A = {n} k = n diff --git a/huffman.py b/huffman.py index b40286e..cf4473a 100644 --- a/huffman.py +++ b/huffman.py @@ -1,8 +1,8 @@ -from priority_queue import min_priority_queue +from priority_queue import MinPriorityQueue import sys -class Min_priority_queue(min_priority_queue): +class Min_priority_queue(MinPriorityQueue): def min_heap_insert(self, key): if self.heap_size >= self.length: sys.exit("heap overflow") diff --git a/merge_sort.py b/merge_sort.py index 9e07bea..c879a73 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -1,5 +1,4 @@ from insertion_sort import insertion_sort -import math def merge_with_sentinel(array, left, mid, right): @@ -31,8 +30,9 @@ def merge_with_sentinel(array, left, mid, right): def merge_without_sentinel(array, left, mid, right): """ merge procedure without sentinels + A merge procedure without sentinels that stops once either array `left_part` or `right_part` has had all its elements - copied back to `array` and then copying the remainder of the other array back into `array` + copied back to `array` and then copying the remainder of another array back into `array` :param array: :param left: :param mid: @@ -44,9 +44,7 @@ def merge_without_sentinel(array, left, mid, right): i = 0 j = 0 k = left - left_length = mid - left + 1 - right_length = right - mid - while i < left_length and j < right_length: + while i < len(left_part) and j < len(right_part): if left_part[i] <= right_part[j]: array[k] = left_part[i] k = k + 1 @@ -55,10 +53,10 @@ def merge_without_sentinel(array, left, mid, right): array[k] = right_part[j] k = k + 1 j = j + 1 - if i < left_length: - array[k: right + 1] = left_part[i: left_length] + if i < len(left_part): + array[k: right + 1] = left_part[i:] else: - array[k: right + 1] = right_part[j: right_length] + array[k: right + 1] = right_part[j:] def merge_sort(array, merge_method=merge_with_sentinel): @@ -79,10 +77,10 @@ def _merge_sort(array, left, right, merge_method): merge_method(array, left, mid, right) -def merge_ins_sort(array, partition=2): +def merge_ins_sort(array, partition: int = 2): """ - Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make - it faster in practice for small problem sizes on many machines. + Although merge sort runs faster than insertion sort asymptotically, + the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines. Thus, it makes sense to coarsen the leaves of the recursion by using insertion sort within merge sort when subproblems become sufficiently small. Consider a modification to merge sort in which n/k sublists of length k are sorted using insertion sort and then merged using the standard merging mechanism, where k is a value to be determined. @@ -94,7 +92,7 @@ def merge_ins_sort(array, partition=2): """ assert partition > 0 n = len(array) - sublist_length = math.ceil(n / partition) + sublist_length = n // partition sublist_number = partition for i in range(sublist_number): left = sublist_length * i @@ -105,7 +103,7 @@ def merge_ins_sort(array, partition=2): merge_with_sentinel(array, sublist_length * i, sublist_length * (i + 1) - 1, min(sublist_length * (i + 2) - 1, n - 1)) sublist_length *= 2 - sublist_number = math.ceil(sublist_number / 2) + sublist_number = sublist_number // 2 def merge_ins_sort2(array, sublist_length): diff --git a/min_heap_with_linked_list_test.py b/min_heap_with_linked_list_test.py index 440bab1..05e0cc3 100644 --- a/min_heap_with_linked_list_test.py +++ b/min_heap_with_linked_list_test.py @@ -2,6 +2,7 @@ from min_heap_with_linked_list import min_heap, min_priority_queue from linkedlist import LinkedList, LinkedListNode + class TestHeap(unittest.TestCase): def test_min_heapify(self): L1 = LinkedList(1) @@ -20,6 +21,7 @@ def test_min_heapify(self): h = min_heap([L5, L1, L2, L3, L4]) h.min_heapify(0) self.assertEqual(h, [L1, L3, L2, L5, L4]) + def test_build_min_heap(self): L1 = LinkedList(1) L2 = LinkedList(2) @@ -37,6 +39,7 @@ def test_build_min_heap(self): h = min_heap([L3, L4, L5, L2, L1]) h.build_min_heap() self.assertEqual(h, [L1, L2, L5, L3, L4]) + def test_heap_minimum(self): L1 = LinkedList(1) L1.insert(LinkedListNode(1)) @@ -55,6 +58,7 @@ def test_heap_minimum(self): L3.insert(LinkedListNode(5)) q = min_priority_queue([L1, L2, L3, L4, L5]) self.assertEqual(q.heap_minimum().key, 1) + def test_heap_extract_min(self): L1 = LinkedList(1) L1.insert(LinkedListNode(1)) @@ -78,12 +82,12 @@ def test_heap_extract_min(self): self.assertEqual(q, [L2, L4, L3, L5, L5]) # def test_heap_decrease_key(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) +# q = MinPriorityQueue(a) # q.heap_decrease_key(8, 1) # self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) # def test_heap_insert(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) +# q = MinPriorityQueue(a) # q.heap_extract_min() # q.min_heap_insert(0) # self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/priority_queue.py b/priority_queue.py index 118a370..2b62e26 100644 --- a/priority_queue.py +++ b/priority_queue.py @@ -39,7 +39,7 @@ def heap_delete(self, i): self.max_heapify(0) -class min_priority_queue(MinHeap): +class MinPriorityQueue(MinHeap): def heap_minimum(self): return self[0] diff --git a/quicksort.py b/quicksort.py index 810560e..eed28db 100644 --- a/quicksort.py +++ b/quicksort.py @@ -1,15 +1,15 @@ -from partition import partition, partition2, partition3, randomized_partition +from partition import partition, randomized_partition -def quicksort(A, p, r, partition_method=partition): +def quicksort(array, p, r, partition_method=partition): if p < r: - q = partition_method(A, p, r) - quicksort(A, p, q - 1) - quicksort(A, q + 1, r) + q = partition_method(array, p, r) + quicksort(array, p, q - 1) + quicksort(array, q + 1, r) -def randomized_quicksort(A, p, r): +def randomized_quicksort(array, p, r): if p < r: - q = randomized_partition(A, p, r) - randomized_quicksort(A, p, q - 1) - randomized_quicksort(A, q + 1, r) + q = randomized_partition(array, p, r) + randomized_quicksort(array, p, q - 1) + randomized_quicksort(array, q + 1, r) diff --git a/stack.py b/stack.py index eb8e765..19b17d3 100644 --- a/stack.py +++ b/stack.py @@ -1,14 +1,14 @@ -class FullException(BaseException): +class FullException(Exception): pass -class EmptyException(BaseException): +class EmptyException(Exception): pass -class stack(list): +class Stack(list): def __init__(self, size): - list.__init__(self, [None] * size) + super(Stack, self).__init__([None] * size) self.top = -1 self.size = len(size) @@ -19,7 +19,7 @@ def push(self, x): self.top = self.top + 1 self[self.top] = x - def pop(self): + def pop(self, *args, **kwargs): if self.empty(): raise EmptyException('This stack is empty') else: diff --git a/tests/all_pairs_shortest_paths_test.py b/tests/all_pairs_shortest_paths_test.py index e311d0d..a5bf18b 100644 --- a/tests/all_pairs_shortest_paths_test.py +++ b/tests/all_pairs_shortest_paths_test.py @@ -1,5 +1,4 @@ -from all_pairs_shortest_paths import extend_shortest_paths, slow_all_pairs_shortest_paths, \ - faster_all_pairs_shortest_paths +from all_pairs_shortest_paths import slow_all_pairs_shortest_paths, faster_all_pairs_shortest_paths import unittest import numpy as np diff --git a/tests/min_heap_with_linked_list_test.py b/tests/min_heap_with_linked_list_test.py index b81a39e..91c7202 100644 --- a/tests/min_heap_with_linked_list_test.py +++ b/tests/min_heap_with_linked_list_test.py @@ -83,12 +83,12 @@ def test_heap_extract_min(self): self.assertEqual(q, [L2, L4, L3, L5, L5]) # def test_heap_decrease_key(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) +# q = MinPriorityQueue(a) # q.heap_decrease_key(8, 1) # self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) # def test_heap_insert(self): # a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] -# q = min_priority_queue(a) +# q = MinPriorityQueue(a) # q.heap_extract_min() # q.min_heap_insert(0) # self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/tests/priority_queue_test.py b/tests/priority_queue_test.py index a5d3b55..5c21b0b 100644 --- a/tests/priority_queue_test.py +++ b/tests/priority_queue_test.py @@ -1,5 +1,5 @@ import unittest -from priority_queue import MaxPriorityQueue, min_priority_queue +from priority_queue import MaxPriorityQueue, MinPriorityQueue class TestMaxPriorityQueue(unittest.TestCase): @@ -59,28 +59,28 @@ def test_heap_delete(self): class TestMinPriorityQueue(unittest.TestCase): def test_init(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - q = min_priority_queue(a) + q = MinPriorityQueue(a) self.assertEqual(q, [1, 2, 3, 4, 7, 8, 9, 10, 14, 16]) def test_heap_minimum(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - self.assertEqual(min_priority_queue(a).heap_minimum(), 1) + self.assertEqual(MinPriorityQueue(a).heap_minimum(), 1) def test_heap_extract_min(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - q = min_priority_queue(a) + q = MinPriorityQueue(a) self.assertEqual(q.heap_extract_min(), 1) self.assertEqual(q, [2, 4, 3, 10, 7, 8, 9, 16, 14, 16]) def test_heap_decrease_key(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - q = min_priority_queue(a) + q = MinPriorityQueue(a) q.heap_decrease_key(8, 1) self.assertEqual(q, [1, 1, 3, 2, 7, 8, 9, 10, 4, 16]) def test_heap_insert(self): a = [1, 10, 3, 2, 7, 8, 9, 4, 14, 16] - q = min_priority_queue(a) + q = MinPriorityQueue(a) q.heap_extract_min() q.min_heap_insert(0) self.assertEqual(q, [0, 2, 3, 10, 4, 8, 9, 16, 14, 7]) diff --git a/two_sum.py b/two_sum.py index d6301e0..cb906c6 100644 --- a/two_sum.py +++ b/two_sum.py @@ -1,4 +1,4 @@ -def two_sum(x:int, array:list): +def two_sum(x: int, array: list): """ an algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x. From 0fc7b70b193143695d95ff2954d6c1d21f9e62c5 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 2 Jan 2021 17:30:12 +0800 Subject: [PATCH 26/49] conform to PEP8 --- Johnson.py | 12 ++-- any_disks_intersect.py | 2 +- any_segments_intersect.py | 6 +- bh_tree.py | 8 +-- binary_counter.py | 6 +- common-matrix-multiply-Strassen.py | 4 +- constraints.py | 12 ++-- depth_tree.py | 8 +-- fibonacciheap.py | 2 +- graph.py | 66 ++++++++++--------- hamiltonian_path.py | 6 +- huffman.py | 6 +- interval_graph_coloring.py | 4 +- interval_tree.py | 14 ++-- memoized_cut_rod.py | 3 +- merge_sort.py | 12 ++-- min_gap_tree.py | 16 ++--- min_heap_with_linked_list.py | 1 - min_priority_queue_using_rb_tree.py | 8 ++- most_reliable_path.py | 6 +- os_tree.py | 8 +-- partition.py | 46 ++++++------- pointer_tree.py | 8 +-- polygon_area.py | 15 ++--- randomized_permute.py | 4 +- rank_tree.py | 8 +-- rb_tree.py | 8 +-- right_horizontal_ray_intersect.py | 2 +- segment_intersect.py | 2 +- tests/merge_sort_test.py | 6 +- tests/min_gap_tree_test.py | 26 ++++---- .../min_priority_queue_using_rb_tree_test.py | 8 +-- tests/rb_tree_test.py | 26 ++++---- tests/test_gcd.py | 1 + three_sum.py | 20 +++--- vEB_tree.py | 2 +- 36 files changed, 206 insertions(+), 186 deletions(-) diff --git a/Johnson.py b/Johnson.py index 8108827..ca06c0e 100644 --- a/Johnson.py +++ b/Johnson.py @@ -18,7 +18,7 @@ def Bellman_Ford(self, w, s): :param s: :return: """ - initialize_signle_source(self, s) + initialize_single_source(self, s) for i in range(1, len(self.vertices)): for u, v in self.edges: relax(self, u, v, w) @@ -28,26 +28,26 @@ def Bellman_Ford(self, w, s): return True -def initialize_signle_source(self, s): +def initialize_single_source(self, s): for v in self.vertices: v.d = float("Inf") v.p = None s.d = 0 -def relax(self, u, v, w): +def relax(u, v, w): if v.d > u.d + w[u, v]: v.d = u.d + w[u, v] v.p = u def Dijkstra(self, w, s): - ''' + """ Dijkstra's algorithm solves the single-source shortest-paths problem on a weighted, directed graph G = (V, E) for the case in which all edge weights are nonnegative. - ''' - initialize_signle_source(self, s) + """ + initialize_single_source(self, s) S = set() Q = min_priority_queue(self.vertices, 'd') while Q.heap_size > 1: diff --git a/any_disks_intersect.py b/any_disks_intersect.py index e23f34b..1be9df4 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -112,7 +112,7 @@ def right_rotate(self, y): y.p = x def insert(self, z): - ''' the disk z will only be inserted when the left endpoint of z is being processed''' + """ the disk z will only be inserted when the left endpoint of z is being processed""" # this is the x_coordinate of the left endpoint of z x_coordinate = z[0][0] z = rb_node(z, None, None, None, 0) diff --git a/any_segments_intersect.py b/any_segments_intersect.py index a17367d..2c83064 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -12,7 +12,7 @@ def vertical(a): def comparable(a, b, x): - '''Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical ''' + """Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical """ p1 = a[0] p2 = a[1] p3 = b[0] @@ -153,7 +153,7 @@ def right_rotate(self, y): y.p = x def insert(self, z): - ''' the segment z will only be inserted when the left endpoint of z is being processed''' + """ the segment z will only be inserted when the left endpoint of z is being processed""" # this is the x_coordinate of the left endpoint of z x_coordinate = z[0][0] z = rb_node(z, None, None, None, 0) @@ -295,7 +295,7 @@ def delete_fixup(self, x): def any_segments_intersect(S): - '''This algorithm takes as input a set S of n line segments, returning the boolean value TRUE if any pair of segments in S intersects, and FALSE otherwise.''' + """This algorithm takes as input a set S of n line segments, returning the boolean value TRUE if any pair of segments in S intersects, and FALSE otherwise.""" T = rb_tree() segment_list = [] point_list = [] diff --git a/bh_tree.py b/bh_tree.py index 4e916c3..6bbf5f6 100644 --- a/bh_tree.py +++ b/bh_tree.py @@ -1,16 +1,16 @@ # A variant of red black tree that has black_height attribute # !/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class bh_node(rb_node): +class bh_node(RbNode): def __init__(self, key, p, left, right, color, bh): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.bh = bh -class bh_tree(rb_tree): +class bh_tree(RbTree): nil = bh_node(None, None, None, None, 1, 0) root = nil diff --git a/binary_counter.py b/binary_counter.py index f2a334f..e95701a 100644 --- a/binary_counter.py +++ b/binary_counter.py @@ -1,7 +1,7 @@ -class binary_counter(list): +class BinaryCounter(list): def __init__(self, size): self.leftmost_1 = -1 - list.__init__(self, [0] * size) + super(BinaryCounter, self).__init__([0] * size) def increment(self): i = 0 @@ -16,7 +16,7 @@ def increment(self): self.leftmost_1 = -1 def reset(self): - for i in range(0, self.leftmost_1 + 1): + for i in range(self.leftmost_1 + 1): self[i] = 0 self.leftmost_1 = -1 diff --git a/common-matrix-multiply-Strassen.py b/common-matrix-multiply-Strassen.py index f71fc02..61a0424 100644 --- a/common-matrix-multiply-Strassen.py +++ b/common-matrix-multiply-Strassen.py @@ -10,10 +10,10 @@ def common_matrix_multiply(A, B): - if (A.shape[1] != B.shape[0]): + if A.shape[1] != B.shape[0]: print("The width of matrix A not equal the height of matrix B.\nHence no matrix multiplication allowed") return - shape = (A.shape[0], B.shape[1]) + shape = A.shape[0], B.shape[1] # shape = A.shape length = shape[0] half = length / 2 diff --git a/constraints.py b/constraints.py index ff4a443..1e9cc41 100644 --- a/constraints.py +++ b/constraints.py @@ -3,12 +3,12 @@ def Bellman_Ford(G, w, s): - '''A variant to the original Bellman_Ford algorithm + """A variant to the original Bellman_Ford algorithm that we use to solve a system of difference constraints with m inequalities on n unknowns. The running time is O(nm), faster than O(n * n + nm) of the original Bellman-Ford algorithm. - ''' + """ edges = G.edges - set([(s, v) for v in G.adj[s]]) G.initialize_signle_source(s) j = 1 @@ -34,7 +34,7 @@ def initialize_signle_source(self, s): def difference_constraints(A, b): - '''A algorithm to solve a system of difference constraints Ax <= b + """A algorithm to solve a system of difference constraints Ax <= b by solving a single-source shortest-paths problem using Bellman-Ford algorithm. Each row of the linear-programming matrix A contains one 1 and one 1, and all other entries of A are 0. @@ -42,7 +42,7 @@ def difference_constraints(A, b): Calling convention: A is a two-dimensional list, b is a list. Return value: This function returns a list representing x if there exists feasible solution; otherwise, this function returns None. - ''' + """ row = len(A) col = len(A[0]) @@ -68,10 +68,10 @@ def difference_constraints(A, b): def difference_constraints_with_arbitrary_weight(A, b): - ''' An variant to the above difference constraints function + """ An variant to the above difference constraints function that the weight of the edge from the auxiliary vertex to any other vertex can be arbitrary value. - ''' + """ row = len(A) col = len(A[0]) vertices_num = col diff --git a/depth_tree.py b/depth_tree.py index c69b2d3..72e2107 100644 --- a/depth_tree.py +++ b/depth_tree.py @@ -2,12 +2,12 @@ # A variant of red black tree that has depth attribute -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class depth_node(rb_node): +class depth_node(RbNode): def __init__(self, key, p, left, right, color, depth): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.depth = depth def update_depth_whole_tree(self, amount): @@ -17,7 +17,7 @@ def update_depth_whole_tree(self, amount): self.right.update_depth_whole_tree(amount) -class depth_tree(rb_tree): +class depth_tree(RbTree): nil = depth_node(None, None, None, None, 1, -1) root = nil diff --git a/fibonacciheap.py b/fibonacciheap.py index bd3c242..778ddcc 100644 --- a/fibonacciheap.py +++ b/fibonacciheap.py @@ -82,7 +82,7 @@ def remove_child(self, y): y.remove() -class FibonacciHeap(object): +class FibonacciHeap: def __init__(self): self.n = 0 self.minimum = None diff --git a/graph.py b/graph.py index afc3a27..964840d 100644 --- a/graph.py +++ b/graph.py @@ -180,11 +180,11 @@ def printAllEdges_aux(self, u): print((v, u)) def path_num(self, s, t): - ''' + """ A linear-time algorithm that takes as input a directed acyclic graph G = (V, E) and two vertices s and t, and returns the number of simple paths from s to t in G. - ''' + """ for u in self.vertices: u.color = 0 u.num = 0 @@ -231,9 +231,11 @@ def strongly_connected_components_dfs_visit(self, u): u.f = time def simplified(self): - '''create a simplified graph that has the same strong + """ + create a simplified graph that has the same strong connected components and component graph as G and that is as small - as possible''' + as possible + """ self.dfs() t = self.transpose() return t.simplified_dfs() @@ -335,10 +337,12 @@ def semiconnected(self): return True def cut(self, x, y, w): - '''For a given edge (x, y) contained in some minimum spanning tree, + """ + For a given edge (x, y) contained in some minimum spanning tree, form a minimum spanning tree that contains (x, y) using a method like Prim's algorithm, and construct a cut (S, V - S) such that (x, y) is the light edge crossing - the cut, S = {u: u.root = x}''' + the cut, S = {u: u.root = x} + """ for v in self.vertices: v.weight = float("Inf") v.p = None @@ -396,9 +400,11 @@ def Kruskal(self, w): return A def Prim(self, w, r): - '''G.Prim(weight, root) -- Given weight function + """ + G.Prim(weight, root) -- Given weight function and an arbitrary vertex root of the graph G, - compute minimum spanning tree using Prim's algorithm''' + compute minimum spanning tree using Prim's algorithm + """ for v in self.vertices: v.weight = float("Inf") v.p = None @@ -412,9 +418,9 @@ def Prim(self, w, r): q.heap_decrease_key(v.index, w(u, v)) # def Prim_vEB(self, w, r, bound): - # '''G.Prim(weight, root) -- Given weight function + # """G.Prim(weight, root) -- Given weight function # and an arbitrary vertex root of the graph G, - # compute minimum spanning tree using Prim's algorithm''' + # compute minimum spanning tree using Prim's algorithm""" # for v in self.vertices: # v.weight = bound - 1 # v.p = None @@ -432,7 +438,7 @@ def Prim(self, w, r): # v.weight = w(u, v) # t.insert(v) def Bellman_Ford(self, w, s): - ''' + """ The Bellman-Ford algorithm solves the single-source shortest-paths problem in the general case in which edge weights may be negative. @@ -441,7 +447,7 @@ def Bellman_Ford(self, w, s): no solution exists. If there is no such cycle, this function returns True and produces the shortest paths and their weights. - ''' + """ self.initialize_signle_source(s) for i in range(1, len(self.vertices)): for u, v in self.edges: @@ -463,14 +469,14 @@ def relax(self, u, v, w): v.p = u def Bellman_Ford_modified(self, w, s): - ''' + """ Given a weighted, directed graph G = (V, E) with no negative-weight cycles, let m be the maximum over all vertices v of the minimum number of edges in a shortest path from the source s to v. This variant to the Bellman-Ford algorithm terminates in m + 1 passes, even if m is not known in advance. - ''' + """ modified = True number = 0 self.initialize_signle_source(s) @@ -497,10 +503,10 @@ def relax_modified(self, u, v, w): return 0 def dag_shortest_paths(self, w, s): - ''' + """ compute shortest paths from a single source s for a directed acyclic graph with a weight function w - ''' + """ l = self.topological_sort() self.initialize_signle_source(s) for u in l: @@ -508,7 +514,7 @@ def dag_shortest_paths(self, w, s): self.relax(u, v, w) def dag_shortest_paths_modified(self, s): - ''' + """ In the PERT chart analysis, vertices repre sent jobs and edges represent sequencing contraints; that is, edge (u, v) would @@ -522,7 +528,7 @@ def dag_shortest_paths_modified(self, s): vertices in linear time. This function return a list of vertices in a longest path - ''' + """ sink = Vertex("sink") vertices = self.vertices.union({sink}) edges = self.edges.union(set([(v, sink) for v in G.vertices])) @@ -536,10 +542,10 @@ def dag_shortest_paths_modified(self, s): return l[::-1] def total_path_number(self): - ''' + """ A algorithm to count the total number of paths in a directed acyclic graph - ''' + """ number = 0 self._total_path_number_dfs() for v in self.vertices: @@ -572,11 +578,11 @@ def _total_path_number_dfs_visit(self, u): u.f = time def Dijkstra(self, w, s): - ''' + """ Dijkstra's algorithm solves the single-source shortest-paths problem on a weighted, directed graph G = (V, E) for the case in which all edge weights are nonnegative. - ''' + """ self.initialize_signle_source(s) S = set() Q = min_priority_queue(self.vertices, 'd') @@ -590,11 +596,11 @@ def Dijkstra(self, w, s): Q.heap_decrease_key(v.index, u.d + w(u, v)) def Dijkstra_modified(self, w, s, W): - ''' + """ A algorithm to the the case when the values of the weight function w is in the range {0, 1, ..., W} for some nonnegative integer W. - ''' + """ self.initialize_signle_source(s) A = [] for i in range(0, W * len(self.vertices) + 1): @@ -621,14 +627,14 @@ def Dijkstra_modified(self, w, s, W): v.p = u def single_edge(self): - ''' + """ An algorithm that given an adjacency-list representation of a multigraph G = (V, E), compute the adjacency-list representation of the "equivalent" undirected graph G2 = (V, E2), where E2 consists of the edges in E with all multiple edges between two vertices replaced by a single edge and with all self-loops removed - ''' + """ return Graph(self.vertices, self.edges, directed=False) def union(self, G2): @@ -640,12 +646,12 @@ def union(self, G2): return Graph(vertices, edges, directed=self.directed) def square(self): - ''' + """ The square of a directed graph G = (V, E) is the graph G^2 = (V, E^2) such that (u, v) belongs to E^2 if and only if G contains a path with at most two edges between u and v. - ''' + """ sqrt = self.copy() for u in self.vertices: for v in self.adj[u]: @@ -767,10 +773,10 @@ def max_heap_insert(self, element): class min_heap(list): def __init__(self, data, attr): - ''' + """ data: input data for heap attr: the attribute of input date used as compare key - ''' + """ list.__init__(self, data) for i in range(0, len(data)): self[i].index = i diff --git a/hamiltonian_path.py b/hamiltonian_path.py index e02e201..a7c690f 100644 --- a/hamiltonian_path.py +++ b/hamiltonian_path.py @@ -1,13 +1,17 @@ #!/usr/bin/env python + def hamiltonian_path(G, u, v): - '''An algorithm to the hamiltonian-path problem on directed acyclic graphs''' + """ + An algorithm to the hamiltonian-path problem on directed acyclic graphs + """ we = dict() for i in G.edges: we[i] = -1 def w(x, y): return we[(x, y)] + G.dag_shortest_paths(w, u) if abs(v.d) == len(G.vertices) - 1: return True diff --git a/huffman.py b/huffman.py index cf4473a..716897f 100644 --- a/huffman.py +++ b/huffman.py @@ -148,9 +148,11 @@ def decode_compact_prefix_code(store): def huffman_tenary(chars, freqs, m): - ''' generalize Huffman's algorithm to tenary codewords + """ + generalize Huffman's algorithm to tenary codewords the parameter m is the number of symbols we use, eg, in - original huffman algorithm, we use 0 and 1, so m = 2''' + original huffman algorithm, we use 0 and 1, so m = 2 + """ n = len(chars) c = [0] * n for i in range(0, n): diff --git a/interval_graph_coloring.py b/interval_graph_coloring.py index 2125273..cc0faf9 100644 --- a/interval_graph_coloring.py +++ b/interval_graph_coloring.py @@ -1,5 +1,7 @@ def interval_graph_coloring(graph): - '''The input graph is represented as an adjacency matrix since all we need is edge information about the graph''' + """ + The input graph is represented as an adjacency matrix since all we need is edge information about the graph + """ m = graph.shape[0] color = [1] * m number = 1 diff --git a/interval_tree.py b/interval_tree.py index 2ddb448..9c5ba0d 100755 --- a/interval_tree.py +++ b/interval_tree.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree class interval(object): @@ -9,9 +9,9 @@ def __init__(self, low, high): self.high = high -class interval_node(rb_node): +class interval_node(RbNode): def __init__(self, key, p, left, right, color, interval, maximum): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.interval = interval self.maximum = maximum @@ -40,7 +40,7 @@ def interval_search_exactly(self, T, i): return T.nil -class interval_tree(rb_tree): +class interval_tree(RbTree): nil = interval_node(None, None, None, None, 1, None, float("-Inf")) root = nil @@ -150,8 +150,10 @@ def closed_interval_search(self, interval): return x def closed_interval_search_minimum_low_end(self, interval): - '''given an interval, returns an interval over- - lapping i that has the minimum low endpoint, or T.nil if no such interval exists''' + """ + given an interval, returns an interval over- + lapping i that has the minimum low endpoint, or T.nil if no such interval exists + """ x = self.root overlap = False i = self.nil diff --git a/memoized_cut_rod.py b/memoized_cut_rod.py index 86a608c..3f5da3e 100644 --- a/memoized_cut_rod.py +++ b/memoized_cut_rod.py @@ -2,6 +2,7 @@ def memoized_cut_rod(p, n): r = [float("-Inf")] * (n + 1) return memoized_cut_rod_aux(p, n, r) + def memoized_cut_rod_aux(p, n, r): if r[n] >= 0: return r[n] @@ -13,5 +14,3 @@ def memoized_cut_rod_aux(p, n, r): q = max(q, p[i - 1] + memoized_cut_rod_aux(p, n - i, r)) r[n] = q return q - - diff --git a/merge_sort.py b/merge_sort.py index c879a73..00760e1 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -77,7 +77,7 @@ def _merge_sort(array, left, right, merge_method): merge_method(array, left, mid, right) -def merge_ins_sort(array, partition: int = 2): +def merge_ins_sort_bottom_to_top(array, partition: int = 2): """ Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines. @@ -106,7 +106,7 @@ def merge_ins_sort(array, partition: int = 2): sublist_number = sublist_number // 2 -def merge_ins_sort2(array, sublist_length): +def merge_ins_sort_top_to_bottom(array, sublist_length): """ Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines. @@ -121,10 +121,10 @@ def merge_ins_sort2(array, sublist_length): """ n = len(array) assert 0 < sublist_length < n - _merge_ins_sort2(array, 0, n - 1, sublist_length) + _merge_ins_sort_top_to_bottom(array, 0, n - 1, sublist_length) -def _merge_ins_sort2(array, start, end, sublist_length): +def _merge_ins_sort_top_to_bottom(array, start, end, sublist_length): """ :param array: @@ -136,8 +136,8 @@ def _merge_ins_sort2(array, start, end, sublist_length): length = end - start + 1 if length > sublist_length: mid = (start + end) // 2 - _merge_ins_sort2(array, start, mid, sublist_length) - _merge_ins_sort2(array, mid + 1, end, sublist_length) + _merge_ins_sort_top_to_bottom(array, start, mid, sublist_length) + _merge_ins_sort_top_to_bottom(array, mid + 1, end, sublist_length) merge_with_sentinel(array, start, mid, end) else: insertion_sort(array, start, end) diff --git a/min_gap_tree.py b/min_gap_tree.py index afc7157..c47891f 100644 --- a/min_gap_tree.py +++ b/min_gap_tree.py @@ -1,26 +1,26 @@ #!/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class min_gap_node(rb_node): +class MinGapNode(RbNode): def __init__(self, key, p, left, right, color, successor, min_gap): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.successor = successor self.min_gap = min_gap -class min_gap_tree(rb_tree): - positive_infinity = min_gap_node( +class MinGapTree(RbTree): + positive_infinity = MinGapNode( float("Inf"), None, None, None, 1, None, float("Inf")) - nil = min_gap_node(None, None, None, None, 1, - positive_infinity, float("Inf")) + nil = MinGapNode(None, None, None, None, 1, + positive_infinity, float("Inf")) root = nil def __init__(self, values): if isinstance(values, list): for i in values: - self.insert(min_gap_node(i, None, None, None, 0, None, None)) + self.insert(MinGapNode(i, None, None, None, 0, None, None)) else: print("Not invalid argument") diff --git a/min_heap_with_linked_list.py b/min_heap_with_linked_list.py index d23a3a7..9eebd03 100644 --- a/min_heap_with_linked_list.py +++ b/min_heap_with_linked_list.py @@ -1,4 +1,3 @@ -from linkedlist import LinkedListNode, LinkedList import sys diff --git a/min_priority_queue_using_rb_tree.py b/min_priority_queue_using_rb_tree.py index e591e7e..dea6c42 100644 --- a/min_priority_queue_using_rb_tree.py +++ b/min_priority_queue_using_rb_tree.py @@ -1,18 +1,22 @@ -from rb_tree import rb_tree +from rb_tree import RbTree import sys -class min_priority_queue(rb_tree): + +class min_priority_queue(RbTree): def heap_minimum(self): return self.minimum() + def heap_extract_min(self): x = self.minimum() self.delete(x) return x + def heap_decrease_key(self, node, key): if key > node.key: sys.exit("new key is larger than current key") self.delete(node) node.key = key self.insert(node) + def min_heap_insert(self, node): self.insert(node) diff --git a/most_reliable_path.py b/most_reliable_path.py index 2a102bb..988e2b5 100644 --- a/most_reliable_path.py +++ b/most_reliable_path.py @@ -1,7 +1,8 @@ from graph import max_priority_queue + def most_reliable_path(G, r, s): - ''' + """ We are given a directed graph G = (V, E) on which each edge (u, v) that belongs to E has an associated value r(u, v), which is a real number in the range @@ -16,7 +17,7 @@ def most_reliable_path(G, r, s): s: the source r: the function that returns the probability that the channel from u to v will not fail. - ''' + """ initialize_single_source(G, s) S = set() Q = max_priority_queue(G.vertices, 'r') @@ -29,6 +30,7 @@ def most_reliable_path(G, r, s): v.p = u Q.heap_increase_key(v.index, u.r * r(u, v)) + def initialize_single_source(G, s): for v in G.vertices: v.r = 0 diff --git a/os_tree.py b/os_tree.py index 45cbc07..46cd716 100755 --- a/os_tree.py +++ b/os_tree.py @@ -1,11 +1,11 @@ #!/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class OSNode(rb_node): +class OSNode(RbNode): def __init__(self, key, p, left, right, color, size): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.size = size def select_recursive(self, i): @@ -54,7 +54,7 @@ def ith_successor(self, i): return y.ith_successor(i - r - 1) -class os_tree(rb_tree): +class os_tree(RbTree): nil = OSNode(None, None, None, None, 1, 0) root = nil diff --git a/partition.py b/partition.py index d335eba..07a7a40 100644 --- a/partition.py +++ b/partition.py @@ -1,62 +1,62 @@ import random -def partition(A, p, r): - x = A[r] +def partition(array, p, r): + x = array[r] i = p - 1 for j in range(p, r): - if A[j] <= x: + if array[j] <= x: i = i + 1 - A[i], A[j] = A[j], A[i] - A[i + 1], A[r] = A[r], A[i + 1] + array[i], array[j] = array[j], array[i] + array[i + 1], array[r] = array[r], array[i + 1] return i + 1 -def partition2(A, p, r): +def partition2(array, p, r): """ Partition A into three parts: < x, = x, > x. The return value is the median of the second part. So the return value is floor((p + r) / 2) when all elements in the array A[p .. r] have the same value. Partition in place. """ - x = A[r] + x = array[r] i = p - 1 k = i for j in range(p, r): - if A[j] < x: + if array[j] < x: i = i + 1 - A[i], A[j] = A[j], A[i] + array[i], array[j] = array[j], array[i] k = k + 1 if i != k: - A[j], A[k] = A[k], A[j] - elif A[j] == x: + array[j], array[k] = array[k], array[j] + elif array[j] == x: k = k + 1 - A[k], A[j] = A[j], A[k] - A[k + 1], A[r] = A[r], A[k + 1] + array[k], array[j] = array[j], array[k] + array[k + 1], array[r] = array[r], array[k + 1] return (k + 2 + i) // 2 -def partition3(A, p, r): +def partition3(array, p, r): """ Variant of partition2. Requires O(n) extra space, but it is easier to implement. """ - x = A[r] + x = array[r] n = r - p + 1 i = -1 k = n B = [0] * n for j in range(p, r): - if A[j] < x: + if array[j] < x: i = i + 1 - B[i] = A[j] - elif A[j] > x: + B[i] = array[j] + elif array[j] > x: k = k - 1 - B[k] = A[j] + B[k] = array[j] for j in range(i + 1, k): B[j] = x for j in range(p, r + 1): - A[j] = B[j - p] + array[j] = B[j - p] return (2 * p + i + k) // 2 -def randomized_partition(A, p, r): +def randomized_partition(array, p, r): i = random.randint(p, r) - A[i], A[r] = A[r], A[i] - return partition(A, p, r) + array[i], array[r] = array[r], array[i] + return partition(array, p, r) diff --git a/pointer_tree.py b/pointer_tree.py index 01df858..aeae9c1 100644 --- a/pointer_tree.py +++ b/pointer_tree.py @@ -1,18 +1,18 @@ #!/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class pointer_node(rb_node): +class pointer_node(RbNode): def __init__(self, key, p, left, right, color, minimum, maximum, predecessor, successor): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.minimum = minimum self.maximum = maximum self.predecessor = predecessor self.successor = successor -class pointer_tree(rb_tree): +class pointer_tree(RbTree): negative_infinity = pointer_node( float("-Inf"), None, None, None, 1, None, None, None, None) positive_infinity = pointer_node( diff --git a/polygon_area.py b/polygon_area.py index ce406bc..65cb061 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -1,11 +1,10 @@ #!/usr/bin/env python - -def polygon_area(P): - n = len(P) - S = 0 - for i in range(0, n - 1): - S = S + (P[i][0] + P[i + 1][0]) * (P[i + 1][1] - P[i][1]) - S = S + (P[0][0] + P[n - 1][0]) * (P[0][1] - P[n - 1][1]) - return 0.5 * abs(S) +def polygon_area(polygon): + n = len(polygon) + area = 0 + for i in range(n - 1): + area = area + (polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) + area = area + (polygon[0][0] + polygon[n - 1][0]) * (polygon[0][1] - polygon[n - 1][1]) + return 0.5 * abs(area) diff --git a/randomized_permute.py b/randomized_permute.py index b1d05c6..fef9550 100644 --- a/randomized_permute.py +++ b/randomized_permute.py @@ -1,10 +1,10 @@ import random def randomize_in_place(A): - ''' + """ An algorithm to permute the given array in place. It computes a uniform random permutation. - ''' + """ n = len(A) for i in range(0, n): j = random.randint(i, n - 1) diff --git a/rank_tree.py b/rank_tree.py index ea48257..5c1e8e5 100644 --- a/rank_tree.py +++ b/rank_tree.py @@ -1,12 +1,12 @@ # The variant of os_tree that use rank instead of size # !/usr/bin/env python -from rb_tree import rb_node, rb_tree +from rb_tree import RbNode, RbTree -class rank_node(rb_node): +class rank_node(RbNode): def __init__(self, key, p, left, right, color, rank): - rb_node.__init__(self, key, p, left, right, color) + RbNode.__init__(self, key, p, left, right, color) self.rank = rank def update_rank_whole_tree(self, amount): @@ -27,7 +27,7 @@ def decrease_all_successors(self, amount): y.decrease_all_successors(amount) -class rank_tree(rb_tree): +class rank_tree(RbTree): nil = rank_node(None, None, None, None, 1, 0) root = nil diff --git a/rb_tree.py b/rb_tree.py index aaa9153..77a33c9 100644 --- a/rb_tree.py +++ b/rb_tree.py @@ -5,7 +5,7 @@ from tree import Node, Tree -class rb_node(Node): +class RbNode(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color @@ -19,14 +19,14 @@ def minimum(self, nil): return y -class rb_tree(Tree): - nil = rb_node(None, None, None, None, 1) +class RbTree(Tree): + nil = RbNode(None, None, None, None, 1) root = nil def __init__(self, values): if isinstance(values, list): for i in values: - self.insert(rb_node(i, None, None, None, 0)) + self.insert(RbNode(i, None, None, None, 0)) else: print("Not invalid argument") diff --git a/right_horizontal_ray_intersect.py b/right_horizontal_ray_intersect.py index 9316ffb..0f2c43f 100644 --- a/right_horizontal_ray_intersect.py +++ b/right_horizontal_ray_intersect.py @@ -4,7 +4,7 @@ def right_horizontal_ray_intersect(p0, p1, p2): - '''An algorithm to determine whether a given right horizontal ray from p0 intersects a line segment p1p2''' + """An algorithm to determine whether a given right horizontal ray from p0 intersects a line segment p1p2""" max_x = max(p1[0], p2[0]) if max_x < p0[0]: return False diff --git a/segment_intersect.py b/segment_intersect.py index 8559da4..413ef87 100644 --- a/segment_intersect.py +++ b/segment_intersect.py @@ -6,7 +6,7 @@ def segments_intersect(p1, p2, p3, p4): d2 = direction(p3, p4, p2) d3 = direction(p1, p2, p3) d4 = direction(p1, p2, p4) - if ((d1 > 0 and d2 < 0) or (d1 < 0 and d2 > 0)) and ((d3 > 0 and d4 < 0) or (d3 < 0 and d4 > 0)): + if ((d1 > 0 > d2) or (d1 < 0 < d2)) and ((d3 > 0 > d4) or (d3 < 0 < d4)): return True elif d1 == 0 and on_segment(p3, p4, p1): return True diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 2b09e49..881c64e 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort, merge_ins_sort2 +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, merge_ins_sort_top_to_bottom class TestMergeSort(unittest.TestCase): @@ -23,10 +23,10 @@ def test_merge_ins_sort(self): for length in range(100, 200): array = [random.randint(1, 10000) for _ in range(length)] array_copy = array[:] - merge_ins_sort(array, partition=1) + merge_ins_sort_bottom_to_top(array, partition=1) self.assertEqual(array, sorted(array_copy)) for length in range(100, 200): array = [random.randint(1, 10000) for _ in range(length)] array_copy = array[:] - merge_ins_sort2(array, sublist_length=15) + merge_ins_sort_top_to_bottom(array, sublist_length=15) self.assertEqual(array, sorted(array_copy)) diff --git a/tests/min_gap_tree_test.py b/tests/min_gap_tree_test.py index ea1b5e1..2bcf352 100755 --- a/tests/min_gap_tree_test.py +++ b/tests/min_gap_tree_test.py @@ -1,33 +1,33 @@ #!/usr/bin/env python import unittest -from min_gap_tree import min_gap_tree, min_gap_node +from min_gap_tree import MinGapTree, MinGapNode class TestMinGapTree(unittest.TestCase): def test_insert_one(self): - T = min_gap_tree([50]) + T = MinGapTree([50]) self.wrap(T, 50, float("Inf")) def test_insert_two(self): - T = min_gap_tree([50, 38]) + T = MinGapTree([50, 38]) self.wrap(T, 50, 12) self.wrap(T, 38, 12) def test_insert_three(self): - T = min_gap_tree([50, 38, 31]) + T = MinGapTree([50, 38, 31]) self.wrap(T, 38, 7) self.wrap(T, 31, 7) self.wrap(T, 50, float("Inf")) def test_insert_four(self): - T = min_gap_tree([50, 38, 31, 12]) + T = MinGapTree([50, 38, 31, 12]) self.wrap(T, 38, 7) self.wrap(T, 31, 7) self.wrap(T, 50, float("Inf")) self.wrap(T, 12, 19) def test_insert_five(self): - T = min_gap_tree([50, 38, 31, 12, 19]) + T = MinGapTree([50, 38, 31, 12, 19]) self.wrap(T, 38, 7) self.wrap(T, 19, 7) self.wrap(T, 50, float("Inf")) @@ -35,7 +35,7 @@ def test_insert_five(self): self.wrap(T, 31, 7) def test_insert_six(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) self.wrap(T, 38, 3) self.wrap(T, 19, 3) self.wrap(T, 50, float("Inf")) @@ -44,7 +44,7 @@ def test_insert_six(self): self.wrap(T, 9, 3) def test_delete_one(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) self.wrap(T, 38, 7) self.wrap(T, 19, 7) @@ -53,7 +53,7 @@ def test_delete_one(self): self.wrap(T, 31, 7) def test_delete_two(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) self.wrap(T, 38, 7) @@ -62,7 +62,7 @@ def test_delete_two(self): self.wrap(T, 31, 7) def test_delete_three(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -71,7 +71,7 @@ def test_delete_three(self): self.wrap(T, 50, float("Inf")) def test_delete_four(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -80,7 +80,7 @@ def test_delete_four(self): self.wrap(T, 50, float("Inf")) def test_delete_five(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -89,7 +89,7 @@ def test_delete_five(self): self.wrap(T, 50, float("Inf")) def test_delete_six(self): - T = min_gap_tree([50, 38, 31, 12, 19, 9]) + T = MinGapTree([50, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) diff --git a/tests/min_priority_queue_using_rb_tree_test.py b/tests/min_priority_queue_using_rb_tree_test.py index 1e1238b..5bdbb4e 100644 --- a/tests/min_priority_queue_using_rb_tree_test.py +++ b/tests/min_priority_queue_using_rb_tree_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import unittest from min_priority_queue_using_rb_tree import min_priority_queue -from rb_tree import rb_node +from rb_tree import RbNode class TestMinPriorityQueue(unittest.TestCase): @@ -27,9 +27,9 @@ def test_heap_decrease_key(self): def test_heap_insert(self): q = min_priority_queue([41, 38, 31, 12, 19, 9]) - q.min_heap_insert(rb_node(5, None, None, None, 0)) - q.min_heap_insert(rb_node(38, None, None, None, 0)) - q.min_heap_insert(rb_node(50, None, None, None, 0)) + q.min_heap_insert(RbNode(5, None, None, None, 0)) + q.min_heap_insert(RbNode(38, None, None, None, 0)) + q.min_heap_insert(RbNode(50, None, None, None, 0)) self.assertEqual(q.heap_extract_min().key, 5) self.assertEqual(q.heap_extract_min().key, 9) self.assertEqual(q.heap_extract_min().key, 12) diff --git a/tests/rb_tree_test.py b/tests/rb_tree_test.py index 76e9fa7..36a6a58 100755 --- a/tests/rb_tree_test.py +++ b/tests/rb_tree_test.py @@ -1,25 +1,25 @@ #!/usr/bin/env python import unittest -from rb_tree import rb_tree, rb_node +from rb_tree import RbTree, RbNode class TestRbtree(unittest.TestCase): def test_insert_one(self): - T = rb_tree([41]) + T = RbTree([41]) print(T.root.iterative_tree_search(41).p.key) self.assertEqual(T.root, T.root.iterative_tree_search(41)) self.assertEqual(T.nil.color, 1) self.wrap(T, 41, -1, -1, -1, 1) def test_insert_two(self): - T = rb_tree([41, 38]) + T = RbTree([41, 38]) self.assertEqual(T.root, T.iterative_tree_search(41)) self.assertEqual(T.nil.color, 1) self.wrap(T, 41, 38, -1, -1, 1) self.wrap(T, 38, -1, -1, 41, 0) def test_insert_three(self): - T = rb_tree([41, 38, 31]) + T = RbTree([41, 38, 31]) self.assertEqual(T.root, T.iterative_tree_search(38)) self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 31, 41, -1, 1) @@ -27,7 +27,7 @@ def test_insert_three(self): self.wrap(T, 41, -1, -1, 38, 0) def test_insert_four(self): - T = rb_tree([41, 38, 31, 12]) + T = RbTree([41, 38, 31, 12]) self.assertEqual(T.root, T.iterative_tree_search(38)) self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 31, 41, -1, 1) @@ -36,7 +36,7 @@ def test_insert_four(self): self.wrap(T, 12, -1, -1, 31, 0) def test_insert_five(self): - T = rb_tree([41, 38, 31, 12, 19]) + T = RbTree([41, 38, 31, 12, 19]) self.assertEqual(T.root, T.iterative_tree_search(38)) self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 19, 41, -1, 1) @@ -46,7 +46,7 @@ def test_insert_five(self): self.wrap(T, 31, -1, -1, 19, 0) def test_insert_six(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) self.assertEqual(T.root, T.iterative_tree_search(38)) self.assertEqual(T.nil.color, 1) self.wrap(T, 38, 19, 41, -1, 1) @@ -57,7 +57,7 @@ def test_insert_six(self): self.wrap(T, 9, -1, -1, 12, 0) def test_delete_one(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) self.wrap(T, 38, 19, 41, -1, 1) self.wrap(T, 19, 12, 31, 38, 0) @@ -66,7 +66,7 @@ def test_delete_one(self): self.wrap(T, 31, -1, -1, 19, 1) def test_delete_two(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) self.wrap(T, 38, 19, 41, -1, 1) @@ -75,7 +75,7 @@ def test_delete_two(self): self.wrap(T, 31, -1, -1, 19, 0) def test_delete_three(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -84,7 +84,7 @@ def test_delete_three(self): self.wrap(T, 41, -1, -1, 38, 1) def test_delete_four(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -93,7 +93,7 @@ def test_delete_four(self): self.wrap(T, 41, -1, -1, 38, 0) def test_delete_five(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) @@ -102,7 +102,7 @@ def test_delete_five(self): self.wrap(T, 41, -1, -1, -1, 1) def test_delete_six(self): - T = rb_tree([41, 38, 31, 12, 19, 9]) + T = RbTree([41, 38, 31, 12, 19, 9]) T.delete(T.iterative_tree_search(9)) T.delete(T.iterative_tree_search(12)) T.delete(T.iterative_tree_search(19)) diff --git a/tests/test_gcd.py b/tests/test_gcd.py index 1829945..8a2d9f2 100644 --- a/tests/test_gcd.py +++ b/tests/test_gcd.py @@ -10,3 +10,4 @@ def test_gcd(self): self.assertEqual(gcd(10, 3), 1) self.assertEqual(gcd(10, 4), 2) self.assertEqual(gcd(10, 1), 1) + self.assertEqual(gcd(10, 5), 5) diff --git a/three_sum.py b/three_sum.py index 4fec1d0..6387f4a 100644 --- a/three_sum.py +++ b/three_sum.py @@ -1,23 +1,23 @@ #!/usr/bin/env python # coding=utf-8 -def threeSum(A): - '''Given an array A of n integers, find one triplet + +def three_sum(array): + """ + Given an array `array` of n integers, find one triplet in the array which gives the sum of zero. - A must be in increasing order''' - n = len(A) + `array` must be in increasing order + """ + n = len(array) for i in range(n - 2): j = i + 1 k = n - 1 while k >= j: - if A[i] + A[j] + A[k] == 0: - return (A[i], A[j], A[k]) - elif A[i] + A[j] + A[k] > 0: + if array[i] + array[j] + array[k] == 0: + return array[i], array[j], array[k] + elif array[i] + array[j] + array[k] > 0: k = k - 1 else: j = j + 1 - - - diff --git a/vEB_tree.py b/vEB_tree.py index 357e318..3778b22 100644 --- a/vEB_tree.py +++ b/vEB_tree.py @@ -5,7 +5,7 @@ class vEB_node(object): def __init__(self, u): - '''u must be exact power of 2, as required by CLRS; otherwise, the behavior is undefined''' + """u must be exact power of 2, as required by CLRS; otherwise, the behavior is undefined""" self.u = u self.min = None self.max = None From e983987a891f1ff0f48fdb0b231e749d9bc2ec08 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 3 Jan 2021 17:31:11 +0800 Subject: [PATCH 27/49] quicksort partition with extra space --- Bellman_Ford_matrix.py | 10 ++-- activity_selection.py | 4 +- closest_points.py | 10 ++-- closest_points_l1_distance.py | 10 ++-- closest_points_l_infinite_distance.py | 10 ++-- constraints.py | 20 +++---- counting_sort.py | 4 +- fft.py | 6 +-- graph.py | 10 ++-- hash.py | 2 +- huffman.py | 8 +-- insertion_sort.py | 22 +++----- interpolation.py | 6 +-- interval_graph_coloring.py | 4 +- knapsack_0_1.py | 4 +- kth-Quantiles.py | 4 +- longest_palindrome_subsequence.py | 2 +- partition.py | 76 ++++++++++++--------------- polynomial_multiply.py | 8 +-- quicksort.py | 24 ++++----- randomized_permute.py | 7 +-- selection_sort.py | 4 +- simplex.py | 4 +- single_edge.py | 18 +++---- tests/bubble_sort_test.py | 2 +- tests/counting_sort_test.py | 2 +- tests/cut_rod_test.py | 10 ++-- tests/insertion_sort_test.py | 8 +-- tests/k_way_merge_test.py | 6 +-- tests/merge_sort_test.py | 4 +- tests/partition_test.py | 17 +++--- tests/quicksort_test.py | 48 ++++++++--------- tests/random_array.py | 6 +++ tests/selection_sort_test.py | 5 +- tree.py | 2 +- 35 files changed, 192 insertions(+), 195 deletions(-) create mode 100644 tests/random_array.py diff --git a/Bellman_Ford_matrix.py b/Bellman_Ford_matrix.py index 6867850..21d547d 100644 --- a/Bellman_Ford_matrix.py +++ b/Bellman_Ford_matrix.py @@ -18,8 +18,8 @@ def Bellman_Ford_matrix(W, s): def extend_shortest_paths(L, W): n = W.shape[0] LW = [float("Inf")] * n - for j in range(0, n): - for k in range(0, n): + for j in range(n): + for k in range(n): LW[j] = min(LW[j], L[k] + W[k, j]) return LW @@ -27,7 +27,7 @@ def extend_shortest_paths(L, W): def slow_all_pairs_shortest_paths(W, s): n = W.shape[0] L = [0] * n - for i in range(0, n): + for i in range(n): if i + 1 == s: L[i] = 0 else: @@ -43,8 +43,8 @@ def extend_shortest_paths_with_predecessor_subgraph(s, L, P, W): n = W.shape[0] LW = [float("Inf")] * n PP = [None] * n - for j in range(0, n): - for k in range(0, n): + for j in range(n): + for k in range(n): if LW[j] > L[k] + W[k, j]: LW[j] = L[k] + W[k, j] PP[j] = k + 1 diff --git a/activity_selection.py b/activity_selection.py index 2e24de7..199ec58 100644 --- a/activity_selection.py +++ b/activity_selection.py @@ -7,7 +7,7 @@ def activity_selection(s, f, n): s = [float("-Inf")] + s[0:n] + [float("Inf")] f = [float("-Inf")] + f[0:n] + [float("Inf")] for l in range(3, n + 3): - for i in range(0, n + 3 - l): + for i in range(n + 3 - l): j = i + l - 1 print("i = {}, j = {}".format(i, j)) for k in range(i + 1, j): @@ -34,7 +34,7 @@ def activity_selection_with_weight(s, f, v, n): s = [float("-Inf")] + s[0:n] + [float("Inf")] f = [float("-Inf")] + f[0:n] + [float("Inf")] for l in range(3, n + 3): - for i in range(0, n + 3 - l): + for i in range(n + 3 - l): j = i + l - 1 for k in range(i + 1, j): if f[i] <= s[k] and f[k] <= s[j]: diff --git a/closest_points.py b/closest_points.py index 7aec8da..2ad5163 100644 --- a/closest_points.py +++ b/closest_points.py @@ -17,7 +17,7 @@ def y_sort(S): YY = MaxHeap(Y) YY.heapsort() Y = [] - for i in range(0, len(YY)): + for i in range(len(YY)): Y.append((YY[i][1], YY[i][0])) return Y @@ -29,7 +29,7 @@ def distance(p1, p2): def brute_force(P): P = list(P) d = float("Inf") - for i in range(0, len(P)): + for i in range(len(P)): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d @@ -53,7 +53,7 @@ def closest_points_aux(P, X, Y): l = X[half - 1][0] YL = [] YR = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if Y[i] in PL: YL.append(Y[i]) else: @@ -62,11 +62,11 @@ def closest_points_aux(P, X, Y): dr = closest_points_aux(PR, XR, YR) d1 = min(dl, dr) YY = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if abs(Y[i][0] - l) < d1: YY.append(Y[i]) d2 = float("Inf") - for i in range(0, len(YY)): + for i in range(len(YY)): for j in range(1, 10): if i + j < len(YY): d2 = min(distance(YY[i], YY[i + j]), d2) diff --git a/closest_points_l1_distance.py b/closest_points_l1_distance.py index 4a2bf7c..35b8817 100644 --- a/closest_points_l1_distance.py +++ b/closest_points_l1_distance.py @@ -17,7 +17,7 @@ def y_sort(S): YY = MaxHeap(Y) YY.heapsort() Y = [] - for i in range(0, len(YY)): + for i in range(len(YY)): Y.append((YY[i][1], YY[i][0])) return Y @@ -29,7 +29,7 @@ def distance(p1, p2): def brute_force(P): P = list(P) d = float("Inf") - for i in range(0, len(P)): + for i in range(len(P)): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d @@ -53,7 +53,7 @@ def closest_points_aux(P, X, Y): l = X[half - 1][0] YL = [] YR = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if Y[i] in PL: YL.append(Y[i]) else: @@ -62,11 +62,11 @@ def closest_points_aux(P, X, Y): dr = closest_points_aux(PR, XR, YR) d1 = min(dl, dr) YY = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if abs(Y[i][0] - l) < d1: YY.append(Y[i]) d2 = float("Inf") - for i in range(0, len(YY)): + for i in range(len(YY)): for j in range(1, 10): if i + j < len(YY): d2 = min(distance(YY[i], YY[i + j]), d2) diff --git a/closest_points_l_infinite_distance.py b/closest_points_l_infinite_distance.py index e1e00eb..a99b692 100644 --- a/closest_points_l_infinite_distance.py +++ b/closest_points_l_infinite_distance.py @@ -17,7 +17,7 @@ def y_sort(S): YY = MaxHeap(Y) YY.heapsort() Y = [] - for i in range(0, len(YY)): + for i in range(len(YY)): Y.append((YY[i][1], YY[i][0])) return Y @@ -29,7 +29,7 @@ def distance(p1, p2): def brute_force(P): P = list(P) d = float("Inf") - for i in range(0, len(P)): + for i in range(len(P)): for j in range(i + 1, len(P)): d = min(d, distance(P[i], P[j])) return d @@ -53,7 +53,7 @@ def closest_points_aux(P, X, Y): l = X[half - 1][0] YL = [] YR = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if Y[i] in PL: YL.append(Y[i]) else: @@ -62,11 +62,11 @@ def closest_points_aux(P, X, Y): dr = closest_points_aux(PR, XR, YR) d1 = min(dl, dr) YY = [] - for i in range(0, len(Y)): + for i in range(len(Y)): if abs(Y[i][0] - l) < d1: YY.append(Y[i]) d2 = float("Inf") - for i in range(0, len(YY)): + for i in range(len(YY)): for j in range(1, 7): if i + j < len(YY): d2 = min(distance(YY[i], YY[i + j]), d2) diff --git a/constraints.py b/constraints.py index 1e9cc41..3bd6d6c 100644 --- a/constraints.py +++ b/constraints.py @@ -50,12 +50,12 @@ def difference_constraints(A, b): vertices = [] edges = [] weights = dict() - for i in range(0, vertices_num + 1): + for i in range(vertices_num + 1): vertices.append(Vertex(i)) for i in range(1, vertices_num + 1): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = 0 - for i in range(0, row): + for i in range(row): u = A[i].index(-1) + 1 v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) @@ -79,12 +79,12 @@ def difference_constraints_with_arbitrary_weight(A, b): edges = [] weights = dict() distribute = sample(range(-10, 10), vertices_num) - for i in range(0, vertices_num + 1): + for i in range(vertices_num + 1): vertices.append(Vertex(i)) for i in range(1, vertices_num + 1): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = distribute[i - 1] - for i in range(0, row): + for i in range(row): u = A[i].index(-1) + 1 v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) @@ -103,12 +103,12 @@ def equality_constraints(A, b): vertices = [] edges = [] weights = dict() - for i in range(0, vertices_num + 1): + for i in range(vertices_num + 1): vertices.append(Vertex(i)) for i in range(1, vertices_num + 1): edges.append((vertices[0], vertices[i])) weights[(vertices[0], vertices[i])] = 0 - for i in range(0, row): + for i in range(row): u = A[i].index(-1) + 1 v = A[i].index(1) + 1 edges.append((vertices[u], vertices[v])) @@ -131,7 +131,7 @@ def difference_constraints_without_aux_vertex(A, b): weights = dict() for i in range(vertices_num): vertices.append(Vertex(i + 1)) - for i in range(0, row): + for i in range(row): u = A[i].index(-1) v = A[i].index(1) edges.append((vertices[u], vertices[v])) @@ -167,10 +167,10 @@ def single_variable_constraints(A, b): vertices = [] edges = [] weights = dict() - for i in range(0, vertices_num + 1): + for i in range(vertices_num + 1): vertices.append(Vertex(i)) - for i in range(0, row): - for j in range(0, len(A[i])): + for i in range(row): + for j in range(len(A[i])): if A[i][j] == 1: edges.append((vertices[0], vertices[j + 1])) weights[(vertices[0], vertices[j + 1])] = b[i] diff --git a/counting_sort.py b/counting_sort.py index 922ab3d..1d71762 100644 --- a/counting_sort.py +++ b/counting_sort.py @@ -1,8 +1,8 @@ def counting_sort(A, B, k): C = [] - for i in range(0, k + 1): + for i in range(k + 1): C.append(0) - for j in range(0, len(A)): + for j in range(len(A)): C[A[j]] = C[A[j]] + 1 for i in range(1, k + 1): C[i] = C[i] + C[i - 1] diff --git a/fft.py b/fft.py index 6f7c3ea..e90b743 100644 --- a/fft.py +++ b/fft.py @@ -14,7 +14,7 @@ def recursive_fft(a): y0 = recursive_fft(a0) y1 = recursive_fft(a1) y = [0.0] * n - for k in range(0, n // 2): + for k in range(n // 2): y[k] = y0[k] + w * y1[k] y[k + n // 2] = y0[k] - w * y1[k] w = w * wn @@ -24,7 +24,7 @@ def recursive_fft(a): def recursive_inverse_fft(y): n = len(y) result = recursive_inverse_fft_aux(y) - return [result[i] / n for i in range(0, n)] + return [result[i] / n for i in range(n)] def recursive_inverse_fft_aux(y): @@ -38,7 +38,7 @@ def recursive_inverse_fft_aux(y): a0 = recursive_inverse_fft_aux(y0) a1 = recursive_inverse_fft_aux(y1) a = [0.0] * n - for k in range(0, n // 2): + for k in range(n // 2): a[k] = (a0[k] + w * a1[k]) a[k + n // 2] = (a0[k] - w * a1[k]) w = w * wn diff --git a/graph.py b/graph.py index 964840d..e2ac779 100644 --- a/graph.py +++ b/graph.py @@ -254,7 +254,7 @@ def simplified_dfs(self): stack = [] cc = cc + 1 self.simplified_dfs_visit(u, stack, s) - for i in range(0, len(stack) - 1): + for i in range(len(stack) - 1): s._addEdge(stack[i], stack[i + 1]) if len(stack) > 1: s._addEdge(stack[len(stack) - 1], stack[0]) @@ -331,7 +331,7 @@ def component_graph_dfs_visit(self, u): def semiconnected(self): cg = self.component_graph() vertices_list = sorted(cg.vertices, key=lambda u: u.key, reverse=False) - for i in range(0, len(vertices_list) - 1): + for i in range(len(vertices_list) - 1): if vertices_list[i + 1] not in cg.adj[vertices_list[i]]: return False return True @@ -603,7 +603,7 @@ def Dijkstra_modified(self, w, s, W): """ self.initialize_signle_source(s) A = [] - for i in range(0, W * len(self.vertices) + 1): + for i in range(W * len(self.vertices) + 1): A.append(set()) A[0].add(s) i = 0 @@ -696,7 +696,7 @@ def __init__(self, key): class max_heap(list): def __init__(self, data, attr): list.__init__(self, data) - for i in range(0, len(data)): + for i in range(len(data)): self[i].index = i self.length = len(data) self.attr = attr @@ -778,7 +778,7 @@ def __init__(self, data, attr): attr: the attribute of input date used as compare key """ list.__init__(self, data) - for i in range(0, len(data)): + for i in range(len(data)): self[i].index = i self.attr = attr self.length = len(data) diff --git a/hash.py b/hash.py index f82b6b1..f234d74 100755 --- a/hash.py +++ b/hash.py @@ -29,7 +29,7 @@ def double_hashing(k, i): return (k + i * (1 + k % (len(T) - 1))) % len(T) -T = [None for i in range(0, 11)] +T = [None] * 11 print("length of T is ", len(T)) for i in 10, 22, 31, 4, 15, 28, 17, 88, 59: hash_insert(T, i, double_hashing) diff --git a/huffman.py b/huffman.py index 716897f..cc230cc 100644 --- a/huffman.py +++ b/huffman.py @@ -95,10 +95,10 @@ def __lt__(self, y): def huffman(chars, freqs): n = len(chars) c = [0] * n - for i in range(0, n): + for i in range(n): c[i] = character(chars[i], freqs[i]) q = Min_priority_queue(c) - for i in range(0, n - 1): + for i in range(n - 1): x = q.heap_extract_min() y = q.heap_extract_min() q.min_heap_insert(node(x, y, x.freq + y.freq)) @@ -134,7 +134,7 @@ def compact_store_prefix_code_aux(node, store, string): def decode_compact_prefix_code(store): code = '' pos = 0 - for i in range(0, len(store)): + for i in range(len(store)): last_len = len(code) char = store[i][1][0] for pos in range(last_len - 1, -1, -1): @@ -155,7 +155,7 @@ def huffman_tenary(chars, freqs, m): """ n = len(chars) c = [0] * n - for i in range(0, n): + for i in range(n): c[i] = character(chars[i], freqs[i]) q = Min_priority_queue(c) while q.heap_size >= m: diff --git a/insertion_sort.py b/insertion_sort.py index b149efc..fcf47b6 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -31,29 +31,23 @@ def insert_with_binary_search(array, right_index): array[index] = x -def _insertion_sort_recursive(array, length, insert_method): - if length > 1: - _insertion_sort_recursive(array, length - 1, insert_method) - insert_method(array, length - 1) - - -def insertion_sort(array, left=0, right=None, insert_method=insert_with_linear_search): +def insertion_sort(array, insert_method=insert_with_linear_search): """ inplace sort O(n ^ 2) sort :param array: :param insert_method: - :param left: - :param right: :return: """ - if right is None: - right = len(array) - else: - right += 1 - for j in range(left, right): + for j in range(len(array)): insert_method(array, j) +def _insertion_sort_recursive(array, length, insert_method): + if length > 1: + _insertion_sort_recursive(array, length - 1, insert_method) + insert_method(array, length - 1) + + def insertion_sort_recursive(array, insert_method=insert_with_linear_search): """ recursive version of insertion sort diff --git a/interpolation.py b/interpolation.py index 97e7f76..9003511 100644 --- a/interpolation.py +++ b/interpolation.py @@ -23,17 +23,17 @@ def Lagrange_interpolation(X, Y, n): R = roots_interpolation(X, n) # print( "length of R is {}".format(len(R))) A = [0] * n - for k in range(0, n): + for k in range(n): q, re = di.synthetic_division(R, n + 1, X[k]) # print( q) # print( "length of q is {}".format(len(q))) m = 1.0 - for j in range(0, n): + for j in range(n): if j != k: m = m * (X[k] - X[j]) # print( "m = {}".format(m)) m = Y[k] / m # print( "m = {}".format(m)) - for j in range(0, n): + for j in range(n): A[j] = A[j] + q[j] * m return A diff --git a/interval_graph_coloring.py b/interval_graph_coloring.py index cc0faf9..0766480 100644 --- a/interval_graph_coloring.py +++ b/interval_graph_coloring.py @@ -5,8 +5,8 @@ def interval_graph_coloring(graph): m = graph.shape[0] color = [1] * m number = 1 - for i in range(0, m): - for j in range(0, m): + for i in range(m): + for j in range(m): if graph[i, j] == 1 and color[i] == color[j]: color[j] = color[i] + 1 if color[j] > number: diff --git a/knapsack_0_1.py b/knapsack_0_1.py index 987c458..ed2fc0b 100644 --- a/knapsack_0_1.py +++ b/knapsack_0_1.py @@ -33,8 +33,8 @@ def knapsack_0_1_memoized(W, w, v): n = len(w) value = zeros((W + 1, n + 1)) solution = zeros((W + 1, n + 1)) - for i in range(0, W + 1): - for j in range(0, n + 1): + for i in range(W + 1): + for j in range(n + 1): value[i, j] = float("-Inf") knapsack_0_1_memoized_aux(W, w, v, m, n, value, solution) return value, solution diff --git a/kth-Quantiles.py b/kth-Quantiles.py index efef928..258a9a6 100755 --- a/kth-Quantiles.py +++ b/kth-Quantiles.py @@ -33,11 +33,11 @@ def median_of_two_arrays(X, x_start, x_end, Y, y_start, y_end, size): if __name__ == '__main__': - A = [random.randint(1, 100) for i in range(0, 15)] + A = [random.randint(1, 100) for i in range(15)] print(A) randomized_quicksort(A, 0, 14) print(A) - B = [random.randint(1, 100) for i in range(0, 15)] + B = [random.randint(1, 100) for i in range(15)] print(B) randomized_quicksort(B, 0, 14) print(B) diff --git a/longest_palindrome_subsequence.py b/longest_palindrome_subsequence.py index e186c6e..ff1ff0e 100644 --- a/longest_palindrome_subsequence.py +++ b/longest_palindrome_subsequence.py @@ -17,7 +17,7 @@ def longest_palindrome_subsequence(s): else: c[i][i + 1] = 1 for length in range(3, n + 1): - for i in range(0, n - length + 1): + for i in range(n - length + 1): j = i + length - 1 if s[i] == s[j]: print(i, j, c[i + 1][j - 1]) diff --git a/partition.py b/partition.py index 07a7a40..ae41bf5 100644 --- a/partition.py +++ b/partition.py @@ -1,25 +1,26 @@ import random -def partition(array, p, r): - x = array[r] - i = p - 1 - for j in range(p, r): - if array[j] <= x: - i = i + 1 - array[i], array[j] = array[j], array[i] - array[i + 1], array[r] = array[r], array[i + 1] - return i + 1 - - -def partition2(array, p, r): +def partition(array, left, right): + pivot_index = left + pivot = array[right] + for i in range(left, right): + if array[i] <= pivot: + array[i], array[pivot_index] = array[pivot_index], array[i] + pivot_index += 1 + array[pivot_index], array[right] = array[right], array[pivot_index] + return pivot_index + + +def partition2(array, left, right): """ - Partition A into three parts: < x, = x, > x. The return value is the median of the second part. So the return value is floor((p + r) / 2) when all elements in the array A[p .. r] have the same value. Partition in place. + Partition A into three parts: < x, = x, > x. The return value is the median of the second part. + So the return value is (left + right) // 2 when all elements in the array A[left .. right] have the same value. Partition in place. """ - x = array[r] - i = p - 1 + x = array[right] + i = left - 1 k = i - for j in range(p, r): + for j in range(left, right): if array[j] < x: i = i + 1 array[i], array[j] = array[j], array[i] @@ -29,34 +30,25 @@ def partition2(array, p, r): elif array[j] == x: k = k + 1 array[k], array[j] = array[j], array[k] - array[k + 1], array[r] = array[r], array[k + 1] + array[k + 1], array[right] = array[right], array[k + 1] return (k + 2 + i) // 2 -def partition3(array, p, r): +def partition3(array, left, right): """ - Variant of partition2. Requires O(n) extra space, but it is easier to implement. + Variant of partition. Requires O(n) extra space, but it is easier to implement. """ - x = array[r] - n = r - p + 1 - i = -1 - k = n - B = [0] * n - for j in range(p, r): - if array[j] < x: - i = i + 1 - B[i] = array[j] - elif array[j] > x: - k = k - 1 - B[k] = array[j] - for j in range(i + 1, k): - B[j] = x - for j in range(p, r + 1): - array[j] = B[j - p] - return (2 * p + i + k) // 2 - - -def randomized_partition(array, p, r): - i = random.randint(p, r) - array[i], array[r] = array[r], array[i] - return partition(array, p, r) + pivot = array[right] + left_part = [array[i] for i in range(left, right) if array[i] <= pivot] + right_part = [array[i] for i in range(left, right) if array[i] > pivot] + pivot_index = left + len(left_part) + array[left:pivot_index] = left_part[:] + array[pivot_index + 1:right + 1] = right_part[:] + array[pivot_index] = pivot + return pivot_index + + +def randomized_partition(array, left, right): + i = random.randint(left, right) + array[i], array[right] = array[right], array[i] + return partition(array, left, right) diff --git a/polynomial_multiply.py b/polynomial_multiply.py index e6dc60e..15c8d7d 100644 --- a/polynomial_multiply.py +++ b/polynomial_multiply.py @@ -9,16 +9,16 @@ def polynominal_multiply(a, b, precision=0): print(length) extend_a = [0] * length extend_b = [0] * length - for i in range(0, a_len): + for i in range(a_len): extend_a[i] = a[i] for i in range(a_len, length): extend_a[i] = 0 - for i in range(0, b_len): + for i in range(b_len): extend_b[i] = b[i] for i in range(b_len, length): extend_b[i] = 0 a_fft = fft.recursive_fft(extend_a) b_fft = fft.recursive_fft(extend_b) - m_fft = [a_fft[i] * b_fft[i] for i in range(0, len(a_fft))] + m_fft = [a_fft[i] * b_fft[i] for i in range(len(a_fft))] ab = fft.recursive_inverse_fft(m_fft) - return [round(ab[i].real, precision) for i in range(0, a_len + b_len - 1)] + return [round(ab[i].real, precision) for i in range(a_len + b_len - 1)] diff --git a/quicksort.py b/quicksort.py index eed28db..02b79e7 100644 --- a/quicksort.py +++ b/quicksort.py @@ -1,15 +1,15 @@ from partition import partition, randomized_partition -def quicksort(array, p, r, partition_method=partition): - if p < r: - q = partition_method(array, p, r) - quicksort(array, p, q - 1) - quicksort(array, q + 1, r) - - -def randomized_quicksort(array, p, r): - if p < r: - q = randomized_partition(array, p, r) - randomized_quicksort(array, p, q - 1) - randomized_quicksort(array, q + 1, r) +def quicksort(array, left, right, partition_method=partition): + if left < right: + index = partition_method(array, left, right) + quicksort(array, left, index - 1) + quicksort(array, index + 1, right) + + +def randomized_quicksort(array, left, right): + if left < right: + index = randomized_partition(array, left, right) + randomized_quicksort(array, left, index - 1) + randomized_quicksort(array, index + 1, right) diff --git a/randomized_permute.py b/randomized_permute.py index fef9550..a5bc53a 100644 --- a/randomized_permute.py +++ b/randomized_permute.py @@ -1,16 +1,17 @@ import random + def randomize_in_place(A): """ An algorithm to permute the given array in place. It computes a uniform random permutation. """ n = len(A) - for i in range(0, n): + for i in range(n): j = random.randint(i, n - 1) A[i], A[j] = A[j], A[i] -#def permute_by_sorting(A): +# def permute_by_sorting(A): # n = len(A) # P = [0] * n -# for i in +# for i in diff --git a/selection_sort.py b/selection_sort.py index 6bdf522..a7b18a8 100644 --- a/selection_sort.py +++ b/selection_sort.py @@ -2,11 +2,11 @@ # encoding: utf-8 -def selection_sort(array:list): +def selection_sort(array: list): """ Inplace sort Consider sorting n numbers stored in array A by first finding the smallest element of A - and exchanging it with the element in A[1] . Then find the second smallest element of A, and exchange it with A[2]. + and exchanging it with the element in A[0] . Then find the second smallest element of A, and exchange it with A[1]. Continue in this manner for the first n - 1 elements of A. :param array: :return: diff --git a/simplex.py b/simplex.py index 68a9e19..249ed80 100644 --- a/simplex.py +++ b/simplex.py @@ -65,7 +65,7 @@ def initialize_simplex(A, b, c): m = len(b) n = len(c) minimum = float("Inf") - for i in range(0, m): + for i in range(m): if minimum > b[i]: k = i + 1 minimum = b[i] @@ -98,7 +98,7 @@ def initialize_simplex(A, b, c): A = new_A b = new_b c = new_c - N = set(range(0, n + 1)) + N = set(range(n + 1)) B = set(range(n + 1, n + m + 1)) v = 0 l = n + k diff --git a/single_edge.py b/single_edge.py index 5b2ee2d..3a08a0e 100644 --- a/single_edge.py +++ b/single_edge.py @@ -12,7 +12,7 @@ def __init__(self, data, option=0): self.vertices_number = len(data) self.vertices = [None] * self.vertices_number self.edges_number = 0 - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): for j in data[i]: self.insert_edge(i + 1, j) elif option == 1: @@ -22,7 +22,7 @@ def __init__(self, data, option=0): def transpose(self): t = graph(self.vertices_number, 1) - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): j = self.vertices[i] while j is not None: t.insert_edge(j.key, i + 1) @@ -31,12 +31,12 @@ def transpose(self): def union(self, g): u = graph(self.vertices_number, 1) - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): j = self.vertices[i] while j is not None: u.insert_edge(i + 1, j.key) j = j.right - for i in range(0, g.vertices_number): + for i in range(g.vertices_number): j = g.vertices[i] while j is not None: u.insert_edge(i + 1, j.key) @@ -47,7 +47,7 @@ def single_edge(self): g = self.union(self.transpose()) single = graph(g.vertices_number, 1) s = [0] * g.vertices_number - for u in range(0, g.vertices_number): + for u in range(g.vertices_number): v = g.vertices[u] while v: if (u + 1) != v.key and s[v.key - 1] == 0: @@ -68,7 +68,7 @@ def insert_edge(self, u, v): self.edges_number = self.edges_number + 1 def print_graph(self): - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): j = self.vertices[i] print('{}: '.format(i + 1), ) while j is not None: @@ -81,7 +81,7 @@ def square(self): descendent = graph(self.vertices_number, 1) s = [0] * self.vertices_number # generate grandchild graph - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): j = self.vertices[i] while j is not None: k = self.vertices[j.key - 1] @@ -96,7 +96,7 @@ def square(self): s[j.key - 1] = 0 j = j.right # generate great grandchild graph - for i in range(0, grandchild.vertices_number): + for i in range(grandchild.vertices_number): j = grandchild.vertices[i] while j is not None: k = self.vertices[j.key - 1] @@ -110,7 +110,7 @@ def square(self): s[j.key - 1] = 0 j = j.right square = graph(self.vertices_number, 1) - for i in range(0, self.vertices_number): + for i in range(self.vertices_number): j = self.vertices[i] print(j) while j is not None: diff --git a/tests/bubble_sort_test.py b/tests/bubble_sort_test.py index 68f7d94..3fd80be 100644 --- a/tests/bubble_sort_test.py +++ b/tests/bubble_sort_test.py @@ -7,7 +7,7 @@ class TestBubbleSort(unittest.TestCase): def test_bubble_sort(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] bubble_sort(array) self.assertEqual(array, sorted(array_copy)) diff --git a/tests/counting_sort_test.py b/tests/counting_sort_test.py index 5eee259..adfd457 100644 --- a/tests/counting_sort_test.py +++ b/tests/counting_sort_test.py @@ -6,7 +6,7 @@ class TestHeap(unittest.TestCase): def test_counting_sort(self): A = [2, 5, 3, 0, 2, 3, 0, 3] B = [] - for i in range(0, len(A)): + for i in range(len(A)): B.append(0) counting_sort(A, B, 5) self.assertEqual(B, [0, 0, 2, 2, 3, 3, 3, 5]) diff --git a/tests/cut_rod_test.py b/tests/cut_rod_test.py index c496dcd..596b93e 100755 --- a/tests/cut_rod_test.py +++ b/tests/cut_rod_test.py @@ -10,14 +10,14 @@ def test_bottom_up_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] - for i in range(0, len(values), 2): + for i in range(len(values), 2): self.assertEqual(bottom_up_cut_rod(p, values[i]), values[i + 1]) def test_bottom_up_cut_rod_two_subproblem(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] - for i in range(0, len(values), 2): + for i in range(len(values), 2): self.assertEqual(bottom_up_cut_rod_two_subproblem( p, values[i]), values[i + 1]) @@ -25,19 +25,19 @@ def test_memoized_cut_rod(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 10, 5, 13, 6, 17, 7, 18, 8, 22, 9, 25, 10, 30] - for i in range(0, len(values), 2): + for i in range(len(values), 2): self.assertEqual(memoized_cut_rod(p, values[i]), values[i + 1]) def test_bottom_up_cut_rod_with_fixed_cut_cost(self): p = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30] values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11, 6, 17, 7, 17, 8, 20, 9, 24, 10, 30] - for i in range(0, len(values), 2): + for i in range(len(values), 2): self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost( p, values[i], 2), values[i + 1]) values = [1, 1, 2, 5, 3, 8, 4, 9, 5, 11.5, 6, 17, 7, 17, 8, 20.5, 9, 24, 10, 30] - for i in range(0, len(values), 2): + for i in range(len(values), 2): self.assertEqual(bottom_up_cut_rod_with_fixed_cut_cost( p, values[i], 1.5), values[i + 1]) diff --git a/tests/insertion_sort_test.py b/tests/insertion_sort_test.py index c8dc791..1b84092 100644 --- a/tests/insertion_sort_test.py +++ b/tests/insertion_sort_test.py @@ -8,26 +8,26 @@ class TestInsertionSort(unittest.TestCase): def test_insertion_sort_with_linear_search(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] insertion_sort(array, insert_method=insert_with_linear_search) self.assertEqual(array, sorted(array_copy)) def test_insertion_sort_with_binary_search(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] insertion_sort(array, insert_method=insert_with_binary_search) self.assertEqual(array, sorted(array_copy)) def test_insertion_sort_recursive(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] insertion_sort_recursive(array) self.assertEqual(array, sorted(array_copy)) for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] insertion_sort_recursive( array, insert_method=insert_with_binary_search) diff --git a/tests/k_way_merge_test.py b/tests/k_way_merge_test.py index 36c5126..f30e50a 100644 --- a/tests/k_way_merge_test.py +++ b/tests/k_way_merge_test.py @@ -6,10 +6,10 @@ class TestKWayMerge(unittest.TestCase): def test_k_way_merge(self): - for j in range(0, 10000): - A = [random.randint(1, 10000) for _ in range(0, 100)] + for j in range(10000): + A = [random.randint(1, 10000) for _ in range(100)] lists = [None] * 10 - for i in range(0, 10): + for i in range(10): lists[i] = A[10 * i: (i + 1) * 10] lists[i].sort() A.sort() diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 881c64e..1b46f29 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -7,14 +7,14 @@ class TestMergeSort(unittest.TestCase): def test_merge_sort_with_sentinel(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] merge_sort(array, merge_with_sentinel) self.assertEqual(array, sorted(array_copy)) def test_merge_sort_without_sentinel(self): for _ in range(100): - array = [random.randint(1, 10000) for _ in range(0, 100)] + array = [random.randint(1, 10000) for _ in range(100)] array_copy = array[:] merge_sort(array, merge_without_sentinel) self.assertEqual(array, sorted(array_copy)) diff --git a/tests/partition_test.py b/tests/partition_test.py index 7f82011..b2c67ce 100644 --- a/tests/partition_test.py +++ b/tests/partition_test.py @@ -1,12 +1,15 @@ import unittest from partition import partition, partition2, partition3 +from random_array import random_arrays class TestPartition(unittest.TestCase): def test_partition(self): - a = [2, 8, 7, 1, 3, 5, 6, 4] - partition(a, 0, 7) - self.assertEqual(a, [2, 1, 3, 4, 7, 5, 6, 8]) + for array in random_arrays(): + pivot_index = partition(array, 0, len(array) - 1) + pivot = array[pivot_index] + self.assertTrue(all(array[i] <= pivot for i in range(pivot_index)) and all( + array[i] > pivot for i in range(pivot_index + 1, len(array)))) def test_partition2(self): a = [2, 8, 7, 1, 4, 5, 6, 4] @@ -14,6 +17,8 @@ def test_partition2(self): self.assertEqual(a, [2, 1, 4, 4, 7, 5, 6, 8]) def test_partition3(self): - a = [2, 8, 7, 1, 3, 5, 6, 4] - partition3(a, 0, 7) - self.assertEqual(a, [2, 1, 3, 4, 6, 5, 7, 8]) + for array in random_arrays(): + pivot_index = partition3(array, 0, len(array) - 1) + pivot = array[pivot_index] + self.assertTrue(all(array[i] <= pivot for i in range(pivot_index)) and all( + array[i] > pivot for i in range(pivot_index + 1, len(array)))) diff --git a/tests/quicksort_test.py b/tests/quicksort_test.py index e5605ac..0ebac67 100644 --- a/tests/quicksort_test.py +++ b/tests/quicksort_test.py @@ -6,29 +6,29 @@ class TestQuickSort(unittest.TestCase): def test_quicksort(self): - for i in range(100): - A = [random.randint(1, 10000) for i in range(100)] - B = A[:] - quicksort(A, 0, len(A) - 1, partition) - B.sort() - self.assertEqual(A, B) - for i in range(100): - A = [random.randint(1, 10000) for i in range(100)] - B = A[:] - quicksort(A, 0, len(A) - 1, partition2) - B.sort() - self.assertEqual(A, B) - for i in range(100): - A = [random.randint(1, 10000) for i in range(100)] - B = A[:] - quicksort(A, 0, len(A) - 1, partition3) - B.sort() - self.assertEqual(A, B) + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(100)] + array_copy = array[:] + quicksort(array, 0, len(array) - 1, partition) + array_copy.sort() + self.assertEqual(array, array_copy) + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(100)] + array_copy = array[:] + quicksort(array, 0, len(array) - 1, partition2) + array_copy.sort() + self.assertEqual(array, array_copy) + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(100)] + array_copy = array[:] + quicksort(array, 0, len(array) - 1, partition3) + array_copy.sort() + self.assertEqual(array, array_copy) def test_randomized_quicksort(self): - for i in range(100): - A = [random.randint(1, 10000) for i in range(100)] - B = A[:] - randomized_quicksort(A, 0, len(A) - 1) - B.sort() - self.assertEqual(A, B) + for _ in range(100): + array = [random.randint(1, 10000) for _ in range(100)] + array_copy = array[:] + randomized_quicksort(array, 0, len(array) - 1) + array_copy.sort() + self.assertEqual(array, array_copy) diff --git a/tests/random_array.py b/tests/random_array.py new file mode 100644 index 0000000..e1a7cca --- /dev/null +++ b/tests/random_array.py @@ -0,0 +1,6 @@ +import random + + +def random_arrays(array_num=100, array_size=100, array_lowerbound=0, array_upperbound=10000): + for _ in range(array_num): + yield [random.randint(array_lowerbound, array_upperbound) for _ in range(array_size)] diff --git a/tests/selection_sort_test.py b/tests/selection_sort_test.py index 3cf6f7c..5f538a4 100644 --- a/tests/selection_sort_test.py +++ b/tests/selection_sort_test.py @@ -2,14 +2,13 @@ # encoding: utf-8 import unittest -import random +from random_array import random_arrays from selection_sort import selection_sort class TestSelectionSort(unittest.TestCase): def test_selection_sort(self): - for size in range(20): - array = [random.randint(1, 10000) for _ in range(size)] + for array in random_arrays(): sorted_array = sorted(array) selection_sort(array) self.assertEqual(array, sorted_array) diff --git a/tree.py b/tree.py index 5ea2034..f9a4ef1 100755 --- a/tree.py +++ b/tree.py @@ -149,7 +149,7 @@ def delete(self, z): y.left.p = y -# A = [random.randint(1, 100) for i in range(0, 15)] +# A = [random.randint(1, 100) for i in range(15)] # A = [29, 81, 53, 51, 28, 31, 57, 30, 22, 62, 6, 50, 7, 2, 24, 55, 54, 56, 98] # print( A) # T = Tree(A) From 763663b7a58a84c2e901a287db5c2440f347b5c2 Mon Sep 17 00:00:00 2001 From: wq Date: Sun, 3 Jan 2021 19:28:47 +0800 Subject: [PATCH 28/49] replace == None with is None, != None with is not None --- Johnson.py | 2 +- any_disks_intersect.py | 2 +- any_segments_intersect.py | 6 +++--- b_tree.py | 4 ++-- disjoint_sets_forest.py | 2 +- disjoint_sets_linked_list.py | 6 +++--- graph.py | 10 +++++----- huffman.py | 6 +++--- insertion_sort.py | 30 ++++++++++++++++++------------ interval_tree.py | 2 +- polar_angle.py | 2 +- single_edge.py | 4 ++-- tests/Bellman_Ford_matrix_test.py | 2 +- tests/Johnson_test.py | 4 ++-- tests/random_array.py | 6 ------ three_points_colinear.py | 2 +- tree.py | 4 ++-- vEB_tree.py | 14 +++++++------- 18 files changed, 54 insertions(+), 54 deletions(-) delete mode 100644 tests/random_array.py diff --git a/Johnson.py b/Johnson.py index ca06c0e..7dfe37f 100644 --- a/Johnson.py +++ b/Johnson.py @@ -21,7 +21,7 @@ def Bellman_Ford(self, w, s): initialize_single_source(self, s) for i in range(1, len(self.vertices)): for u, v in self.edges: - relax(self, u, v, w) + relax(u, v, w) for u, v in self.edges: if v.d > u.d + w[(u, v)]: return False diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 1be9df4..3fb6f3c 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -32,7 +32,7 @@ class rb_node(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color - if key != None: + if key is not None: key.pointer = self def minimum(self, nil): diff --git a/any_segments_intersect.py b/any_segments_intersect.py index 2c83064..a7e4c59 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -73,7 +73,7 @@ class rb_node(Node): def __init__(self, key, p, left, right, color): Node.__init__(self, key, p, left, right) self.color = color - if key != None: + if key is not None: key.pointer = self def minimum(self, nil): @@ -312,7 +312,7 @@ def any_segments_intersect(S): T.insert(s) a = T.above(s) b = T.below(s) - if (a != None and segments_intersect(a[0], a[1], s[0], s[1])) or (b != None and segments_intersect(b[0], b[1], s[0], s[1])): + if (a is not None and segments_intersect(a[0], a[1], s[0], s[1])) or (b is not None and segments_intersect(b[0], b[1], s[0], s[1])): return True if p[1] == 1: s = p.segment @@ -322,7 +322,7 @@ def any_segments_intersect(S): # print( b) # print( type(a)) # print( type(b)) - if a != None and b != None and segments_intersect(a[0], a[1], b[0], b[1]): + if a is not None and b is not None and segments_intersect(a[0], a[1], b[0], b[1]): return True T.delete(s) return False diff --git a/b_tree.py b/b_tree.py index 11d3496..d1d6676 100644 --- a/b_tree.py +++ b/b_tree.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -class b_tree_node(object): +class b_tree_node: def __init__(self, t, leaf, n): self.leaf = leaf self.n = n @@ -164,7 +164,7 @@ def merge(self, tree, i): tree.root = y -class b_tree(object): +class b_tree: def __init__(self, t): self.t = t self.root = b_tree_node(t, True, 0) diff --git a/disjoint_sets_forest.py b/disjoint_sets_forest.py index 1d42623..20f20a6 100644 --- a/disjoint_sets_forest.py +++ b/disjoint_sets_forest.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -class node(object): +class node: def __init__(self, key): self.key = key # key.index = self diff --git a/disjoint_sets_linked_list.py b/disjoint_sets_linked_list.py index 072631a..ea1895b 100644 --- a/disjoint_sets_linked_list.py +++ b/disjoint_sets_linked_list.py @@ -1,6 +1,6 @@ #!/usr/bin/env python -class node(object): +class node: def __init__(self, key): self.key = key self.set = None @@ -27,7 +27,7 @@ def union(self, y): return x -class header(object): +class header: def __init__(self, element): self.length = 1 self.head = element @@ -55,7 +55,7 @@ def union(self, y): return y -class header_notail(object): +class header_notail: def __init__(self, element): self.length = 1 self.head = element diff --git a/graph.py b/graph.py index e2ac779..ea2269e 100644 --- a/graph.py +++ b/graph.py @@ -3,7 +3,7 @@ import sys -class Vertex(object): +class Vertex: def __init__(self, key): self.key = key @@ -22,7 +22,7 @@ def print_path(self, v): print(v, ) -class Graph(object): +class Graph: def __init__(self, vertices=tuple(), edges=tuple(), directed=True): self.directed = directed self.vertices = set(vertices) @@ -391,7 +391,7 @@ def alledges_undirected_dfs_visit(self, u): def Kruskal(self, w): A = set() for v in self.vertices: - dsf_node(v) + DfsNode(v) # ls = self.alledges_undirected_dfs() for u, v in sorted(self.edges, key=lambda x: w(x[0], x[1]), reverse=False): if u.index.find_set() != v.index.find_set(): @@ -536,7 +536,7 @@ def dag_shortest_paths_modified(self, s): Ga.dag_shortest_paths(lambda u, v: -u.weight, s) u = sink l = [] - while u.p != None: + while u.p is not None: l.append(u.p) u = u.p return l[::-1] @@ -684,7 +684,7 @@ def _mht_aux(self, u): self._mht_aux(v) -class dsf_node(dsf.node): +class DfsNode(dsf.node): def __init__(self, key): self.key = key key.index = self diff --git a/huffman.py b/huffman.py index cc230cc..e9d1fe1 100644 --- a/huffman.py +++ b/huffman.py @@ -11,7 +11,7 @@ def min_heap_insert(self, key): self.heap_decrease_key(self.heap_size - 1, key) -class character(object): +class character: def __init__(self, char, freq, sibling=None): self.char = char self.freq = freq @@ -38,7 +38,7 @@ def __lt__(self, y): return True -class node(object): +class node: def __init__(self, left, right, freq): self.left = left self.right = right @@ -65,7 +65,7 @@ def __lt__(self, y): return True -class tenary_node(object): +class tenary_node: def __init__(self, freq, child=None, sibling=None): self.freq = freq self.child = child diff --git a/insertion_sort.py b/insertion_sort.py index fcf47b6..25e1cf4 100644 --- a/insertion_sort.py +++ b/insertion_sort.py @@ -1,51 +1,57 @@ from binary_search import bisect_right -def insert_with_linear_search(array, right_index): +def insert_with_linear_search(array, left_index, right_index): """ - Use linear search to find a position in already sorted array[0...right_index-1] to insert array[right_index] into, - making array[0...right_index] a sorted array. + Use linear search to find a position in already sorted array[left_index...right_index-1] to insert array[right_index] into, + making array[left_index...right_index] a sorted array. :param array: + :param left_index: :param right_index: right_index > 0 :return: """ key = array[right_index] i = right_index - 1 - while i >= 0 and key < array[i]: + while i >= left_index and key < array[i]: array[i + 1] = array[i] i = i - 1 array[i + 1] = key -def insert_with_binary_search(array, right_index): +def insert_with_binary_search(array, left_index, right_index): """ - Use binary search to find a position in already sorted array[0...right_index-1] to insert array[right_index] into, - making array[0...right_index] a sorted array. + Use binary search to find a position in already sorted array[left_index...right_index-1] to insert array[right_index] into, + making array[left_index...right_index] a sorted array. :param array: + :param left_index: :param right_index: right_index > 0 :return: """ x = array[right_index] - index = bisect_right(array, x, 0, right_index) + index = bisect_right(array, x, left_index, right_index) array[index + 1: right_index + 1] = array[index: right_index] array[index] = x -def insertion_sort(array, insert_method=insert_with_linear_search): +def insertion_sort(array, left=0, right=None, insert_method=insert_with_linear_search): """ inplace sort O(n ^ 2) sort :param array: + :param left: + :param right: :param insert_method: :return: """ - for j in range(len(array)): - insert_method(array, j) + if right is None: + right = len(array) - 1 + for j in range(left, right + 1): + insert_method(array, 0, j) def _insertion_sort_recursive(array, length, insert_method): if length > 1: _insertion_sort_recursive(array, length - 1, insert_method) - insert_method(array, length - 1) + insert_method(array, 0, length - 1) def insertion_sort_recursive(array, insert_method=insert_with_linear_search): diff --git a/interval_tree.py b/interval_tree.py index 9c5ba0d..6795419 100755 --- a/interval_tree.py +++ b/interval_tree.py @@ -3,7 +3,7 @@ from rb_tree import RbNode, RbTree -class interval(object): +class interval: def __init__(self, low, high): self.low = low self.high = high diff --git a/polar_angle.py b/polar_angle.py index 5150d3a..d4ab834 100644 --- a/polar_angle.py +++ b/polar_angle.py @@ -3,7 +3,7 @@ from heap import MaxHeap -class Vector(object): +class Vector: def __init__(self, p2, p1=(0, 0)): self.x = p2[0] - p1[0] self.y = p2[1] - p1[0] diff --git a/single_edge.py b/single_edge.py index 3a08a0e..f3736c9 100644 --- a/single_edge.py +++ b/single_edge.py @@ -1,12 +1,12 @@ #!/usr/bin/env python -class node(object): +class node: def __init__(self, key, right): self.right = right self.key = key -class graph(object): +class graph: def __init__(self, data, option=0): if option == 0: self.vertices_number = len(data) diff --git a/tests/Bellman_Ford_matrix_test.py b/tests/Bellman_Ford_matrix_test.py index 0f2d12b..012f71c 100644 --- a/tests/Bellman_Ford_matrix_test.py +++ b/tests/Bellman_Ford_matrix_test.py @@ -18,5 +18,5 @@ def test_slow_all_pairs_shortest_paths(self): [float("Inf"), float("Inf"), 0, -3., 9.], [float("Inf"), -2., float("Inf"), 0, float("Inf")], [2., float("Inf"), float("Inf"), 7., 0]]) L = slow_all_pairs_shortest_paths(W, 1) - print(L) + # print(L) self.assertEqual(L, [0, 2.0, 7.0, 4.0, -2.0]) diff --git a/tests/Johnson_test.py b/tests/Johnson_test.py index 7e68875..f062a6a 100644 --- a/tests/Johnson_test.py +++ b/tests/Johnson_test.py @@ -18,7 +18,7 @@ def testJohnson(self): for i, j in zip(edges, weight): w[i] = j D = Johnson(g, w) - print(D) + # print(D) a1 = Vertex(1) a2 = Vertex(2) a3 = Vertex(3) @@ -33,4 +33,4 @@ def testJohnson(self): for i, j in zip(edges, weight): w[i] = j D = Johnson(g, w) - print(D) + # print(D) diff --git a/tests/random_array.py b/tests/random_array.py deleted file mode 100644 index e1a7cca..0000000 --- a/tests/random_array.py +++ /dev/null @@ -1,6 +0,0 @@ -import random - - -def random_arrays(array_num=100, array_size=100, array_lowerbound=0, array_upperbound=10000): - for _ in range(array_num): - yield [random.randint(array_lowerbound, array_upperbound) for _ in range(array_size)] diff --git a/three_points_colinear.py b/three_points_colinear.py index 12f7ebc..dd87706 100644 --- a/three_points_colinear.py +++ b/three_points_colinear.py @@ -3,7 +3,7 @@ from heap import MaxHeap -class vector(object): +class vector: def __init__(self, p1, p2, p1_index=0, p2_index=0): # gurantee that the polar angle of this Vector with respect to the origin point is in the range [0, pi) if p1[1] > p2[1]: diff --git a/tree.py b/tree.py index f9a4ef1..f9aa6dc 100755 --- a/tree.py +++ b/tree.py @@ -3,7 +3,7 @@ import random -class Node(object): +class Node: def __init__(self, key, p, left, right): self.key = key self.p = p @@ -87,7 +87,7 @@ def predecessor(self): return x.p -class Tree(object): +class Tree: root = None def __init__(self, values): diff --git a/vEB_tree.py b/vEB_tree.py index 3778b22..de193fb 100644 --- a/vEB_tree.py +++ b/vEB_tree.py @@ -3,7 +3,7 @@ import math -class vEB_node(object): +class vEB_node: def __init__(self, u): """u must be exact power of 2, as required by CLRS; otherwise, the behavior is undefined""" self.u = u @@ -39,16 +39,16 @@ def successor(self, x): return 1 else: return None - elif self.min != None and x < self.min: + elif self.min is not None and x < self.min: return self.min else: max_low = self.cluster[self.high(x)].max - if max_low != None and self.low(x) < max_low: + if max_low is not None and self.low(x) < max_low: offset = self.cluster[self.high(x)].successor(self.low(x)) return self.index(self.high(x), offset) else: succ_cluster = self.summary.successor(self.high(x)) - if succ_cluster == None: + if succ_cluster is None: return None else: offset = self.cluster[succ_cluster].min @@ -67,7 +67,7 @@ def insert(self, x): if x < self.min: x, self.min = self.min, x if self.u > 2: - if self.cluster[self.high(x)].min == None: + if self.cluster[self.high(x)].min is None: self.summary.insert(self.high(x)) self.cluster[self.high(x)].empty_tree_insert(self.low(x)) else: @@ -95,11 +95,11 @@ def delete(self, x): x = self.index(first_cluster, self.cluster[first_cluster].min) self.min = x self.cluster[self.high(x)].delete(self.low(x)) - if self.cluster[self.high(x)].min == None: + if self.cluster[self.high(x)].min is None: self.summary.delete(self.high(x)) if x == self.max: summary_max = self.summary.max - if summary_max == None: + if summary_max is None: self.max = self.min else: self.max = self.index( From 0861e20e33e882803bf7e73722a1263df32deadb Mon Sep 17 00:00:00 2001 From: wq Date: Tue, 5 Jan 2021 01:06:58 +0800 Subject: [PATCH 29/49] add assert to topological sort since topological_sort can be only applied to directed acyclic graph --- graph.py | 174 ++++++++++++++++++++++---------------------- polygon_area.py | 4 +- tests/graph_test.py | 123 +++++++++++++++---------------- 3 files changed, 150 insertions(+), 151 deletions(-) diff --git a/graph.py b/graph.py index ea2269e..004e05a 100644 --- a/graph.py +++ b/graph.py @@ -1,6 +1,10 @@ from queue import Queue import disjoint_sets_forest as dsf import sys +from typing import Iterable, Optional, Tuple, Set, Dict +from enum import Enum + +Color = Enum('Color', ('WHITE', 'GREY', 'BLACK')) class Vertex: @@ -8,46 +12,47 @@ def __init__(self, key): self.key = key def __repr__(self): - return str(self.key) + return f"Vertex({self.key})" def print_path(self, v): - """print( out the vertices on a shortest path from s to) - v, assuming that BFS has already computed a breadth-first tree""" + """ + print out the vertices on a shortest path from s to + v, assuming that BFS has already computed a breadth-first tree + """ if self == v: - print(self, ) + print(self) elif v.p is None: print("No path from {} to {} exists".format(self.key, v.key)) else: self.print_path(v.p) - print(v, ) + print(v) + + +Vertices = Optional[Iterable[Vertex]] +Edge = Tuple[Vertex, Vertex] +Edges = Optional[Iterable[Edge]] class Graph: - def __init__(self, vertices=tuple(), edges=tuple(), directed=True): - self.directed = directed - self.vertices = set(vertices) - self.edges = set() - self.adj = dict() - for u in vertices: + def __init__(self, vertices: Optional[Vertices] = None, + edges: Optional[Edges] = None, directed: bool = True): + self.directed: bool = directed + self.vertices: Set[Vertex] = set() if vertices is None else set(vertices) + self.edges: Set[Edge] = set() + self.adj: Dict[Vertex, Set[Vertex]] = dict() + self._time: int = 0 + for u in self.vertices: self.adj[u] = set() - for u, v in edges: - self._addEdge(u, v) - - def __eq__(self, G2): - G1 = self - if G1.directed != G2.directed: - return False - elif G1.vertices != G2.vertices: - return False - elif G1.edges != G2.edges: - return False - else: - for u in G1.vertices: - if G1.adj[u] != G2.adj[u]: - return False - return True + if edges is not None: + for u, v in edges: + self._add_edge(u, v) + + def __eq__(self, graph2: 'Graph'): + graph1 = self + return (graph1.directed == graph2.directed) and (graph1.vertices == graph2.vertices) and ( + graph1.edges == graph2.edges) - def _addEdge(self, u, v): + def _add_edge(self, u: Vertex, v: Vertex): if self.directed: self.adj[u].add(v) self.edges.add((u, v)) @@ -57,94 +62,87 @@ def _addEdge(self, u, v): self.adj[v].add(u) self.edges.add((v, u)) - def _addVertex(self, u, edges=tuple()): + def _add_vertex(self, u: Vertex, edges: Optional[Edges] = None): self.vertices.add(u) - for u, v in edges: - self._addEdge(u, v) + if edges is not None: + for u, v in edges: + self._add_edge(u, v) def copy(self): return Graph(self.vertices, self.edges, self.directed) def transpose(self): - t = Graph(self.vertices) - for u in self.vertices: - for v in self.adj[u]: - t._addEdge(v, u) - return t + return Graph(self.vertices, [(v, u) for u, v in self.edges], self.directed) - def bfs(self, s): + def bfs(self, s: Vertex): for u in self.vertices: - u.d = float("Inf") - u.color = 0 - u.p = None - s.color = 1 - s.d = 0 - s.p = None - q = Queue(2 * len(self.vertices)) - q.put(s) - while not q.empty(): - u = q.get() + u.distance = float("Inf") + u.color = Color.WHITE + u.parent = None + s.color = Color.GREY + s.distance = 0 + s.parent = None + queue = Queue() + queue.put(s) + while not queue.empty(): + u = queue.get() for v in self.adj[u]: - if v.color == 0: - v.color = 1 - v.d = u.d + 1 - v.p = u - q.put(v) - u.color = 2 + if v.color == Color.WHITE: + v.color = Color.GREY + v.distance = u.distance + 1 + v.parent = u + queue.put(v) + u.color = Color.BLACK def dfs(self): - global time + self._time = 0 for u in self.vertices: - u.color = 0 + u.color = Color.WHITE u.p = None - time = 0 for u in self.vertices: - if u.color == 0: + if u.color == Color.WHITE: self._dfs_visit(u) - def _dfs_visit(self, u): - global time - time = time + 1 - u.d = time - u.color = 1 + def _dfs_visit(self, u: Vertex): + self._time += 1 + u.d = self._time + u.color = Color.GREY for v in self.adj[u]: - if v.color == 0: + if v.color == Color.WHITE: v.p = u self._dfs_visit(v) - u.color = 2 - time = time + 1 - u.f = time + u.color = Color.BLACK + self._time += 1 + u.f = self._time - def isCyclic(self): - global time + def is_cyclic(self): for u in self.vertices: - u.color = 0 - u.p = None - time = 0 + u.color = Color.WHITE for u in self.vertices: - if u.color == 0: + if u.color == Color.WHITE: if self._is_cyclic_aux(u): return True return False def _is_cyclic_aux(self, u): - global time - time = time + 1 - u.d = time - u.color = 1 + u.color = Color.GREY for v in self.adj[u]: - if v.color == 0: - v.p = u + if v.color == Color.WHITE: if self._is_cyclic_aux(v): return True - elif v.color == 1: + elif v.color == Color.GREY: return True - u.color = 2 - time = time + 1 - u.f = time + u.color = Color.BLACK return False def topological_sort(self): + """ + Perform topological sort for dag + + A topological sort of a dag(directed acyclic graph) G = (V, E) is a linear ordering of all the vertices + such that if G contains an edge (u, v), then u appears before v in the ordering. + """ + assert (not self.is_cyclic()) and self.directed self.dfs() return sorted(self.vertices, key=lambda x: x.f, reverse=True) @@ -255,9 +253,9 @@ def simplified_dfs(self): cc = cc + 1 self.simplified_dfs_visit(u, stack, s) for i in range(len(stack) - 1): - s._addEdge(stack[i], stack[i + 1]) + s._add_edge(stack[i], stack[i + 1]) if len(stack) > 1: - s._addEdge(stack[len(stack) - 1], stack[0]) + s._add_edge(stack[len(stack) - 1], stack[0]) return s def simplified_dfs_visit(self, u, stack, s): @@ -276,7 +274,7 @@ def simplified_dfs_visit(self, u, stack, s): st = status[(v.cc, u.cc)] except KeyError: status[(v.cc, u.cc)] = 1 - s._addEdge(v, u) + s._add_edge(v, u) u.color = 2 time = time + 1 u.f = time @@ -302,7 +300,7 @@ def component_graph(self): if u.color == 0: cc = cc + 1 vertices_list.append(Vertex(cc)) - cg._addVertex(vertices_list[cc - 1]) + cg._add_vertex(vertices_list[cc - 1]) t.component_graph_dfs_visit(u) return cg @@ -321,7 +319,7 @@ def component_graph_dfs_visit(self, u): st = status[(v.cc, u.cc)] except KeyError: status[(v.cc, u.cc)] = 1 - cg._addEdge( + cg._add_edge( vertices_list[v.cc - 1], vertices_list[u.cc - 1]) u.color = 2 @@ -656,7 +654,7 @@ def square(self): for u in self.vertices: for v in self.adj[u]: for w in self.adj[v]: - sqrt._addEdge(u, w) + sqrt._add_edge(u, w) return sqrt def height(self, u): diff --git a/polygon_area.py b/polygon_area.py index 65cb061..f14c739 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -5,6 +5,6 @@ def polygon_area(polygon): n = len(polygon) area = 0 for i in range(n - 1): - area = area + (polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) - area = area + (polygon[0][0] + polygon[n - 1][0]) * (polygon[0][1] - polygon[n - 1][1]) + area += (polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) + area += (polygon[0][0] + polygon[n - 1][0]) * (polygon[0][1] - polygon[n - 1][1]) return 0.5 * abs(area) diff --git a/tests/graph_test.py b/tests/graph_test.py index f0e4d40..caedff1 100644 --- a/tests/graph_test.py +++ b/tests/graph_test.py @@ -1,11 +1,12 @@ #!/usr/bin/env python import unittest +from typing import List from graph import Vertex, Graph class TestGraph(unittest.TestCase): def setUp(self): - self.graphs = [] + self.graphs: List[Graph] = [] v1 = Vertex(1) v2 = Vertex(2) v3 = Vertex(3) @@ -29,7 +30,8 @@ def setUp(self): def tearDown(self): pass - def _buildGraph(self, keys, pairs, directed): + @staticmethod + def _build_graph(cls, keys, pairs, directed): d = dict() vertices = [None] * len(keys) edges = [None] * len(pairs) @@ -63,46 +65,48 @@ def testBfs(self): # print() g.bfs(s) # g.print(Vertices()) - self.assertEqual(s.d, 0) - self.assertEqual(r.d, 1) - self.assertEqual(v.d, 2) - self.assertEqual(w.d, 1) - self.assertEqual(t.d, 2) - self.assertEqual(x.d, 2) - self.assertEqual(u.d, 3) - self.assertEqual(y.d, 3) - - def testDfs(self): + self.assertEqual(s.distance, 0) + self.assertEqual(r.distance, 1) + self.assertEqual(v.distance, 2) + self.assertEqual(w.distance, 1) + self.assertEqual(t.distance, 2) + self.assertEqual(x.distance, 2) + self.assertEqual(u.distance, 3) + self.assertEqual(y.distance, 3) + + # def testDfs(self): + # s = Vertex('s') + # v = Vertex('v') + # z = Vertex('z') + # w = Vertex('w') + # y = Vertex('y') + # x = Vertex('x') + # t = Vertex('t') + # u = Vertex('u') + # # edges_list = [(z, w), (s, w), (y, w), + # # (x, ), (x, ), (z, ), (v, u), (v, t)] + # # vertices = (s, v, z, w, y, x, t, u) + # # map( + # # lambda vertex, edges: + # # map(lambda vertex, edge: + # # vertex.addEdge(edge), + # # zip([vertex] * len(edges) , edges)), + # # zip(vertices, edges_list)) + # vertices = [s, v, z, w, y, x, t, u] + # edges = [(y, x), (x, z), (z, y), (z, w), (w, x), (s, z), + # (s, w), (v, w), (v, s), (t, v), (t, u), (u, v), (u, t)] + # g = Graph(vertices, edges) + # g.dfs() + # # vertices = (s, v, z, w, y, x, t, u) + + def testIsCyclic(self): s = Vertex('s') v = Vertex('v') z = Vertex('z') - w = Vertex('w') - y = Vertex('y') - x = Vertex('x') - t = Vertex('t') - u = Vertex('u') - # edges_list = [(z, w), (s, w), (y, w), - # (x, ), (x, ), (z, ), (v, u), (v, t)] - # vertices = (s, v, z, w, y, x, t, u) - # map( - # lambda vertex, edges: - # map(lambda vertex, edge: - # vertex.addEdge(edge), - # zip([vertex] * len(edges) , edges)), - # zip(vertices, edges_list)) - vertices = [s, v, z, w, y, x, t, u] - edges = [(y, x), (x, z), (z, y), (z, w), (w, x), (s, z), - (s, w), (v, w), (v, s), (t, v), (t, u), (u, v), (u, t)] - g = Graph(vertices, edges) - g.dfs() - vertices = (s, v, z, w, y, x, t, u) - - # for u in vertices: - # print( u, u.d, u.f) - # df = [(1, 10), (12, 13), (2, 9), (7, 8), - # (3, 6), (4, 5), (11, 16), (14, 15)] - # edges_list = [(z, w), (s, w), (y, w), - # (x, ), (x, ), (z, ), (v, u), (v, t)] + vertices = [s, v, z] + self.assertFalse(Graph(vertices, [(s, v), (v, z)]).is_cyclic()) + self.assertTrue(Graph(vertices, [(s, v), (v, z), (z, s)]).is_cyclic()) + def testPathNum(self): m = Vertex('m') n = Vertex('n') @@ -463,7 +467,7 @@ def w(x, y): G.Bellman_Ford_modified(w, s) self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) self.assertEqual([i.d for i in vertices], [ - float("Inf"), 0, 2, 6, 5, 3]) + float("Inf"), 0, 2, 6, 5, 3]) def testTopologicalSort(self): r = Vertex('r') @@ -475,15 +479,12 @@ def testTopologicalSort(self): vertices = [r, s, t, x, y, z] edges = [(r, s), (r, t), (s, t), (s, x), (t, x), (t, y), (t, z), (x, y), (x, z), (y, z)] - G = Graph(vertices, edges) - l = G.topological_sort() - self.assertEqual(l, [r, s, t, x, y, z]) - - result = [] - l = [self.v1, self.v2, self.v3, self.v4, self.v5, self.v6] - result.append(l) - for i in range(len(self.graphs)): - self.assertEqual(self.graphs[i].topological_sort(), l) + graph = Graph(vertices, edges) + # Prove that Graph.topological_sort actually does a topological sort. + # A topological sort of a dag(directed acyclic graph) G = (V, E) is a linear ordering of all the vertices + # such that if G contains an edge (u, v), then u appears before v in the ordering. + mapping = {vertex: index for index, vertex in enumerate(graph.topological_sort())} + self.assertTrue(all(mapping[u] < mapping[v] for u, v in graph.edges)) def testDagShortestPaths(self): r = Vertex('r') @@ -507,12 +508,12 @@ def w(x, y): G.dag_shortest_paths(w, s) self.assertEqual([i.p for i in vertices], [None, None, s, s, x, y]) self.assertEqual([i.d for i in vertices], [ - float("Inf"), 0, 2, 6, 5, 3]) + float("Inf"), 0, 2, 6, 5, 3]) G.dag_shortest_paths(w, r) self.assertEqual([i.p for i in vertices], [None, r, r, t, t, t]) self.assertEqual([i.d for i in vertices], [0, 5, 3, 10, 7, 5]) - def TestDagShortestPathsModified(self): + def testDagShortestPathsModified(self): u = Vertex('u') v = Vertex('v') w = Vertex('w') @@ -524,7 +525,7 @@ def TestDagShortestPathsModified(self): vertices = [u, v, w, z] edges = [(u, v), (v, w), (v, z)] G = Graph(vertices, edges) - self.assertEqual(dag_shortest_paths_modified(G, u), [u, v, z]) + self.assertEqual(G.dag_shortest_paths_modified(u), [u, v, z]) def testTotalPathNumber(self): r = Vertex('r') @@ -639,16 +640,16 @@ def testSingleEdge(self): d = Vertex(4) vertices = [a, b, c, d] edges = [(a, b), (b, a), (a, c), (d, d)] - G = Graph(vertices, edges) - G2 = G.single_edge() - edges = set([(a, b), (b, a), (a, c), (c, a)]) + graph1 = Graph(vertices, edges) + graph2 = graph1.single_edge() + edges = {(a, b), (b, a), (a, c), (c, a)} vertices = set(vertices) - self.assertEqual(G2.vertices, vertices) - self.assertEqual(G2.edges, edges) - self.assertEqual(G2.adj[a], {b, c}) - self.assertEqual(G2.adj[b], {a}) - self.assertEqual(G2.adj[c], {a}) - self.assertEqual(G2.adj[d], set()) + self.assertEqual(graph2.vertices, vertices) + self.assertEqual(graph2.edges, edges) + self.assertEqual(graph2.adj[a], {b, c}) + self.assertEqual(graph2.adj[b], {a}) + self.assertEqual(graph2.adj[c], {a}) + self.assertEqual(graph2.adj[d], set()) def testUnion(self): a = Vertex(1) From b072ccc08ec9130dbc78d6bfd60c80aa622d21e4 Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 6 Jan 2021 00:02:09 +0800 Subject: [PATCH 30/49] generate random array for test purpose --- random_array.py | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 random_array.py diff --git a/random_array.py b/random_array.py new file mode 100644 index 0000000..e1a7cca --- /dev/null +++ b/random_array.py @@ -0,0 +1,6 @@ +import random + + +def random_arrays(array_num=100, array_size=100, array_lowerbound=0, array_upperbound=10000): + for _ in range(array_num): + yield [random.randint(array_lowerbound, array_upperbound) for _ in range(array_size)] From 1dda23d8a07267300f11d966490f7bf355d1476c Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 6 Jan 2021 00:19:58 +0800 Subject: [PATCH 31/49] algorithm to calculate lowest common multiple --- lowest_common_multiple.py | 5 +++++ polygon_area.py | 5 ++++- qsort.c | 25 ------------------------- tests/test_lowest_common_multiple.py | 9 +++++++++ tree.py | 4 ++-- 5 files changed, 20 insertions(+), 28 deletions(-) create mode 100644 lowest_common_multiple.py delete mode 100644 qsort.c create mode 100644 tests/test_lowest_common_multiple.py diff --git a/lowest_common_multiple.py b/lowest_common_multiple.py new file mode 100644 index 0000000..7706aba --- /dev/null +++ b/lowest_common_multiple.py @@ -0,0 +1,5 @@ +from gcd import gcd + + +def lcm(num1: int, num2: int): + return num1 * num2 // gcd(num1, num2) diff --git a/polygon_area.py b/polygon_area.py index f14c739..d28aa35 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -1,7 +1,10 @@ #!/usr/bin/env python +from typing import Sequence, Tuple, Union +Number = Union[int, float] -def polygon_area(polygon): + +def polygon_area(polygon: Sequence[Tuple[Number, Number]]) -> float: n = len(polygon) area = 0 for i in range(n - 1): diff --git a/qsort.c b/qsort.c deleted file mode 100644 index 9729ace..0000000 --- a/qsort.c +++ /dev/null @@ -1,25 +0,0 @@ -/* qsort: sort v[left]...v[right] into increasing order */ -void qsort(int v[], int left, int right) { - int i, last; - - void swap(int v[], int, int); - - if (left >= right) /* do nothing if array contains */ - return; /* fewer than two elements */ - swap(v, left, (left + right)/2); - last = left; - for (i = left + 1; i <= right; i++) - if (v[i] < v[left]) - swap(v, ++last, i); - swap(v, left, last); - qsort(v, left, last - 1 ); - qsort(v, last+1, right); -} - -void swap(int v[], int i, int j) { - int temp; - - temp = v[i]; - v[i] = v[j]; - v[j] = temp; -} diff --git a/tests/test_lowest_common_multiple.py b/tests/test_lowest_common_multiple.py new file mode 100644 index 0000000..ed59060 --- /dev/null +++ b/tests/test_lowest_common_multiple.py @@ -0,0 +1,9 @@ +from unittest import TestCase +from lowest_common_multiple import lcm + + +class LcmTest(TestCase): + def test_lcm(self): + self.assertEqual(lcm(10, 1), 10) + self.assertEqual(lcm(10, 8), 40) + self.assertEqual(lcm(15, 9), 45) diff --git a/tree.py b/tree.py index f9aa6dc..3295893 100755 --- a/tree.py +++ b/tree.py @@ -160,9 +160,9 @@ def delete(self, z): # inorder_tree_walk_stack(T.root) # T.root.inorder_tree_walk_stack() # T.root.inorder_tree_walk() -print() +# print() # T.root.preorder_tree_walk() -print() +# print() # T.root.postorder_tree_walk() # x = T.root.iterative_tree_search(50) # if x is None: From 950677c7eea870cdc756e7c70131528198046e0a Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 6 Jan 2021 01:07:59 +0800 Subject: [PATCH 32/49] move merge method to another file --- k_way_merge.py | 4 +-- merge.py | 56 +++++++++++++++++++++++++++++++++++++ merge_sort.py | 59 +-------------------------------------- tests/k_way_merge_test.py | 14 ++++------ tests/merge_sort_test.py | 3 +- tests/test_merge.py | 25 +++++++++++++++++ tests/two_sum_test.py | 4 +-- 7 files changed, 94 insertions(+), 71 deletions(-) create mode 100644 merge.py create mode 100644 tests/test_merge.py diff --git a/k_way_merge.py b/k_way_merge.py index 1fc0a8a..f014ba6 100644 --- a/k_way_merge.py +++ b/k_way_merge.py @@ -39,6 +39,6 @@ def k_way_merge(lists): elif length == 2: return merge(lists[0], lists[1]) else: - list1 = k_way_merge(lists[0:length // 2]) - list2 = k_way_merge(lists[length // 2: length]) + list1 = k_way_merge(lists[:length // 2]) + list2 = k_way_merge(lists[length // 2:]) return merge(list1, list2) diff --git a/merge.py b/merge.py new file mode 100644 index 0000000..62957e5 --- /dev/null +++ b/merge.py @@ -0,0 +1,56 @@ +def merge_with_sentinel(array, left, mid, right): + """ + merge procedure with sentinels + + merge array[left...mid] and array[mid + 1...right] + :param array: + :param left: + :param mid: + :param right: + :return: + """ + left_part = array[left: mid + 1] + left_part.append(float("Inf")) + right_part = array[mid + 1: right + 1] + right_part.append(float("Inf")) + i = 0 + j = 0 + for k in range(left, right + 1): + if left_part[i] <= right_part[j]: + array[k] = left_part[i] + i += 1 + else: + array[k] = right_part[j] + j += 1 + + +def merge_without_sentinel(array, left, mid, right): + """ + merge procedure without sentinels + + A merge procedure without sentinels that stops once either array `left_part` or `right_part` has had all its elements + copied back to `array` and then copying the remainder of another array back into `array` + :param array: + :param left: + :param mid: + :param right: + :return: + """ + left_part = array[left: mid + 1] + right_part = array[mid + 1: right + 1] + i = 0 + j = 0 + k = left + while i < len(left_part) and j < len(right_part): + if left_part[i] <= right_part[j]: + array[k] = left_part[i] + k += 1 + i += 1 + else: + array[k] = right_part[j] + k += 1 + j += 1 + if i < len(left_part): + array[k: right + 1] = left_part[i:] + else: + array[k: right + 1] = right_part[j:] \ No newline at end of file diff --git a/merge_sort.py b/merge_sort.py index 00760e1..12bad53 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -1,62 +1,5 @@ from insertion_sort import insertion_sort - - -def merge_with_sentinel(array, left, mid, right): - """ - merge procedure with sentinels - - merge array[left...mid] and array[mid + 1...right] - :param array: - :param left: - :param mid: - :param right: - :return: - """ - left_part = array[left: mid + 1] - left_part.append(float("Inf")) - right_part = array[mid + 1: right + 1] - right_part.append(float("Inf")) - i = 0 - j = 0 - for k in range(left, right + 1): - if left_part[i] <= right_part[j]: - array[k] = left_part[i] - i = i + 1 - else: - array[k] = right_part[j] - j = j + 1 - - -def merge_without_sentinel(array, left, mid, right): - """ - merge procedure without sentinels - - A merge procedure without sentinels that stops once either array `left_part` or `right_part` has had all its elements - copied back to `array` and then copying the remainder of another array back into `array` - :param array: - :param left: - :param mid: - :param right: - :return: - """ - left_part = array[left: mid + 1] - right_part = array[mid + 1: right + 1] - i = 0 - j = 0 - k = left - while i < len(left_part) and j < len(right_part): - if left_part[i] <= right_part[j]: - array[k] = left_part[i] - k = k + 1 - i = i + 1 - else: - array[k] = right_part[j] - k = k + 1 - j = j + 1 - if i < len(left_part): - array[k: right + 1] = left_part[i:] - else: - array[k: right + 1] = right_part[j:] +from merge import merge_with_sentinel def merge_sort(array, merge_method=merge_with_sentinel): diff --git a/tests/k_way_merge_test.py b/tests/k_way_merge_test.py index f30e50a..e1944fd 100644 --- a/tests/k_way_merge_test.py +++ b/tests/k_way_merge_test.py @@ -1,16 +1,14 @@ #!/usr/bin/env python import unittest -import random from k_way_merge import k_way_merge +from random_array import random_arrays class TestKWayMerge(unittest.TestCase): def test_k_way_merge(self): - for j in range(10000): - A = [random.randint(1, 10000) for _ in range(100)] - lists = [None] * 10 + for array in random_arrays(): + lists = [] for i in range(10): - lists[i] = A[10 * i: (i + 1) * 10] - lists[i].sort() - A.sort() - self.assertEqual(k_way_merge(lists), A) + lists.append(array[10 * i: (i + 1) * 10]) + lists[-1].sort() + self.assertEqual(k_way_merge(lists), sorted(array)) diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 1b46f29..9e7c2a6 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -1,7 +1,8 @@ #!/usr/bin/env python import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, merge_ins_sort_top_to_bottom +from merge_sort import merge_sort, merge_ins_sort_bottom_to_top, merge_ins_sort_top_to_bottom +from merge import merge_with_sentinel, merge_without_sentinel class TestMergeSort(unittest.TestCase): diff --git a/tests/test_merge.py b/tests/test_merge.py new file mode 100644 index 0000000..18881b8 --- /dev/null +++ b/tests/test_merge.py @@ -0,0 +1,25 @@ +from unittest import TestCase +from merge import merge_without_sentinel, merge_with_sentinel +from random_array import random_arrays + + +class MergeTest(TestCase): + def test_merge_with_sentinel(self): + for array in random_arrays(): + left_array = array[:len(array) // 2] + right_array = array[len(array) // 2:] + left_array.sort() + right_array.sort() + result_array = left_array + right_array + merge_with_sentinel(result_array, 0, len(array) // 2 - 1, len(array) - 1) + self.assertEqual(result_array, sorted(array)) + + def test_merge_without_sentinel(self): + for array in random_arrays(): + left_array = array[:len(array) // 2] + right_array = array[len(array) // 2:] + left_array.sort() + right_array.sort() + result_array = left_array + right_array + merge_without_sentinel(result_array, 0, len(array) // 2 - 1, len(array) - 1) + self.assertEqual(result_array, sorted(array)) diff --git a/tests/two_sum_test.py b/tests/two_sum_test.py index 1ffcad1..415afac 100644 --- a/tests/two_sum_test.py +++ b/tests/two_sum_test.py @@ -1,12 +1,12 @@ import unittest +from random_array import random_arrays import random from two_sum import two_sum class TestInsertionSort(unittest.TestCase): def test_two_sum(self): - for _ in range(1000): - array = [random.randint(1, 20) for _ in range(10)] + for array in random_arrays(array_num=1000, array_size=10, array_lowerbound=1, array_upperbound=20): x = random.randint(1, 100) n = len(array) result = False From e871764020711cf27e6714b932cafa8fedf1f2b6 Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 6 Jan 2021 01:26:00 +0800 Subject: [PATCH 33/49] refactor "if cond return True else return False" style code --- any_disks_intersect.py | 10 ++------- any_segments_intersect.py | 30 ++++++-------------------- hamiltonian_path.py | 5 +---- huffman.py | 45 +++++++++++++-------------------------- kleene_star.py | 5 +---- segment_intersect.py | 6 ++---- 6 files changed, 28 insertions(+), 73 deletions(-) diff --git a/any_disks_intersect.py b/any_disks_intersect.py index 3fb6f3c..29a139f 100644 --- a/any_disks_intersect.py +++ b/any_disks_intersect.py @@ -10,10 +10,7 @@ def comparable(a, b): """Given two disks a and b that are comparable at x, determine whether a is above b or not.""" a_y = a[0][1] b_y = b[0][1] - if a_y >= b_y: - return True - else: - return False + return a_y >= b_y class disk(tuple): @@ -304,7 +301,4 @@ def disks_intersect(a, b): b_r = b[1] print((a_x - b_x) ** 2 + (a_y - b_y) ** 2) print((a_r + b_r) ** 2) - if ((a_x - b_x) ** 2 + (a_y - b_y) ** 2) <= ((a_r + b_r) ** 2): - return True - else: - return False + return ((a_x - b_x) ** 2 + (a_y - b_y) ** 2) <= ((a_r + b_r) ** 2) diff --git a/any_segments_intersect.py b/any_segments_intersect.py index a7e4c59..fe5b756 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -12,7 +12,9 @@ def vertical(a): def comparable(a, b, x): - """Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical """ + """ + Given two segments a and b that are comparable at x, determine whether a is above b or not. Assume that neither segment is vertical + """ p1 = a[0] p2 = a[1] p3 = b[0] @@ -20,41 +22,23 @@ def comparable(a, b, x): x4 = p4[0] x3 = p3[0] if vertical(a) and vertical(b): - if p1[1] >= p3[1]: - return True - else: - return False + return p1[1] >= p3[1] elif vertical(a) and not vertical(b): v1 = (p4[0] - p3[0], p4[1] - p3[1]) v2 = (p4[0] - p1[0], p4[1] - p1[1]) result = v1[0] * v2[1] - v2[0] * v1[1] - # a is below b - if result >= 0: - return False - # a is above b - else: - return True + return result < 0 elif not vertical(a) and vertical(b): v1 = (p2[0] - p1[0], p2[1] - p1[1]) v2 = (p2[0] - p3[0], p2[1] - p3[1]) result = v1[0] * v2[1] - v2[0] * v1[1] - # a is above b - if result >= 0: - return True - # a is above b - else: - return False + return result >= 0 else: v1 = (p2[0] - p1[0], p2[1] - p1[1]) v2 = ((x4 - x3) * (p2[0] - p4[0]) + (x4 - x) * (p4[0] - p3[0]), (x4 - x3) * (p2[1] - p4[1]) + (x4 - x) * (p4[1] - p3[1])) result = v1[0] * v2[1] - v2[0] * v1[1] - # a is above b - if result >= 0: - return True - # a is below b - else: - return False + return result >= 0 class segment(tuple): diff --git a/hamiltonian_path.py b/hamiltonian_path.py index a7c690f..568c6a7 100644 --- a/hamiltonian_path.py +++ b/hamiltonian_path.py @@ -13,7 +13,4 @@ def w(x, y): return we[(x, y)] G.dag_shortest_paths(w, u) - if abs(v.d) == len(G.vertices) - 1: - return True - else: - return False + return abs(v.d) == len(G.vertices) - 1 diff --git a/huffman.py b/huffman.py index e9d1fe1..6b89cbb 100644 --- a/huffman.py +++ b/huffman.py @@ -18,24 +18,19 @@ def __init__(self, char, freq, sibling=None): self.sibling = sibling def __eq__(self, y): - if self.freq == y.freq: - return True + return self.freq == y.freq def __gt__(self, y): - if self.freq > y.freq: - return True + return self.freq > y.freq def __ge__(self, y): - if self.freq >= y.freq: - return True + return self.freq >= y.freq def __le__(self, y): - if self.freq <= y.freq: - return True + return self.freq <= y.freq def __lt__(self, y): - if self.freq < y.freq: - return True + return self.freq < y.freq class node: @@ -45,24 +40,19 @@ def __init__(self, left, right, freq): self.freq = freq def __eq__(self, y): - if self.freq == y.freq: - return True + return self.freq == y.freq def __gt__(self, y): - if self.freq > y.freq: - return True + return self.freq > y.freq def __ge__(self, y): - if self.freq >= y.freq: - return True + return self.freq >= y.freq def __le__(self, y): - if self.freq <= y.freq: - return True + return self.freq <= y.freq def __lt__(self, y): - if self.freq < y.freq: - return True + return self.freq < y.freq class tenary_node: @@ -72,24 +62,19 @@ def __init__(self, freq, child=None, sibling=None): self.sibling = sibling def __eq__(self, y): - if self.freq == y.freq: - return True + return self.freq == y.freq def __gt__(self, y): - if self.freq > y.freq: - return True + return self.freq > y.freq def __ge__(self, y): - if self.freq >= y.freq: - return True + return self.freq >= y.freq def __le__(self, y): - if self.freq <= y.freq: - return True + return self.freq <= y.freq def __lt__(self, y): - if self.freq < y.freq: - return True + return self.freq < y.freq def huffman(chars, freqs): diff --git a/kleene_star.py b/kleene_star.py index 8cd4ff9..c7238fd 100644 --- a/kleene_star.py +++ b/kleene_star.py @@ -14,7 +14,4 @@ def kleene_star(x, L, A): m[i - 1, j - 1] = 1 if m[i - 1, j - 1] != 1: m[i - 1, j - 1] = A(x[i - 1:j], L) - if m[0, length - 1] != 0: - return True - else: - return False + return m[0, length - 1] != 0 diff --git a/segment_intersect.py b/segment_intersect.py index 413ef87..9a594ab 100644 --- a/segment_intersect.py +++ b/segment_intersect.py @@ -27,7 +27,5 @@ def direction(pi, pj, pk): def on_segment(pi, pj, pk): - if min(pi[0], pj[0]) <= pk[0] and pk[0] <= max(pi[0], pj[0]) and min(pi[1], pj[1]) <= pk[1] and pk[1] <= max(pi[1], pj[1]): - return True - else: - return False + return min(pi[0], pj[0]) <= pk[0] <= max(pi[0], pj[0]) and min(pi[1], pj[1]) <= pk[1] <= max( + pi[1], pj[1]) From 61a2954dd31236fc3f4be28315a18f7c1acba9ab Mon Sep 17 00:00:00 2001 From: wq Date: Fri, 8 Jan 2021 08:12:55 +0800 Subject: [PATCH 34/49] eight queen --- eight_queen.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 eight_queen.py diff --git a/eight_queen.py b/eight_queen.py new file mode 100644 index 0000000..6c4f155 --- /dev/null +++ b/eight_queen.py @@ -0,0 +1,37 @@ +N = 8 +counter = 0 + + +def print_solution(chess_board): + for row in range(N): + for col in range(N): + if chess_board[row] != col: + print('-', end=' ') + else: + print('X', end=' ') + print('\n') + print('\n') + + +def isplaceok(chess_board, row, col): + return not any( + (chess_board[i] == col) or (chess_board[i] - col == row - i) or (chess_board[i] - col == i - row) for i in + range(row)) + + +def add_queen(chess_board, row): + global counter + if row >= N: + print_solution(chess_board) + counter += 1 + else: + for col in range(N): + if isplaceok(chess_board, row, col): + chess_board[row] = col + add_queen(chess_board, row + 1) + + +if __name__ == "__main__": + chess_board = [-1] * N + add_queen(chess_board, 0) + print(counter) From 33049021cb2d96b76d8a237e44d8b4b049fb5d37 Mon Sep 17 00:00:00 2001 From: wq Date: Wed, 23 Jun 2021 14:00:13 +0800 Subject: [PATCH 35/49] add unittest for polygon_area.py --- any_segments_intersect.py | 19 ++++++++++++------- polygon_area.py | 5 +---- polygon_area_test.py | 11 +++++++++++ 3 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 polygon_area_test.py diff --git a/any_segments_intersect.py b/any_segments_intersect.py index fe5b756..38762d4 100644 --- a/any_segments_intersect.py +++ b/any_segments_intersect.py @@ -137,7 +137,9 @@ def right_rotate(self, y): y.p = x def insert(self, z): - """ the segment z will only be inserted when the left endpoint of z is being processed""" + """ + the segment z will only be inserted when the left endpoint of z is being processed + """ # this is the x_coordinate of the left endpoint of z x_coordinate = z[0][0] z = rb_node(z, None, None, None, 0) @@ -279,7 +281,9 @@ def delete_fixup(self, x): def any_segments_intersect(S): - """This algorithm takes as input a set S of n line segments, returning the boolean value TRUE if any pair of segments in S intersects, and FALSE otherwise.""" + """ + This algorithm takes as input a set S of n line segments, returning the boolean value TRUE if any pair of segments in S intersects, and FALSE otherwise. + """ T = rb_tree() segment_list = [] point_list = [] @@ -296,16 +300,17 @@ def any_segments_intersect(S): T.insert(s) a = T.above(s) b = T.below(s) - if (a is not None and segments_intersect(a[0], a[1], s[0], s[1])) or (b is not None and segments_intersect(b[0], b[1], s[0], s[1])): + if (a is not None and segments_intersect(a[0], a[1], s[0], s[1])) or ( + b is not None and segments_intersect(b[0], b[1], s[0], s[1])): return True if p[1] == 1: s = p.segment a = T.above(s) b = T.below(s) -# print( a) -# print( b) -# print( type(a)) -# print( type(b)) + # print( a) + # print( b) + # print( type(a)) + # print( type(b)) if a is not None and b is not None and segments_intersect(a[0], a[1], b[0], b[1]): return True T.delete(s) diff --git a/polygon_area.py b/polygon_area.py index d28aa35..d91de2b 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -3,11 +3,8 @@ Number = Union[int, float] - def polygon_area(polygon: Sequence[Tuple[Number, Number]]) -> float: n = len(polygon) - area = 0 - for i in range(n - 1): - area += (polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) + area = sum((polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) for i in range(n - 1)) area += (polygon[0][0] + polygon[n - 1][0]) * (polygon[0][1] - polygon[n - 1][1]) return 0.5 * abs(area) diff --git a/polygon_area_test.py b/polygon_area_test.py new file mode 100644 index 0000000..040423f --- /dev/null +++ b/polygon_area_test.py @@ -0,0 +1,11 @@ +import unittest +from polygon_area import polygon_area + +class TestPolygonArea(unittest.TestCase): + def test_rectangle_area(self): + rectangle = ((0, 0), (0, 2), (2, 2), (2, 0)) + self.assertEqual(polygon_area(rectangle), 4) + + def test_triangle_area(self): + triangle = ((0, 0), (5, 0), (2.5, 5)) + self.assertEqual(polygon_area(triangle), 12.5) From a542476797b40ea9df931cff4e6009e7e080e14c Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 22 Jul 2021 23:39:30 +0800 Subject: [PATCH 36/49] rewrite pow function in python and delete pow.c --- heap.py | 4 ++-- polygon_area.py | 1 + polygon_area_test.py | 3 ++- pow.c | 33 --------------------------------- pow.py | 22 ++++++++++++++++++++++ tests/test_pow.py | 16 ++++++++++++++++ 6 files changed, 43 insertions(+), 36 deletions(-) delete mode 100644 pow.c create mode 100644 pow.py create mode 100644 tests/test_pow.py diff --git a/heap.py b/heap.py index ee7d56a..6342f23 100644 --- a/heap.py +++ b/heap.py @@ -1,6 +1,6 @@ class MaxHeap(list): def __init__(self, data): - super(MaxHeap, self).__init__(data) + super().__init__(data) self.length = len(self) self.heap_size = self.length self.build_max_heap() @@ -45,7 +45,7 @@ def heapsort(self): class MinHeap(list): def __init__(self, data): - super(MinHeap, self).__init__(data) + super().__init__(data) self.length = len(self) self.heap_size = self.length self.build_min_heap() diff --git a/polygon_area.py b/polygon_area.py index d91de2b..6d41e6e 100644 --- a/polygon_area.py +++ b/polygon_area.py @@ -3,6 +3,7 @@ Number = Union[int, float] + def polygon_area(polygon: Sequence[Tuple[Number, Number]]) -> float: n = len(polygon) area = sum((polygon[i][0] + polygon[i + 1][0]) * (polygon[i + 1][1] - polygon[i][1]) for i in range(n - 1)) diff --git a/polygon_area_test.py b/polygon_area_test.py index 040423f..7afde26 100644 --- a/polygon_area_test.py +++ b/polygon_area_test.py @@ -1,9 +1,10 @@ import unittest from polygon_area import polygon_area + class TestPolygonArea(unittest.TestCase): def test_rectangle_area(self): - rectangle = ((0, 0), (0, 2), (2, 2), (2, 0)) + rectangle = ((0, 0), (0, 2), (2, 2), (2, 0)) self.assertEqual(polygon_area(rectangle), 4) def test_triangle_area(self): diff --git a/pow.c b/pow.c deleted file mode 100644 index 9a2501a..0000000 --- a/pow.c +++ /dev/null @@ -1,33 +0,0 @@ -/* pow: compute x^n; return value: x ^ n */ -int pow1(int x, unsigned n) { - int square; - - if (n == 0) - return 1; - if (n == 1) - return x; - - square = x * x; - if (n == 2) - return square; - if (n % 2) - return pow1(square, n / 2) * x; - else - return pow1(square, n / 2); -} - -int pow2(int x, unsigned n) { - int tmp; - - if (n == 0) - return 1; - if (n == 1) - return x; - if (n == 2) - return x * x; - tmp = pow2(x, n / 2); - if (n % 2) - return tmp * tmp * x; - else - return tmp * tmp; -} diff --git a/pow.py b/pow.py new file mode 100644 index 0000000..00b5f0a --- /dev/null +++ b/pow.py @@ -0,0 +1,22 @@ +def pow1(x, n: int): + """ + compute x ^ n + """ + if n == 0: + return 1 + square = x * x + if n % 2: + return pow1(square, n // 2) * x + return pow1(square, n // 2) + + +def pow2(x, n: int): + """ + compute x ^ n + """ + if n == 0: + return 1 + tmp = pow2(x, n // 2) + if n % 2: + return tmp * tmp * x + return tmp * tmp diff --git a/tests/test_pow.py b/tests/test_pow.py new file mode 100644 index 0000000..48d87b0 --- /dev/null +++ b/tests/test_pow.py @@ -0,0 +1,16 @@ +import math +import random +from unittest import TestCase +from pow import pow1, pow2 + + +class Test(TestCase): + def test_pow1(self): + x = random.randint(1, 10) + for n in range(10): + self.assertEqual(pow1(x, n), math.pow(x, n)) + + def test_pow2(self): + x = random.randint(1, 10) + for n in range(10): + self.assertEqual(pow2(x, n), math.pow(x, n)) From ccaebf2d7bae5ef562c949bb9bd31691e5b78585 Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 22 Jul 2021 23:50:35 +0800 Subject: [PATCH 37/49] conform to PEP8 --- merge_sort.py | 12 ++++++------ tests/merge_sort_test.py | 6 +++--- three_sum.py | 23 +++++++++++++---------- two_sum.py | 2 +- 4 files changed, 23 insertions(+), 20 deletions(-) diff --git a/merge_sort.py b/merge_sort.py index 9e07bea..d35f187 100644 --- a/merge_sort.py +++ b/merge_sort.py @@ -79,7 +79,7 @@ def _merge_sort(array, left, right, merge_method): merge_method(array, left, mid, right) -def merge_ins_sort(array, partition=2): +def merge_ins_sort_bottom_to_top(array, partition=2): """ Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines. @@ -108,7 +108,7 @@ def merge_ins_sort(array, partition=2): sublist_number = math.ceil(sublist_number / 2) -def merge_ins_sort2(array, sublist_length): +def merge_ins_sort_top_to_bottom(array, sublist_length): """ Although merge sort runs faster than insertion sort asymptotically, the constant factors in insertion sort can make it faster in practice for small problem sizes on many machines. @@ -123,10 +123,10 @@ def merge_ins_sort2(array, sublist_length): """ n = len(array) assert 0 < sublist_length < n - _merge_ins_sort2(array, 0, n - 1, sublist_length) + _merge_ins_sort_top_to_bottom(array, 0, n - 1, sublist_length) -def _merge_ins_sort2(array, start, end, sublist_length): +def _merge_ins_sort_top_to_bottom(array, start, end, sublist_length): """ :param array: @@ -138,8 +138,8 @@ def _merge_ins_sort2(array, start, end, sublist_length): length = end - start + 1 if length > sublist_length: mid = (start + end) // 2 - _merge_ins_sort2(array, start, mid, sublist_length) - _merge_ins_sort2(array, mid + 1, end, sublist_length) + _merge_ins_sort_top_to_bottom(array, start, mid, sublist_length) + _merge_ins_sort_top_to_bottom(array, mid + 1, end, sublist_length) merge_with_sentinel(array, start, mid, end) else: insertion_sort(array, start, end) diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 2b09e49..881c64e 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort, merge_ins_sort2 +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, merge_ins_sort_top_to_bottom class TestMergeSort(unittest.TestCase): @@ -23,10 +23,10 @@ def test_merge_ins_sort(self): for length in range(100, 200): array = [random.randint(1, 10000) for _ in range(length)] array_copy = array[:] - merge_ins_sort(array, partition=1) + merge_ins_sort_bottom_to_top(array, partition=1) self.assertEqual(array, sorted(array_copy)) for length in range(100, 200): array = [random.randint(1, 10000) for _ in range(length)] array_copy = array[:] - merge_ins_sort2(array, sublist_length=15) + merge_ins_sort_top_to_bottom(array, sublist_length=15) self.assertEqual(array, sorted(array_copy)) diff --git a/three_sum.py b/three_sum.py index 4fec1d0..b1bfd46 100644 --- a/three_sum.py +++ b/three_sum.py @@ -1,23 +1,26 @@ #!/usr/bin/env python # coding=utf-8 -def threeSum(A): - '''Given an array A of n integers, find one triplet + +def three_sum(array): + """ + Given an array `array` of n integers, find one triplet in the array which gives the sum of zero. - A must be in increasing order''' - n = len(A) + `array` must be in increasing order + :param array: + :return: + """ + + n = len(array) for i in range(n - 2): j = i + 1 k = n - 1 while k >= j: - if A[i] + A[j] + A[k] == 0: - return (A[i], A[j], A[k]) - elif A[i] + A[j] + A[k] > 0: + if array[i] + array[j] + array[k] == 0: + return array[i], array[j], array[k] + elif array[i] + array[j] + array[k] > 0: k = k - 1 else: j = j + 1 - - - diff --git a/two_sum.py b/two_sum.py index d6301e0..cb906c6 100644 --- a/two_sum.py +++ b/two_sum.py @@ -1,4 +1,4 @@ -def two_sum(x:int, array:list): +def two_sum(x: int, array: list): """ an algorithm that, given a set S of n integers and another integer x, determines whether or not there exist two elements in S whose sum is exactly x. From e6a3a48aa41988a13e2366c73245eeda4318c77c Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 22 Jul 2021 23:53:21 +0800 Subject: [PATCH 38/49] conform to PEP8 --- tests/merge_sort_test.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/merge_sort_test.py b/tests/merge_sort_test.py index 881c64e..f5e81de 100644 --- a/tests/merge_sort_test.py +++ b/tests/merge_sort_test.py @@ -1,7 +1,8 @@ #!/usr/bin/env python import unittest import random -from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, merge_ins_sort_top_to_bottom +from merge_sort import merge_sort, merge_with_sentinel, merge_without_sentinel, merge_ins_sort_bottom_to_top, \ + merge_ins_sort_top_to_bottom class TestMergeSort(unittest.TestCase): From 9207c9ab4db3cbd35e4854910834b54e5c1a5911 Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 22 Jul 2021 23:59:19 +0800 Subject: [PATCH 39/49] conform to PEP8 --- binary_counter.py => binarycounter.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename binary_counter.py => binarycounter.py (95%) diff --git a/binary_counter.py b/binarycounter.py similarity index 95% rename from binary_counter.py rename to binarycounter.py index f2a334f..4526486 100644 --- a/binary_counter.py +++ b/binarycounter.py @@ -1,4 +1,4 @@ -class binary_counter(list): +class BinaryCounter(list): def __init__(self, size): self.leftmost_1 = -1 list.__init__(self, [0] * size) From 4ce0ce6f88564f88da6d91b5c0ed0438b78011fd Mon Sep 17 00:00:00 2001 From: wq Date: Thu, 22 Jul 2021 23:59:48 +0800 Subject: [PATCH 40/49] conform to PEP8 --- tree.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tree.py b/tree.py index 5ea2034..762c6fa 100755 --- a/tree.py +++ b/tree.py @@ -1,9 +1,7 @@ #!/usr/bin/env python -import random - -class Node(object): +class Node: def __init__(self, key, p, left, right): self.key = key self.p = p @@ -32,8 +30,7 @@ def postorder_tree_walk(self): print(self.key, ) def inorder_tree_walk_stack(self): - s = [] - s.append({"data": self, "status": 0}) + s = [{"data": self, "status": 0}] while len(s) != 0: record = s.pop() if record["status"] == 0: @@ -87,7 +84,7 @@ def predecessor(self): return x.p -class Tree(object): +class Tree: root = None def __init__(self, values): From 3a4d9dd92e2d9a128188849c553a8e584ef73f37 Mon Sep 17 00:00:00 2001 From: wq Date: Fri, 23 Jul 2021 00:05:38 +0800 Subject: [PATCH 41/49] conform to PEP8 --- selection_sort.py | 2 +- stack.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/selection_sort.py b/selection_sort.py index 6bdf522..5bdbae6 100644 --- a/selection_sort.py +++ b/selection_sort.py @@ -2,7 +2,7 @@ # encoding: utf-8 -def selection_sort(array:list): +def selection_sort(array: list): """ Inplace sort Consider sorting n numbers stored in array A by first finding the smallest element of A diff --git a/stack.py b/stack.py index eb8e765..fdee232 100644 --- a/stack.py +++ b/stack.py @@ -6,7 +6,7 @@ class EmptyException(BaseException): pass -class stack(list): +class Stack(list): def __init__(self, size): list.__init__(self, [None] * size) self.top = -1 From 46785dd35adf9715b91172a6d087f31848edb96b Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 23 Jul 2021 01:40:00 +0800 Subject: [PATCH 42/49] add queue.py --- .idea/algorithm.iml | 14 ++ .idea/dbnavigator.xml | 449 ++++++++++++++++++++++++++++++++++++++++++ .idea/encodings.xml | 4 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/vcs.xml | 6 + binary_add.py | 27 +++ queue.py | 42 ++++ 8 files changed, 554 insertions(+) create mode 100644 .idea/algorithm.iml create mode 100644 .idea/dbnavigator.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml create mode 100644 binary_add.py create mode 100644 queue.py diff --git a/.idea/algorithm.iml b/.idea/algorithm.iml new file mode 100644 index 0000000..4c9caa9 --- /dev/null +++ b/.idea/algorithm.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/dbnavigator.xml b/.idea/dbnavigator.xml new file mode 100644 index 0000000..51e620f --- /dev/null +++ b/.idea/dbnavigator.xml @@ -0,0 +1,449 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2ba6d76 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/binary_add.py b/binary_add.py new file mode 100644 index 0000000..a1499ea --- /dev/null +++ b/binary_add.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python +# encoding: utf-8 + + +def binary_add(array1, array2): + """ + Consider the problem of adding two n-bit binary integers, stored in two n-element arrays A and B, + in big-endian order. + The sum of the two integers should be stored in binary form in a (n + 1)-element array C. + :param array1: n-element array A + :param array2: n-element array B + :return: (n + 1)-element array C + """ + assert len(array1) == len(array2) + n = len(array1) + promote = 0 + array3 = [0] * (n + 1) + for i in range(n - 1, -1, -1): + result = array1[i] + array2[i] + promote + if result >= 2: + result -= 2 + promote = 1 + else: + promote = 0 + array3[i + 1] = result + array3[0] = promote + return array3 diff --git a/queue.py b/queue.py new file mode 100644 index 0000000..72b1ff0 --- /dev/null +++ b/queue.py @@ -0,0 +1,42 @@ +class FullException(Exception): + def __init__(self): + Exception.__init__(self) + + +class EmptyException(Exception): + def __init__(self): + Exception.__init__(self) + + +class Queue(object): + def __init__(self, size): + self.data = [0] * size + self.length = size + self.head = 0 + self.tail = 0 + + def enqueue(self, x): + if self.full(): + raise FullException() + self.data[self.tail] = x + if self.tail == self.length - 1: + self.tail = 0 + else: + self.tail = self.tail + 1 + + def dequeue(self): + if self.empty(): + raise EmptyException() + x = self.data[self.head] + if self.head == self.length - 1: + self.head = 0 + else: + self.head = self.head + 1 + return x + + def empty(self): + return self.tail == self.head + + def full(self): + # print( "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length)) + return (self.tail + 1) % self.length == self.head From 2816a07c1e06df129c418c86e2f840bb978663ce Mon Sep 17 00:00:00 2001 From: wq Date: Fri, 23 Jul 2021 01:41:15 +0800 Subject: [PATCH 43/49] add IDE config --- .idea/algorithm.iml | 15 +++++++++++++++ .idea/codeStyles/codeStyleConfig.xml | 5 +++++ .idea/encodings.xml | 4 ++++ .idea/inspectionProfiles/profiles_settings.xml | 6 ++++++ .idea/misc.xml | 4 ++++ .idea/modules.xml | 8 ++++++++ .idea/vcs.xml | 6 ++++++ 7 files changed, 48 insertions(+) create mode 100644 .idea/algorithm.iml create mode 100644 .idea/codeStyles/codeStyleConfig.xml create mode 100644 .idea/encodings.xml create mode 100644 .idea/inspectionProfiles/profiles_settings.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.idea/algorithm.iml b/.idea/algorithm.iml new file mode 100644 index 0000000..8f02df6 --- /dev/null +++ b/.idea/algorithm.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..a55e7a1 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..15a15b2 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..d56657a --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2ba6d76 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file From 271edad207b5bcfe0f8e6ff8d1bde38d0d95c0ac Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 24 Jul 2021 00:59:47 +0800 Subject: [PATCH 44/49] use true divider and remainder operator to calculate promote and result of binary add --- binary_add.py | 7 ++----- deque.py | 9 +++++---- hash.py | 1 - queue.py | 2 +- tests/test_binary_add.py | 9 +++++++++ 5 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 tests/test_binary_add.py diff --git a/binary_add.py b/binary_add.py index a1499ea..baf23e6 100644 --- a/binary_add.py +++ b/binary_add.py @@ -17,11 +17,8 @@ def binary_add(array1, array2): array3 = [0] * (n + 1) for i in range(n - 1, -1, -1): result = array1[i] + array2[i] + promote - if result >= 2: - result -= 2 - promote = 1 - else: - promote = 0 + promote = result // 2 + result = result % 2 array3[i + 1] = result array3[0] = promote return array3 diff --git a/deque.py b/deque.py index 9590822..5a8d313 100644 --- a/deque.py +++ b/deque.py @@ -1,13 +1,14 @@ -from Queue import Queue, FullException, EmptyException +from queue import Queue, FullException, EmptyException -def deque(Queue): +class Deque(Queue): """ - whereas a Queue allows insertion at one end and deletion at the other end, a deque(double-ended Queue allows insertion and deletion at both ends + whereas a Queue allows insertion at one end and deletion at the other end, + a Deque(double-ended Queue) allows insertion and deletion at both ends """ def __init__(self, size): - super(deque, self).__init__(size) + super().__init__(size) def enqueue_tail(self, x): self.enqueue(x) diff --git a/hash.py b/hash.py index f234d74..31a2505 100755 --- a/hash.py +++ b/hash.py @@ -1,7 +1,6 @@ #!/usr/bin/env python - def hash_insert(T, k, h): i = 0 while i < len(T): diff --git a/queue.py b/queue.py index 72b1ff0..aaa18fc 100644 --- a/queue.py +++ b/queue.py @@ -8,7 +8,7 @@ def __init__(self): Exception.__init__(self) -class Queue(object): +class Queue: def __init__(self, size): self.data = [0] * size self.length = size diff --git a/tests/test_binary_add.py b/tests/test_binary_add.py new file mode 100644 index 0000000..2f9f1a6 --- /dev/null +++ b/tests/test_binary_add.py @@ -0,0 +1,9 @@ +from unittest import TestCase +from binary_add import binary_add + + +class Test(TestCase): + def test_binary_add(self): + array1 = [1, 0, 1, 0] + array2 = [0, 1, 1, 0] + self.assertEqual(binary_add(array1, array2), [1, 0, 0, 0, 0]) From cdbfdb9c564f68aacae9a876288204510ae95689 Mon Sep 17 00:00:00 2001 From: wq Date: Mon, 26 Jul 2021 18:59:02 +0800 Subject: [PATCH 45/49] conform to PEP8 --- activity_selection.py | 2 +- b_tree_example.py | 22 +++++++++++----------- binary_add.py | 3 +-- b_tree.py => btree.py | 10 +++++----- 4 files changed, 18 insertions(+), 19 deletions(-) rename b_tree.py => btree.py (97%) diff --git a/activity_selection.py b/activity_selection.py index 199ec58..3369a04 100644 --- a/activity_selection.py +++ b/activity_selection.py @@ -27,7 +27,7 @@ def activity_selection_with_weight(s, f, v, n): """ This is a modification to the activity-selection problem in which each activity has, in addition to a start and finish time, a value v. Now the object is to maximize - the total value of the activies scheduled. It can be solved by dynamic programming method + the total value of the activities scheduled. It can be solved by dynamic programming method """ c = zeros((n + 2, n + 2)) activities = zeros((n + 2, n + 2)) diff --git a/b_tree_example.py b/b_tree_example.py index a6d0cfd..96c3644 100755 --- a/b_tree_example.py +++ b/b_tree_example.py @@ -1,32 +1,32 @@ #!/usr/bin/env python -import b_tree as bt +import btree as bt -a = bt.b_tree_node(3, True, 2) +a = bt.BTreeNode(3, True, 2) a.key[0] = 'A' a.key[1] = 'B' -b = bt.b_tree_node(3, True, 3) +b = bt.BTreeNode(3, True, 3) b.key[0] = 'D' b.key[1] = 'E' b.key[2] = 'F' -c = bt.b_tree_node(3, True, 3) +c = bt.BTreeNode(3, True, 3) c.key[0] = 'J' c.key[1] = 'K' c.key[2] = 'L' -d = bt.b_tree_node(3, True, 2) +d = bt.BTreeNode(3, True, 2) d.key[0] = 'N' d.key[1] = 'O' -x = bt.b_tree_node(3, True, 3) +x = bt.BTreeNode(3, True, 3) x.key[0] = 'Q' x.key[1] = 'R' x.key[2] = 'S' -y = bt.b_tree_node(3, True, 2) +y = bt.BTreeNode(3, True, 2) y.key[0] = 'U' y.key[1] = 'V' -z = bt.b_tree_node(3, True, 2) +z = bt.BTreeNode(3, True, 2) z.key[0] = 'Y' z.key[1] = 'Z' -e = bt.b_tree_node(3, False, 3) +e = bt.BTreeNode(3, False, 3) e.key[0] = 'C' e.key[1] = 'G' e.key[2] = 'M' @@ -34,13 +34,13 @@ e.c[1] = b e.c[2] = c e.c[3] = d -v = bt.b_tree_node(3, False, 2) +v = bt.BTreeNode(3, False, 2) v.key[0] = 'T' v.key[1] = 'X' v.c[0] = x v.c[1] = y v.c[2] = z -t = bt.b_tree(3) +t = bt.BTree(3) t.root.key[0] = 'P' t.root.c[0] = e t.root.c[1] = v diff --git a/binary_add.py b/binary_add.py index baf23e6..92aabdd 100644 --- a/binary_add.py +++ b/binary_add.py @@ -18,7 +18,6 @@ def binary_add(array1, array2): for i in range(n - 1, -1, -1): result = array1[i] + array2[i] + promote promote = result // 2 - result = result % 2 - array3[i + 1] = result + array3[i + 1] = result % 2 array3[0] = promote return array3 diff --git a/b_tree.py b/btree.py similarity index 97% rename from b_tree.py rename to btree.py index d1d6676..7bd91a1 100644 --- a/b_tree.py +++ b/btree.py @@ -1,7 +1,7 @@ #!/usr/bin/env python -class b_tree_node: +class BTreeNode: def __init__(self, t, leaf, n): self.leaf = leaf self.n = n @@ -12,7 +12,7 @@ def __init__(self, t, leaf, n): def split_child(self, i): y = self.c[i - 1] t = y.t - z = b_tree_node(t, y.leaf, t - 1) + z = BTreeNode(t, y.leaf, t - 1) for j in range(1, t): z.key[j - 1] = y.key[j + t - 1] if not y.leaf: @@ -164,16 +164,16 @@ def merge(self, tree, i): tree.root = y -class b_tree: +class BTree: def __init__(self, t): self.t = t - self.root = b_tree_node(t, True, 0) + self.root = BTreeNode(t, True, 0) def insert(self, k): r = self.root t = self.t if r.n == 2 * t - 1: - s = b_tree_node(t, False, 0) + s = BTreeNode(t, False, 0) self.root = s s.c[0] = r s.split_child(1) From 728dcd42d89a57be521d29aeb6b1cd00b0c9972b Mon Sep 17 00:00:00 2001 From: wq Date: Tue, 17 Aug 2021 12:15:06 +0800 Subject: [PATCH 46/49] conform to PEP8 --- FengSort.c | 6 +++--- polygon_area_test.py => tests/polygon_area_test.py | 0 2 files changed, 3 insertions(+), 3 deletions(-) rename polygon_area_test.py => tests/polygon_area_test.py (100%) diff --git a/FengSort.c b/FengSort.c index 124cb26..c9befcc 100644 --- a/FengSort.c +++ b/FengSort.c @@ -31,7 +31,7 @@ int main() FengSort(a, 0, 8); printf("%d, %d, %d, %d, %d, %d, %d, %d, %d\n", a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); - FengSort(b, 0, 1); - printf("%d,%d\n", b[0], b[1]); - exit(0); + FengSort(b, 0, 1); + printf("%d,%d\n", b[0], b[1]); + exit(0); } diff --git a/polygon_area_test.py b/tests/polygon_area_test.py similarity index 100% rename from polygon_area_test.py rename to tests/polygon_area_test.py From c9e9699e5d4b2a3514a9f87f590b74d2708f235c Mon Sep 17 00:00:00 2001 From: wq Date: Fri, 20 Aug 2021 20:15:20 +0800 Subject: [PATCH 47/49] queue unittest --- .idea/modules.xml | 8 -------- queue.py | 12 +++++++----- tests/test_euclid.py | 13 +++++++++++++ tests/test_queue.py | 30 ++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 13 deletions(-) delete mode 100644 .idea/modules.xml create mode 100644 tests/test_euclid.py create mode 100644 tests/test_queue.py diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 2ba6d76..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/queue.py b/queue.py index aaa18fc..41aa7b4 100644 --- a/queue.py +++ b/queue.py @@ -11,7 +11,7 @@ def __init__(self): class Queue: def __init__(self, size): self.data = [0] * size - self.length = size + self.size = size self.head = 0 self.tail = 0 @@ -19,7 +19,7 @@ def enqueue(self, x): if self.full(): raise FullException() self.data[self.tail] = x - if self.tail == self.length - 1: + if self.tail == self.size - 1: self.tail = 0 else: self.tail = self.tail + 1 @@ -28,7 +28,7 @@ def dequeue(self): if self.empty(): raise EmptyException() x = self.data[self.head] - if self.head == self.length - 1: + if self.head == self.size - 1: self.head = 0 else: self.head = self.head + 1 @@ -38,5 +38,7 @@ def empty(self): return self.tail == self.head def full(self): - # print( "tail: {}, head: {}, size: {}".format(self.tail, self.head, self.length)) - return (self.tail + 1) % self.length == self.head + return (self.tail + 1) % self.size == self.head + + def capacity(self): + return self.size - 1 diff --git a/tests/test_euclid.py b/tests/test_euclid.py new file mode 100644 index 0000000..0c7909c --- /dev/null +++ b/tests/test_euclid.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python +# encoding: utf-8 +from unittest import TestCase + +from euclid import euclid + + +class TestEuclid(TestCase): + def test_gcd(self): + self.assertEqual(euclid(10, 3), 1) + self.assertEqual(euclid(10, 4), 2) + self.assertEqual(euclid(10, 1), 1) + self.assertEqual(euclid(10, 5), 5) diff --git a/tests/test_queue.py b/tests/test_queue.py new file mode 100644 index 0000000..b2d8549 --- /dev/null +++ b/tests/test_queue.py @@ -0,0 +1,30 @@ +from unittest import TestCase +from queue import Queue, EmptyException, FullException + + +class TestQueue(TestCase): + def test_enqueue_and_dequeue(self): + queue = Queue(3) + queue.enqueue(1) + queue.enqueue(2) + with self.assertRaises(FullException): + queue.enqueue(3) + self.assertEqual(1, queue.dequeue()) + self.assertEqual(2, queue.dequeue()) + with self.assertRaises(EmptyException): + queue.dequeue() + + def test_empty(self): + queue = Queue(2) + self.assertTrue(queue.empty()) + + def test_full(self): + queue = Queue(2) + queue.enqueue(1) + self.assertTrue(queue.full()) + queue = Queue(1) + self.assertTrue(queue.full()) + + def test_capacity(self): + queue = Queue(5) + self.assertEqual(4, queue.capacity()) From 875b812a3c56ae7ed2171b151afed3afea7686e2 Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 25 Dec 2021 01:41:17 +0800 Subject: [PATCH 48/49] rename queue.py to Queue.py to avoid conflict with python standard queue module --- .idea/algorithm.iml | 9 ++----- queue.py => Queue.py | 0 deque.py | 16 ++++++------ dynamic_array.py | 21 ++++++++++++++++ priority_queue.py | 8 ++---- tests/test_deque.py | 50 +++++++++++++++++++++++++++++++++++++ tests/test_dynamic_array.py | 15 +++++++++++ tests/test_queue.py | 2 +- 8 files changed, 99 insertions(+), 22 deletions(-) rename queue.py => Queue.py (100%) create mode 100644 dynamic_array.py create mode 100644 tests/test_deque.py create mode 100644 tests/test_dynamic_array.py diff --git a/.idea/algorithm.iml b/.idea/algorithm.iml index ff453bd..8b8c395 100644 --- a/.idea/algorithm.iml +++ b/.idea/algorithm.iml @@ -2,16 +2,11 @@ - + - - + \ No newline at end of file diff --git a/queue.py b/Queue.py similarity index 100% rename from queue.py rename to Queue.py diff --git a/deque.py b/deque.py index 5a8d313..0391352 100644 --- a/deque.py +++ b/deque.py @@ -1,4 +1,4 @@ -from queue import Queue, FullException, EmptyException +from Queue import Queue, FullException, EmptyException class Deque(Queue): @@ -18,21 +18,21 @@ def dequeue_head(self): def enqueue_head(self, x): if self.full(): - raise FullException("This double-ended Queue is full") + raise FullException() else: if self.head == 0: - self.head = self.length - 1 + self.head = self.size - 1 else: self.head = self.head - 1 - self[self.head] = x + self.data[self.head] = x def dequeue_tail(self): - if self.emtpy(): - raise EmptyException("This double-ended Queue is empty") + if self.empty(): + raise EmptyException() else: if self.tail == 0: - self.tail = self.length - 1 + self.tail = self.size - 1 else: self.tail = self.tail - 1 - return self[self.tail] + return self.data[self.tail] diff --git a/dynamic_array.py b/dynamic_array.py new file mode 100644 index 0000000..2defc73 --- /dev/null +++ b/dynamic_array.py @@ -0,0 +1,21 @@ +class DynamicArray: + def __init__(self, capacity): + assert capacity > 0 + self._capacity = capacity + self._size = 0 + self._data = [None] * capacity + + def add(self, element): + if self._size == self._capacity: + temp = self._data + self._data = [None] * (self._capacity * 2) + self._data[:self._capacity] = temp[:] + self._capacity *= 2 + self._data[self._size] = element + self._size += 1 + + def size(self): + return self._size + + def get(self, index): + return self._data[index] diff --git a/priority_queue.py b/priority_queue.py index 2b62e26..2d39594 100644 --- a/priority_queue.py +++ b/priority_queue.py @@ -20,9 +20,7 @@ def heap_increase_key(self, i, key): sys.exit("new key is smaller than current key") self[i] = key while i > 0 and self[self.parent(i)] < self[i]: - tmp = self[self.parent(i)] - self[self.parent(i)] = self[i] - self[i] = tmp + self[i], self[self.parent(i)] = self[self.parent(i)], self[i] i = self.parent(i) def max_heap_insert(self, key): @@ -57,9 +55,7 @@ def heap_decrease_key(self, i, key): sys.exit("new key is larger than current key") self[i] = key while i > 0 and self[self.parent(i)] > self[i]: - tmp = self[self.parent(i)] - self[self.parent(i)] = self[i] - self[i] = tmp + self[i], self[self.parent(i)] = self[self.parent(i)], self[i] i = self.parent(i) def min_heap_insert(self, key): diff --git a/tests/test_deque.py b/tests/test_deque.py new file mode 100644 index 0000000..e74d940 --- /dev/null +++ b/tests/test_deque.py @@ -0,0 +1,50 @@ +from unittest import TestCase + +from Queue import FullException, EmptyException +from deque import Deque + + +class TestDeque(TestCase): + def test_enqueue_tail_and_dequeue_head(self): + deque = Deque(3) + deque.enqueue_tail(1) + deque.enqueue_tail(2) + with self.assertRaises(FullException): + deque.enqueue_tail(3) + self.assertEqual(1, deque.dequeue_head()) + self.assertEqual(2, deque.dequeue_head()) + with self.assertRaises(EmptyException): + deque.dequeue_head() + + def test_enqueue_head_and_dequeue_tail(self): + deque = Deque(3) + deque.enqueue_head(1) + deque.enqueue_head(2) + with self.assertRaises(FullException): + deque.enqueue_head(3) + self.assertEqual(1, deque.dequeue_tail()) + self.assertEqual(2, deque.dequeue_tail()) + with self.assertRaises(EmptyException): + deque.dequeue_tail() + + def test_enqueue_tail_and_dequeue_tail(self): + deque = Deque(3) + deque.enqueue_tail(1) + deque.enqueue_tail(2) + self.assertEqual(2, deque.dequeue_tail()) + self.assertEqual(1, deque.dequeue_tail()) + with self.assertRaises(EmptyException): + deque.dequeue_tail() + with self.assertRaises(EmptyException): + deque.dequeue_head() + + def test_enqueue_head_and_dequeue_head(self): + deque = Deque(3) + deque.enqueue_head(1) + deque.enqueue_head(2) + self.assertEqual(2, deque.dequeue_head()) + self.assertEqual(1, deque.dequeue_head()) + with self.assertRaises(EmptyException): + deque.dequeue_tail() + with self.assertRaises(EmptyException): + deque.dequeue_head() diff --git a/tests/test_dynamic_array.py b/tests/test_dynamic_array.py new file mode 100644 index 0000000..194f7fa --- /dev/null +++ b/tests/test_dynamic_array.py @@ -0,0 +1,15 @@ +from unittest import TestCase +from dynamic_array import DynamicArray + + +class TestDynamicArray(TestCase): + def test_add_and_get_and_size(self): + dynamic_array = DynamicArray(2) + self.assertEqual(0, dynamic_array.size()) + dynamic_array.add(1) + dynamic_array.add(2) + dynamic_array.add(3) + self.assertEqual(3, dynamic_array.size()) + self.assertEqual(1, dynamic_array.get(0)) + self.assertEqual(2, dynamic_array.get(1)) + self.assertEqual(3, dynamic_array.get(2)) diff --git a/tests/test_queue.py b/tests/test_queue.py index b2d8549..c8eb359 100644 --- a/tests/test_queue.py +++ b/tests/test_queue.py @@ -1,5 +1,5 @@ from unittest import TestCase -from queue import Queue, EmptyException, FullException +from Queue import Queue, EmptyException, FullException class TestQueue(TestCase): From 253f63e8c1e9cea2b90980d76973b37b347d70bb Mon Sep 17 00:00:00 2001 From: wq Date: Sat, 26 Mar 2022 11:20:46 +0800 Subject: [PATCH 49/49] minor correction --- heap.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/heap.py b/heap.py index 6342f23..c69b0fc 100644 --- a/heap.py +++ b/heap.py @@ -20,11 +20,11 @@ def parent(i): def max_heapify(self, i): left = self.left(i) right = self.right(i) - if (left <= (self.heap_size - 1)) and (self[left] > self[i]): + if left < self.heap_size and self[left] > self[i]: largest = left else: largest = i - if (right <= (self.heap_size - 1)) and (self[right] > self[largest]): + if right < self.heap_size and self[right] > self[largest]: largest = right if largest != i: self[i], self[largest] = self[largest], self[i]