Module: Dither

Defined in:
lib/dither/api.rb,
lib/dither.rb,
lib/dither/aetg.rb,
lib/dither/graph.rb,
lib/dither/version.rb,
lib/dither/aetg_pairwise.rb,
lib/dither/java_ext/dither.rb,
lib/dither/chinese_postman_problem.rb

Overview

implement thimbleby’s solution to the chinese @postman problem www.cs.swansea.ac.uk/~csharold/cv/files/cpp.pdf

Defined Under Namespace

Modules: API, Aetg, Cpp Classes: Error, Graph

Constant Summary collapse

DEFUALT_OPTS =
{
  :t => 2
}
VERSION =
'0.2.6'

Class Method Summary collapse

Class Method Details

.aetg(params, opts = {}) ⇒ Object



84
85
86
87
# File 'lib/dither.rb', line 84

def self.aetg(params, opts = {})
  opts = DEFUALT_OPTS.dup.merge(opts)
  Aetg::Pairwise.new(params, opts).run
end

.all_edges(raw_graph) ⇒ Object

Cpp



217
218
219
# File 'lib/dither/chinese_postman_problem.rb', line 217

def self.all_edges(raw_graph)
  Dither::Cpp::Graph.create(raw_graph).cpp
end

.all_pairs(params, t = 2, opts = {}) ⇒ Object

deprecated



13
14
15
16
# File 'lib/dither.rb', line 13

def self.all_pairs(params, t = 2, opts = {})
  opts[:t] = t
  ipog(params, opts)
end

.ategObject



89
90
91
92
# File 'lib/dither.rb', line 89

def self.aetg(params, opts = {})
  opts = DEFUALT_OPTS.dup.merge(opts)
  Aetg::Pairwise.new(params, opts).run
end

.ipog(params, opts = {}) ⇒ Object

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/dither.rb', line 18

def self.ipog(params, opts = {})
  opts = DEFUALT_OPTS.dup.merge(opts)
  t = opts[:t] || 2
  if t < 2
    raise Dither::Error,'t must be >= 2'
  end
  raise Dither::Error, 'param length must be > 1' if params.any? { |a| a.size <= 1 }
  if t > params.size
    raise Dither::Error, 't must be <= params.length'
  end

  pointer = Dither::API.dither_ipog_new(t)
  c_params = (0..params.max { |a| a.size }.size).to_a
  c_int_params = FFI::MemoryPointer.new(:int, c_params.size)
  c_int_params.write_array_of_int(c_params)

  params.each_with_index do |param, i|
    Dither::API.dither_ipog_add_parameter_int(pointer, i, c_int_params, param.size)
  end

  if opts[:constraints]
    constraint_scratch = FFI::MemoryPointer.new(:int, params.size)
    opts[:constraints].each do |constraint|
      arr = Array.new(params.size, -1)
      constraint.each do |k, v|
        if k >= params.size
          raise Dither::Error, "Invalid constraint #{k} > #{params.size}"
        end
        if v >= params[k].size
          raise Dither::Error, "Invalid constraint #{k} > #{params[k].size}"

        end
        arr[k] = v
      end
      constraint_scratch.write_array_of_int(arr)
      Dither::API.dither_ipog_add_constraint(pointer, constraint_scratch, params.size)
    end
  end

  if opts[:previously_tested]
    tested_scratch = FFI::MemoryPointer.new(:int, params.size)
    opts[:previously_tested].each do |test_case|
      if test_case.size != params.size
        raise Dither::Error
      end
      arr = Array.new(params.size)
      (0...params.size).each do |i|
        arr[i] = params[i].find_index(test_case[i])
      end
      tested_scratch.write_array_of_int(arr)
      Dither::API.dither_ipog_add_previously_tested(pointer, tested_scratch, params.size)
    end
  end

  Dither::API.dither_ipog_run(pointer)
  result_size = Dither::API.dither_ipog_size(pointer)
  solution = FFI::MemoryPointer.new(:int, params.size * result_size)
  Dither::API.dither_ipog_fill(pointer, solution)

  results = solution.read_array_of_int(params.size * result_size)
    .enum_for(:each_slice, params.size)
    .map do |test_case|
    test_case.zip(params).map { |a, b| b[a] }
  end
end