dither 0.0.10-java → 0.0.11-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f604e88d5d8eac1f835c1dda247b4fd0772002ea
4
- data.tar.gz: 4dbd069d8a778df29828151bbb176093885f0f3b
3
+ metadata.gz: 3e5528867e133a68bb9a429ae778153f59d7fa07
4
+ data.tar.gz: 06470e7386b123b3a6642fb48761318ad9bfc0be
5
5
  SHA512:
6
- metadata.gz: b648cc3b440e1f2cd88dd47d85cd84e31a6755fe5c6912b11aa23c1fa405155c55a25a74f80e37b37a91ec5fe40e62abb74adba574eb87d86abe4968521adfd2
7
- data.tar.gz: 20ef90a73de9b0f31bc43f3435c33f5202b1eef2aa8ecc7971eb42900dde8b4a1f243ff1dba5ede919cf5555a0f2e4d114bf5011d3793f15b845fa6df0273b08
6
+ metadata.gz: 70072c1bcfe0006bb632bf33542e700c8dd1036c2946b3d8bed6f4f752d1feffdbbf850a45eae283ab0651019c10b4ca03551f72741a6e9fe8dd8ae90b210741
7
+ data.tar.gz: 630cc4a6cef209358550c04242a82093ddf7729de981ccd3eeb942b8b144286da4c20a4bebe31c07dc2fada801b21e2327fd8b8f59d8b881ac59e097cba0ab9c
data/README.md CHANGED
@@ -3,6 +3,7 @@ Collection of combinatorial test generation strategies.
3
3
 
4
4
  # Usage
5
5
 
6
+ ## Pairwise Testing
6
7
  ```ruby
7
8
  require 'dither'
8
9
 
@@ -31,6 +32,49 @@ Dither.ipog([[true, false],
31
32
 
32
33
  ```
33
34
 
35
+ ## Graph Models (Experimental)
36
+ ```ruby
37
+ raw_graph = {
38
+ :origin => 0,
39
+ :edges => [
40
+ {
41
+ :name => :a,
42
+ :src_vertex => 0,
43
+ :dst_vertex => 1,
44
+ },
45
+ {
46
+ :name => :b,
47
+ :src_vertex => 0,
48
+ :dst_vertex => 2,
49
+ },
50
+ {
51
+ :name => :c,
52
+ :src_vertex => 1,
53
+ :dst_vertex => 2,
54
+ },
55
+ {
56
+ :name => :d,
57
+ :src_vertex => 1,
58
+ :dst_vertex => 3,
59
+ },
60
+ {
61
+ :name => :e,
62
+ :src_vertex => 2,
63
+ :dst_vertex => 3,
64
+ },
65
+ {
66
+ :name => :f,
67
+ :src_vertex => 3,
68
+ :dst_vertex => 0,
69
+ }
70
+ ]
71
+ }
72
+
73
+ # shortest path to cover all edges at least once
74
+ Dither.all_edges(raw_graph)
75
+ ```
76
+
77
+
34
78
  # Note on Patches/Pull Requests
35
79
 
36
80
  * Fork the project.
