dither 0.1.3-java → 0.1.4-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +46 -0
- data/lib/dither.rb +1 -0
- data/lib/dither/graph.rb +102 -0
- data/lib/dither/version.rb +1 -1
- data/spec/dither/graph_spec.rb +124 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3af620c3811276969244eb515443a6f89bce71c8
|
4
|
+
data.tar.gz: f40ebd686325b3d402f3e752cb9db9fcaca4074f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 36ef90323fdb4264d5f183fd203adc0a7ed7d12e7cf5bc561b38cef6878ec4e6af2b75f342011f2925df0b1abc34d7ac602e53da4a1d79550a8426efe73db1da
|
7
|
+
data.tar.gz: 26e28e273e9d7cf80773a990c94b7866059fead5a22b4b949a59a4839544b1be5860973a792b2ac40422b7c31d6db53e06223a4dd500efe840bd6a17b2c9afd9
|
data/README.md
CHANGED
@@ -98,6 +98,52 @@ raw_graph = {
|
|
98
98
|
Dither.all_edges(raw_graph)
|
99
99
|
```
|
100
100
|
|
101
|
+
Random walk on a graph. Each edge has equal weight.
|
102
|
+
```ruby
|
103
|
+
raw_graph = {
|
104
|
+
:origin => 0,
|
105
|
+
:edges => [
|
106
|
+
{
|
107
|
+
:name => :a,
|
108
|
+
:src_vertex => 0,
|
109
|
+
:dst_vertex => 1,
|
110
|
+
},
|
111
|
+
{
|
112
|
+
:name => :b,
|
113
|
+
:src_vertex => 0,
|
114
|
+
:dst_vertex => 2,
|
115
|
+
},
|
116
|
+
{
|
117
|
+
:name => :c,
|
118
|
+
:src_vertex => 1,
|
119
|
+
:dst_vertex => 2,
|
120
|
+
},
|
121
|
+
{
|
122
|
+
:name => :d,
|
123
|
+
:src_vertex => 1,
|
124
|
+
:dst_vertex => 3,
|
125
|
+
},
|
126
|
+
{
|
127
|
+
:name => :e,
|
128
|
+
:src_vertex => 2,
|
129
|
+
:dst_vertex => 3,
|
130
|
+
},
|
131
|
+
{
|
132
|
+
:name => :f,
|
133
|
+
:src_vertex => 3,
|
134
|
+
:dst_vertex => 0,
|
135
|
+
}
|
136
|
+
]
|
137
|
+
}
|
138
|
+
|
139
|
+
graph = Dither::Graph.create(raw_graph)
|
140
|
+
|
141
|
+
# infinite sequence of random walks
|
142
|
+
graph.each do |path|
|
143
|
+
puts path.map(&:name).to_s
|
144
|
+
end
|
145
|
+
```
|
146
|
+
|
101
147
|
|
102
148
|
# Note on Patches/Pull Requests
|
103
149
|
|
data/lib/dither.rb
CHANGED
data/lib/dither/graph.rb
ADDED
@@ -0,0 +1,102 @@
|
|
1
|
+
|
2
|
+
module Dither
|
3
|
+
class Graph
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
attr_accessor :rand, :max_depth, :origin_name
|
7
|
+
attr_reader :vertices, :edges, :stop_conditions, :skip_conditions
|
8
|
+
Edge = Struct.new(:name, :src_vertex, :dst_vertex, :count)
|
9
|
+
Vertex = Struct.new(:name, :edges, :count)
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@vertices = {}
|
13
|
+
@edges = []
|
14
|
+
@stop_conditions = []
|
15
|
+
@skip_conditions = []
|
16
|
+
@rand = Random.new
|
17
|
+
@max_depth = 10
|
18
|
+
@origin_name = :origin
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.create(hash)
|
22
|
+
edges = hash[:edges]
|
23
|
+
graph = Graph.new
|
24
|
+
graph.origin_name = hash[:origin] if hash.has_key?(:origin)
|
25
|
+
|
26
|
+
edges.each do |edge|
|
27
|
+
graph.add_edge(edge[:name], edge[:src_vertex], edge[:dst_vertex])
|
28
|
+
end
|
29
|
+
graph
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_edge(name, src_vertex_name, dst_vertex_name)
|
33
|
+
# check & create vertexes if they do not exist
|
34
|
+
vertices[src_vertex_name] ||= Vertex.new(src_vertex_name, [], 0)
|
35
|
+
vertices[dst_vertex_name] ||= Vertex.new(dst_vertex_name, [], 0)
|
36
|
+
|
37
|
+
# add edge to src_vertex
|
38
|
+
src_vertex = vertices[src_vertex_name]
|
39
|
+
dst_vertex = vertices[dst_vertex_name]
|
40
|
+
edge = Edge.new(name, src_vertex, dst_vertex, 0)
|
41
|
+
src_vertex.edges << edge
|
42
|
+
edges << edge
|
43
|
+
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_skip_condition(cond)
|
48
|
+
raise Dither::Error, "#{cond} does not respond to skip?" unless cond.respond_to? :skip?
|
49
|
+
skip_conditions << cond
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_stop_condition(cond)
|
53
|
+
raise Dither::Error, "#{cond} does not respond to stop?" unless cond.respond_to? :stop?
|
54
|
+
stop_conditions << cond
|
55
|
+
end
|
56
|
+
|
57
|
+
def origin
|
58
|
+
vertices[origin_name]
|
59
|
+
end
|
60
|
+
|
61
|
+
def random_walk
|
62
|
+
current_edge = origin.edges.sample(:random => rand)
|
63
|
+
current_max_depth = max_depth - 1
|
64
|
+
loop do
|
65
|
+
current_edge.src_vertex.count += 1
|
66
|
+
current_edge.count += 1
|
67
|
+
yield current_edge
|
68
|
+
current_edge = current_edge.dst_vertex.edges.sample(:random => rand)
|
69
|
+
current_max_depth -= 1
|
70
|
+
break if current_max_depth < 0 || current_edge.src_vertex.name == origin_name
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def each
|
75
|
+
loop do
|
76
|
+
break if stop?
|
77
|
+
path = []
|
78
|
+
random_walk { |a| path << a }
|
79
|
+
next if skip?
|
80
|
+
yield path
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def stop?
|
85
|
+
stop_conditions.any? { |cond| cond.stop?(self) }
|
86
|
+
end
|
87
|
+
|
88
|
+
def skip?
|
89
|
+
skip_conditions.any? { |cond| cond.skip?(self) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def vertices_covered
|
93
|
+
b = vertices.count { |a| a.count > 0 }
|
94
|
+
b/vertices.length.to_f
|
95
|
+
end
|
96
|
+
|
97
|
+
def edges_covered
|
98
|
+
b = edges.count { |a| a.count > 0 }
|
99
|
+
b/edges.length.to_f
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
data/lib/dither/version.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
require File.expand_path('../../spec_helper.rb', __FILE__)
|
3
|
+
|
4
|
+
describe Dither::Graph do
|
5
|
+
let(:raw_graph) do
|
6
|
+
{
|
7
|
+
:edges => [
|
8
|
+
{
|
9
|
+
:name => :a,
|
10
|
+
:src_vertex => :origin,
|
11
|
+
:dst_vertex => 1,
|
12
|
+
},
|
13
|
+
{
|
14
|
+
:name => :b,
|
15
|
+
:src_vertex => :origin,
|
16
|
+
:dst_vertex => 2,
|
17
|
+
},
|
18
|
+
{
|
19
|
+
:name => :c,
|
20
|
+
:src_vertex => 1,
|
21
|
+
:dst_vertex => 2,
|
22
|
+
},
|
23
|
+
{
|
24
|
+
:name => :d,
|
25
|
+
:src_vertex => 1,
|
26
|
+
:dst_vertex => 3,
|
27
|
+
},
|
28
|
+
{
|
29
|
+
:name => :e,
|
30
|
+
:src_vertex => 2,
|
31
|
+
:dst_vertex => 3,
|
32
|
+
},
|
33
|
+
{
|
34
|
+
:name => :f,
|
35
|
+
:src_vertex => 3,
|
36
|
+
:dst_vertex => :origin,
|
37
|
+
}
|
38
|
+
]
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
let(:raw_graph_infinite_cycle) do
|
44
|
+
{
|
45
|
+
:origin => 0,
|
46
|
+
:edges => [
|
47
|
+
{
|
48
|
+
:name => :a,
|
49
|
+
:src_vertex => 0,
|
50
|
+
:dst_vertex => 1,
|
51
|
+
},
|
52
|
+
{
|
53
|
+
:name => :b,
|
54
|
+
:src_vertex => 1,
|
55
|
+
:dst_vertex => 2,
|
56
|
+
},
|
57
|
+
{
|
58
|
+
:name => :c,
|
59
|
+
:src_vertex => 2,
|
60
|
+
:dst_vertex => 1,
|
61
|
+
},
|
62
|
+
]
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'can run random walk' do
|
67
|
+
graph = Dither::Graph.create(raw_graph)
|
68
|
+
graph.rand = Random.new 0
|
69
|
+
graph.each do |path|
|
70
|
+
first = path.map(&:name)
|
71
|
+
expect(first).to eql([:a, :d, :f])
|
72
|
+
break
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'can skip at skip condition' do
|
77
|
+
graph = Dither::Graph.create(raw_graph_infinite_cycle)
|
78
|
+
stop_cond = 'stop_cond'
|
79
|
+
def stop_cond.stop?(graph)
|
80
|
+
@count ||= 0
|
81
|
+
@count += 1
|
82
|
+
@count > 2
|
83
|
+
end
|
84
|
+
skip_cond = double("skip_cond", :skip? => true)
|
85
|
+
graph.add_skip_condition(skip_cond)
|
86
|
+
graph.add_stop_condition(stop_cond)
|
87
|
+
count = 0
|
88
|
+
graph.each do |a|
|
89
|
+
count += 1
|
90
|
+
end
|
91
|
+
|
92
|
+
expect(count).to eql(0)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'can stop at stop condition' do
|
96
|
+
graph = Dither::Graph.create(raw_graph_infinite_cycle)
|
97
|
+
cond = double("stop_cond", :stop? => true)
|
98
|
+
graph.add_stop_condition(cond)
|
99
|
+
count = 0
|
100
|
+
graph.each { |a| count += 1 }
|
101
|
+
|
102
|
+
expect(count).to eql(0)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'infinite cycle terminates at max_depth' do
|
106
|
+
graph = Dither::Graph.create(raw_graph_infinite_cycle)
|
107
|
+
graph.random_walk { |a| }
|
108
|
+
|
109
|
+
edge_count = graph.edges.map(&:count).reduce(&:+)
|
110
|
+
expect(edge_count).to eql(graph.max_depth)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'raise error when invalid stop condition' do
|
114
|
+
graph = Dither::Graph.new
|
115
|
+
|
116
|
+
expect { graph.add_stop_condition("hi") }.to raise_error
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'raise error when invalid skip condition' do
|
120
|
+
graph = Dither::Graph.new
|
121
|
+
|
122
|
+
expect { graph.add_skip_condition("hi") }.to raise_error
|
123
|
+
end
|
124
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dither
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Jason Gowan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,6 +72,7 @@ files:
|
|
72
72
|
- lib/dither/aetg.rb
|
73
73
|
- lib/dither/aetg_pairwise.rb
|
74
74
|
- lib/dither/chinese_postman_problem.rb
|
75
|
+
- lib/dither/graph.rb
|
75
76
|
- lib/dither/ipog.rb
|
76
77
|
- lib/dither/ipog_helper.rb
|
77
78
|
- lib/dither/java_ext/dither.rb
|
@@ -82,6 +83,7 @@ files:
|
|
82
83
|
- lib/dither/version.rb
|
83
84
|
- spec/dither/chinese_postman_problem_spec.rb
|
84
85
|
- spec/dither/dither_spec.rb
|
86
|
+
- spec/dither/graph_spec.rb
|
85
87
|
- spec/spec_helper.rb
|
86
88
|
- lib/dither-0.1.2.jar
|
87
89
|
- lib/choco-solver-3.3.1-with-dependencies.jar
|
@@ -112,4 +114,5 @@ summary: Collection of test generation strategies
|
|
112
114
|
test_files:
|
113
115
|
- spec/dither/chinese_postman_problem_spec.rb
|
114
116
|
- spec/dither/dither_spec.rb
|
117
|
+
- spec/dither/graph_spec.rb
|
115
118
|
- spec/spec_helper.rb
|