Skip to content

graph class and weighted class graph #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Nov 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 64 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,78 @@
## Usage

```ruby
graph = Graph.new(path_to_file)
#simple not weighted graph
# json import
graph = Graph.load_from_json(path)

#initialization from hash
hash_graph = {1 => [2, 3], 2 => [1, 4]}
graph = Graph.adjacency_list_init(hash_graph)

graph.vertices #return list of vertices
graph.edges #return list of edges
```
```ruby
#adding new vertex (vertex could be numbers,chars .etc)
# if vertex is already exists it will not be added
graph.insert_vertex(new_vertex)
```
```ruby
#adding new edge for simple Graph
# vertices will also be included in vertices list of graph if they are not there
# also add second_vertex to adjacency_list of first_vertex
graph.insert_edge([first_vertex, second_vertex])
```
```ruby
graph.output_to_standard_stream # prints graph(adjacency_list)
```
```ruby
#will create(overwrite) json_file and save adjacency_list in it
#json_file name must ends with .json
graph.dump_to_json(path_to_file)
```

```ruby
WeightedGraph - weighted_adjacency_list

# json import
# will raise error if
graph = WeightedGraph.load_from_json(path)

#initialization from hash
hash_graph = {1 => [[2, 3]], 2 => [[1, 4]]}
graph = WeightedGraph.adjacency_list_init(hash_graph)

graph.vertices #return list of vertices
graph.edges #return list of edges

#v1,v2 vertices,w - weight
graph.insert_edge([v1,[v2,w]])
```

## Data formats

```json
```
for simple not weighted Graph class
{
"1":[2],
"2":[3],
"3":[1]
"3":[1,4]
"4": []
}

hash = {1 => [2,3]}

for weightedGraph
{
"1":[[2,1]],
"2":[[3,4]],
"3":[[1,5],[4,6]]
"4": []
}

hash = {1 => [[2,3], [3,4]]}

