diff --git a/README.md b/README.md index 4a90872..b8f1fa9 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,30 @@ graph.add_edge(3, 5, 4) # edge from vertex 3 to vertex 5 with weight 4 puts graph ``` +## Algorithms usage + +```ruby + +# initializes Algorithms object +alg = Algorithms.new + +# matrix example +matrix = AdjMatrixGraph.new +matrixSrc = [[0, 0, 2], + [2, 0, 0], + [0, 2, 0]] +matrix.load_from_array(matrixSrc) + +# lambda which will be used for each vertex +my_print = lambda { |n| print(n) } + +# matrix_DFS call +alg.matrix_DFS(matrix, my_print) +# 0 2 1 + +``` + + ## Data formats ``` diff --git a/lib/visual_graphs/algorithms.rb b/lib/visual_graphs/algorithms.rb new file mode 100644 index 0000000..de93fe8 --- /dev/null +++ b/lib/visual_graphs/algorithms.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +module VisualGraphs + # class with different algorithms for graphs + class Algorithms + + # Depth-First Search, (for adjacency matrix based graph) + def matrix_DFS(graph_matrix, vertexAction) + + msg = 'argument must be of AdjMatrixGraph type' + raise AdjacencyMatrixError, msg unless graph_matrix.is_a?(AdjMatrixGraph) + + matrix = graph_matrix.adjacency_matrix + initial_index = 0 + + visited = [] + node_stack = [initial_index] + loop do + curr_node = node_stack.shift + + visited.append(curr_node) + return false if curr_node == nil + return true if curr_node == matrix.length + + vertexAction.call(curr_node) + + children = (0..matrix.length-1).to_a.select do |i| + # do not process loops + next if curr_node == i + next if visited.find{|v| v == i} != nil + + matrix[curr_node][i] != 0 + end + + node_stack = node_stack + children + end + end + end +end + diff --git a/test/algorithms_test.rb b/test/algorithms_test.rb new file mode 100644 index 0000000..043b39e --- /dev/null +++ b/test/algorithms_test.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +require "./test/test_helper" +require './lib/visual_graphs/algorithms' +require './lib/visual_graphs/adjacency_matrix_graph' + +class AlgorithmTest < Minitest::Test + include VisualGraphs + + def test_exists_matrix_DFS_method + assert Algorithms.methods.size > 0 + end + + def test_matrix_DFS_does_not_accept_invalid_data + alg = Algorithms.new + + exception = assert_raises AdjacencyMatrixError do + my_print = lambda { |n| print(n ) } + alg.matrix_DFS(5, my_print) + end + assert_equal 'argument must be of AdjMatrixGraph type', exception.message + + exception = assert_raises AdjacencyMatrixError do + my_print = lambda { |n| print(n ) } + alg.matrix_DFS([1, 2, 3], my_print) + end + assert_equal 'argument must be of AdjMatrixGraph type', exception.message + + exception = assert_raises AdjacencyMatrixError do + my_print = lambda { |n| print(n ) } + alg.matrix_DFS("it's joke", my_print) + end + assert_equal 'argument must be of AdjMatrixGraph type', exception.message + end + + def test_matrix_DFS_correct_work_size2 + alg = Algorithms.new + + matrix = AdjMatrixGraph.new + matrixSrc = [[2, 3], [0, 1]] + matrix.load_from_array(matrixSrc) + + traversed_vertices = [] + traverse = lambda { |n| traversed_vertices.append(n) } + alg.matrix_DFS(matrix, traverse) + + assert_equal traversed_vertices, [0, 1] + end + + + def test_matrix_DFS_correct_work_size5 + alg = Algorithms.new + + matrix = AdjMatrixGraph.new + matrixSrc = [[0, 1, 1, 0, 0], + [0, 0, 0, 0, 0], + [0, 0, 0, 1, 1], + [0, 0, 0, 0, 0], + [0, 0, 0, 0, 0]] + matrix.load_from_array(matrixSrc) + + traversed_vertices = [] + traverse = lambda { |n| traversed_vertices.append(n) } + alg.matrix_DFS(matrix, traverse) + + assert_equal traversed_vertices, [0, 1, 2, 3, 4] + end + + def test_matrix_DFS_correct_work_size3 + alg = Algorithms.new + + matrix = AdjMatrixGraph.new + matrixSrc = [[0, 0, 2], + [2, 0, 0], + [0, 2, 0]] + matrix.load_from_array(matrixSrc) + + traversed_vertices = [] + traverse = lambda { |n| traversed_vertices.append(n) } + + alg.matrix_DFS(matrix, traverse) + + assert_equal traversed_vertices, [0, 2, 1] + end +end \ No newline at end of file diff --git a/test/resources/test_min_heap.txt b/test/resources/test_min_heap.txt new file mode 100644 index 0000000..715f3ce --- /dev/null +++ b/test/resources/test_min_heap.txt @@ -0,0 +1,7 @@ +printing min heap: +nil +Vertex +Vertex +Vertex +Vertex +Vertex