@@ -0,0 +1,220 @@
1
+
2
+ # implement thimbleby's solution to the chinese @postman problem
3
+ # http://www.cs.swansea.ac.uk/~csharold/cv/files/cpp.pdf
4
+
5
+ module Dither
6
+ module Cpp
7
+ class Graph
8
+
9
+ attr_accessor :n, :neg, :pos, :degree, :path, :edges, :cheapest_edge, :f, :defined, :label, :c, :initialized, :origin
10
+
11
+ Edge = Struct.new(:name, :src_vertex, :dst_vertex)
12
+
13
+ def initialize(n)
14
+
15
+ @n = n
16
+ @degree = Array.new(n).fill(0)
17
+ @defined = Array.new(n).fill { |_| Array.new(n).fill(false) }
18
+ @label = Array.new(n).fill { |_| Array.new(n).fill { |_| [] } }
19
+ @c = Array.new(n).fill { |_| Array.new(n).fill(0.0) }
20
+ @f = Array.new(n).fill { |_| Array.new(n).fill(0) }
21
+ @edges = Array.new(n).fill { |_| Array.new(n).fill(0) }
22
+ @cheapest_edge = Array.new(n).fill { |_| Array.new(n).fill(0) }
23
+ @path = Array.new(n).fill { |_| Array.new(n).fill(0) }
24
+ @initialized = true
25
+ end
26
+
27
+
28
+ def cpp
29
+ initialized?
30
+ least_cost_paths
31
+ check_valid
32
+ find_feasible
33
+ while improvments do
34
+ end
35
+ print(origin)
36
+ end
37
+
38
+ def self.create(raw_graph)
39
+ vertices = [].to_set
40
+ raw_graph[:edges].each do |edge|
41
+ vertices << edge[:src_vertex]
42
+ vertices << edge[:dst_vertex]
43
+ end
44
+
45
+ graph = Graph.new(vertices.length)
46
+
47
+ raw_graph[:edges].each do |edge|
48
+ graph.add_edge(edge[:name], edge[:src_vertex], edge[:dst_vertex], 1)
49
+ end
50
+ graph.origin = raw_graph[:origin]
51
+ graph
52
+ end
53
+
54
+ def add_edge(lab, u, v, cost)
55
+ @label[u][v] = [] unless defined[u][v]
56
+ @label[u][v] << lab
57
+ if !defined[u][v] || c[u][v] > cost
58
+ @c[u][v] = cost
59
+ @cheapest_edge[u][v] = edges[u][v]
60
+ @defined[u][v] = true
61
+ @path[u][v] = v
62
+ end
63
+ @edges[u][v] += 1
64
+ @degree[u] += 1
65
+ @degree[v] -= 1
66
+ self
67
+ end
68
+
69
+ def check_valid
70
+ (0...n).each do |i|
71
+ raise Dither::Error, 'negative cycle' if c[i][i] < 0
72
+ (0...n).each do |j|
73
+ raise Dither::Error, 'not strongly connected' unless defined[i][j]
74
+ end
75
+ end
76
+ end
77
+
78
+ def least_cost_paths
79
+ (0...n).each do |k|
80
+ (0...n).each do |i|
81
+ if defined[i][k]
82
+ (0...n).each do |j|
83
+ if defined[k][j] && (!defined[i][j] || c[i][j] > c[i][k]+c[k][j])
84
+ @defined[i][j] = true
85
+ @path[i][j] = path[i][k]
86
+ @c[i][j] = c[i][k] + c[k][j]
87
+ # negative cycle
88
+ return if i == j && c[i][j] < 0
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ def find_feasible
97
+ nn, np = 0, 0
98
+ (0...n).each do |i|
99
+ if degree[i] < 0
100
+ nn += 1
101
+ elsif degree[i] > 0
102
+ np += 1
103
+ end
104
+ end
105
+
106
+ @neg = Array.new(nn)
107
+ @pos = Array.new(np)
108
+ nn, np = 0, 0
109
+ (0...n).each do |i|
110
+ if degree[i] < 0
111
+ @neg[nn] = i
112
+ nn += 1
113
+ elsif degree[i] > 0
114
+ @pos[np] = i
115
+ np += 1
116
+ end
117
+ end
118
+
119
+ (0...nn).each do |u|
120
+ i = neg[u]
121
+ (0...np).each do |v|
122
+ j = pos[v]
123
+ @f[i][j] = -degree[i] < degree[j] ? -degree[i] : degree[j]
124
+ @degree[i] += f[i][j]
125
+ @degree[j] -= f[i][j]
126
+ end
127
+ end
128
+ end
129
+
130
+ def improvments
131
+ r = Graph.new(n)
132
+ (0...neg.length).each do |u|
133
+ i = neg[u]
134
+ (0...pos.length).each do |v|
135
+ j = pos[v]
136
+ if edges[i][j] > 0
137
+ r.add_edge(nil, i, j, c[i][j])
138
+ end
139
+ if f[i][j] != 0
140
+ r.add_edge(nil, j, i, -c[i][j])
141
+ end
142
+ end
143
+ end
144
+
145
+ r.least_cost_paths
146
+ (0...n).each do |i|
147
+ if r.c[i][i] < 0
148
+ k = 0
149
+ kunset = true
150
+ u = i
151
+ begin
152
+ v = r.path[u][i]
153
+ if r.c[u][v] < 0 && (kunset || k > f[v][u])
154
+ k = f[v][u]
155
+ kunset = false
156
+ end
157
+ u = v
158
+ end while u != i
159
+ u = i
160
+ begin
161
+ v = r.path[u][i]
162
+ if r.c[u][v] < 0
163
+ @f[v][u] -= k
164
+ else
165
+ @f[u][v] += k
166
+ end
167
+ u = v
168
+ end while u != i
169
+ return true
170
+ end
171
+ end
172
+ false
173
+ end
174
+
175
+ def print(start)
176
+ result = []
177
+ v = start
178
+ loop do
179
+ skip = false
180
+ u = v
181
+ (0...n).each do |i|
182
+ if f[u][i] > 0
183
+ v = i
184
+ @f[u][v] -= 1
185
+ while u != v
186
+ p = path[u][v]
187
+ result << Edge.new(label[u][p][cheapest_edge[u][p]], u, p)
188
+ u = p
189
+ end
190
+ skip = true
191
+ end
192
+ end
193
+
194
+ next if skip
195
+
196
+ v = -1
197
+ (0...n).each do |i|
198
+ if edges[u][i] > 0
199
+ v = i if v == -1 || i != path[u][start]
200
+ end
201
+ end
202
+ return result if v == -1
203
+ result << Edge.new(label[u][v][edges[u][v] - 1], u, v)
204
+ @edges[u][v] -= 1
205
+ end
206
+ result
207
+ end
208
+
209
+ def initialized?
210
+ raise Dither::Error, 'graph not initialized' unless initialized
211
+ raise Dither::Error, 'origin not set' unless origin
212
+ @initialized = false
213
+ end
214
+ end # Graph
215
+ end # Cpp
216
+
217
+ def self.all_edges(raw_graph)
218
+ Dither::Cpp::Graph.create(raw_graph).cpp
219
+ end
220
+ end # Dither
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Dither
3
- VERSION = '0.0.10'
3
+ VERSION = '0.0.11'
4
4
  end