```


Expand Down
7 changes: 7 additions & 0 deletions lib/visual_graphs.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@
require_relative "visual_graphs/graph"
module VisualGraphs
class Error < StandardError; end

class InvalidJSONFileNameError < RuntimeError; end

class IncorrectArgumentsForGraphInit < StandardError;end
# error for wrong parameters in weighted graph initialization
class WrongParamsForWeightedGraphInit< StandardError;end

end
70 changes: 63 additions & 7 deletions lib/visual_graphs/graph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,80 @@

module VisualGraphs
class Graph
def initialize(path)
file = File.open(path)
attr_accessor :adjacency_list
attr_accessor :edges

def initialize
@adjacency_list = {}
@edges = []
end

def self.load_from_json(path)
graph = Graph.new
file = File.open(path)
temp = JSON.load(file)
temp.each do |k, v|
temp_k = k.to_i
@adjacency_list[temp_k] = v
v.each { |adj_vertex| @edges << [temp_k, adj_vertex] }
graph.adjacency_list[temp_k] = v
v.each { |adj_vertex| graph.edges << [temp_k, adj_vertex] }
end
file.close
graph
end


def self.adjacency_list_init(list)
graph = Graph.new
list.each do |pair|
graph.adjacency_list.store(pair[0], pair[1])
pair[1].each {|vertex| graph.edges << [pair[0], vertex] }
end
graph
end

def vertices()
def vertices
@adjacency_list.keys
end

def edges()
@edges

def insert_vertex(vertex)
unless @adjacency_list.keys.include? vertex
@adjacency_list[vertex] = []
return true
end
false
end

# edge is array [1,2] , where 1 and 2 are vertex
# also will insert vertexes unless they are not in adjecency_list
def insert_edge(edge)
unless @edges.include? edge
insert_vertex(edge[0])
insert_vertex(edge[1])
@adjacency_list[edge[0]] << edge[1]
@edges << edge
return true
end
false
end

def output_to_standard_stream
@adjacency_list.each do |vertex, adjacency_list|
puts "#{vertex} : #{adjacency_list}"
end
end

def correct_path?(path)
path.is_a? String and path.end_with? '.json'
end

# will create json file and dump graph to it
# throws No such file or directory error
def dump_to_json(path)
raise InvalidJSONFileNameError unless correct_path? path

File.open(path, 'w') { |f| f.write(@adjacency_list.to_json) }
end

end
end
54 changes: 54 additions & 0 deletions lib/visual_graphs/weighted_graph.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require_relative 'graph'

module VisualGraphs
class WeightedGraph < VisualGraphs::Graph
def initialize()
super()
end

def self.load_from_json(path)
graph = Graph.load_from_json(path)
weighted_graph = WeightedGraph.new
weighted_graph.edges = graph.edges
weighted_graph.adjacency_list = graph.adjacency_list
graph_is_weighted?(graph.edges)
weighted_graph
end

def self.adjacency_list_init(list)
graph = Graph.adjacency_list_init(list)
weighted_graph = WeightedGraph.new
weighted_graph.edges = graph.edges
weighted_graph.adjacency_list = graph.adjacency_list
graph_is_weighted?(graph.edges)
weighted_graph
end

#check that all edges are: [v1, [v2,w]]
# v1,v2 - vertices , w - weight
def self.graph_is_weighted?(edges)
edges.each do |edge|
unless correct_edge?(edge)
raise WrongParamsForWeightedGraphInit
end
end
end

def self.correct_edge?(edge)
edge[1].is_a? Array and edge[1].length == 2
end

def insert_edge(edge)
if (WeightedGraph.correct_edge? edge) && !(@edges.include? edge)
insert_vertex(edge[0])
insert_vertex(edge[1][0])
@adjacency_list[edge[0]] << edge[1]
@edges << edge
return true
end
false
end

end

end
99 changes: 99 additions & 0 deletions test/adjacency_list_graph_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
require './test/test_helper'
require 'json'

class AdjacencyListGraphTest < Minitest::Test
include VisualGraphs

def setup
@filepath = 'test/resources/test_data.json'
@output_file_path = 'test/resources/output_test_data.json'
File.delete @output_file_path if File.exist? @output_file_path
end

def test_json_file_created_when_graph_was_dumped_to_json
graph = Graph.load_from_json(@filepath)
graph.dump_to_json(@output_file_path)
assert_equal true, File.exists?(@output_file_path), 'json file was not created'
end

def test_dumped_graph_in_json_file_is_correct
graph = Graph.load_from_json(@filepath)
graph.dump_to_json(@output_file_path)

init_file = File.open(@filepath)
dumped_file = File.open(@output_file_path)
initial_graph_json = JSON.load(init_file)
dumped_graph_json = JSON.load(dumped_file)
init_file.close
dumped_file.close
assert_equal initial_graph_json, dumped_graph_json, 'dump_to_json is not working'

end

def test_incorrect_json_file_name_raise_exception
assert_raises InvalidJSONFileNameError do
graph = Graph.load_from_json(@filepath)
graph.dump_to_json('test/incorrect')
end
end

def test_correct_vertices_adjacency_list_initialization
hash_graph = Graph.adjacency_list_init({1 => [2], 2 => [3], 3 => [1]})
assert_equal [1, 2, 3], hash_graph.vertices, 'vertices arrays do not match'
end

def test_correct_edges_adjacency_list_initialization
hash_graph = Graph.adjacency_list_init({1 => [2], 2 => [3], 3 => [1]})
assert_equal [[1, 2], [2, 3], [3, 1]], hash_graph.edges, 'edges arrays do not match'
end

def test_adding_edge_will_add_edge_to_adjacency_list
graph = Graph.load_from_json(@filepath)
graph.insert_edge([1, 5])
assert_equal true, graph.instance_variable_get(:@adjacency_list)[1].include?(5), 'vertex was not added to adjacency_list'
end

def test_existing_edge_will_not_be_inserted
graph = Graph.load_from_json(@filepath)
graph.insert_edge([1, 2])
assert_equal 1, graph.edges.count([1, 2])
end


def test_non_existent_edge_will_be_inserted
graph = Graph.load_from_json(@filepath)
graph.insert_edge([1,4])
assert_equal true, graph.edges.include?([1, 4]), 'new edge was not added'
end

def test_existing_vertice_will_not_be_inserted
graph = Graph.load_from_json(@filepath)
graph.insert_vertex(1)
assert_equal 1, graph.vertices.count(1), 'existing vertex has been added twice'
end

def test_non_existing_vertice_will_be_inserted
graph = Graph.load_from_json(@filepath)
graph.insert_vertex(10)
assert_equal true,graph.vertices.include?(10), 'vertex was not added'
end

def test_non_existent_vertice_will_be_added_while_inserting_edge
graph = Graph.load_from_json(@filepath)
graph.insert_edge([1,4])
assert_equal true, graph.vertices.include?(4), 'new vertex was not added during edge inserting'
end

def test_loop_edge_will_be_added
graph = Graph.load_from_json(@filepath)
graph.insert_edge([1, 1])
assert_equal true, graph.edges.include?([1, 1]), 'looped edge was not added'
end

def test_loop_edge_will_not_add_same_vertex_twice
graph = Graph.load_from_json(@filepath)
graph.insert_edge([4, 4])
assert_equal 1, graph.vertices.count(4), 'more than 1 vertex was added during looped-edge inserting'
end

end
5 changes: 5 additions & 0 deletions test/coverage/.last_run.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"result": {
"line": 100.0
}
}
7 changes: 7 additions & 0 deletions test/coverage/.resultset.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Unit Tests": {
"coverage": {
},
"timestamp": 1636022168
}
}
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test/coverage/assets/0.12.3/application.css

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions test/coverage/assets/0.12.3/application.js

Large diffs are not rendered by default.

Binary file added test/coverage/assets/0.12.3/colorbox/border.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/colorbox/controls.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/colorbox/loading.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/favicon_green.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/favicon_red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/favicon_yellow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added test/coverage/assets/0.12.3/loading.gif
Binary file added test/coverage/assets/0.12.3/magnify.png
Loading