data/lib/dither.rb CHANGED
@@ -33,6 +33,7 @@ require 'dither/test_case'
33
33
  require 'dither/ipog_helper'
34
34
  require 'dither/ipog'
35
35
  require 'dither/mipog'
36
+ require 'dither/chinese_postman_problem'
36
37
 
37
38
  if RUBY_PLATFORM =~ /java/
38
39
  require 'java'
@@ -0,0 +1,77 @@
1
+ require File.expand_path('../../spec_helper.rb', __FILE__)
2
+
3
+ describe Dither::Cpp::Graph do
4
+ let(:raw_graph) do
5
+ {
6
+ :origin => 0,
7
+ :edges => [
8
+ {
9
+ :name => :a,
10
+ :src_vertex => 0,
11
+ :dst_vertex => 1,
12
+ },
13
+ {
14
+ :name => :b,
15
+ :src_vertex => 0,
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 => 0,
37
+ }
38
+ ]
39
+ }
40
+ end
41
+
42
+ it 'can compute chinese postman problem' do
43
+ expected = [
44
+ [:b, 0, 2],
45
+ [:e, 2, 3],
46
+ [:f, 3, 0],
47
+ [:a, 0, 1],
48
+ [:c, 1, 2],
49
+ [:e, 2, 3],
50
+ [:f, 3, 0],
51
+ [:a, 0, 1],
52
+ [:d, 1, 3],
53
+ [:f, 3, 0]].map { |a| Dither::Cpp::Graph::Edge.new(*a) }
54
+ expect(Dither.all_edges(raw_graph)).to eq(expected)
55
+ end
56
+
57
+ it 'verify origin is set' do
58
+ raw_graph.delete(:origin)
59
+ expect { Dither.all_edges(raw_graph) }.to raise_error
60
+ end
61
+
62
+ it 'raise error when calling cpp twice' do
63
+ graph = Dither::Cpp::Graph.create(raw_graph)
64
+ graph.cpp
65
+ expect { graph.cpp }.to raise_error
66
+ end
67
+
68
+ it 'raise error when graph is not strongly connected' do
69
+ raw_graph[:edges] << {
70
+ :name => :w,
71
+ :src_vertex => 23,
72
+ :dst_vertex => 78
73
+ }
74
+
75
+ expect { Dither.all_edges(raw_graph) }.to raise_error
76
+ end
77
+ 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.0.10
4
+ version: 0.0.11
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-06-11 00:00:00.000000000 Z
11
+ date: 2015-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -70,6 +70,7 @@ files:
70
70
  - dither.gemspec
71
71
  - lib/dither.jar
72
72
  - lib/dither.rb
73
+ - lib/dither/chinese_postman_problem.rb
73
74
  - lib/dither/ipog.rb
74
75
  - lib/dither/ipog_helper.rb
75
76
  - lib/dither/java_ext/dither.rb
@@ -78,6 +79,7 @@ files:
78
79
  - lib/dither/test_case.rb
79
80
  - lib/dither/unbound_param.rb
80
81
  - lib/dither/version.rb
82
+ - spec/dither/chinese_postman_problem_spec.rb
81
83
  - spec/dither/dither_spec.rb
82
84
  - spec/spec_helper.rb
83
85
  homepage: https://github.com/jesg/dither
@@ -100,10 +102,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
100
102
  version: '0'
101
103
  requirements: []
102
104
  rubyforge_project: dither
103
- rubygems_version: 2.4.5
105
+ rubygems_version: 2.4.6
104
106
  signing_key:
105
107
  specification_version: 4
106
108
  summary: Collection of test generation strategies
107
109
  test_files:
110
+ - spec/dither/chinese_postman_problem_spec.rb
108
111
  - spec/dither/dither_spec.rb
109
112
  - spec/spec_helper.rb