Class: Pairity::AdjacencyMatrix

Inherits:
Object
  • Object
show all
Defined in:
lib/pairity/adjacency_matrix.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeAdjacencyMatrix

Returns a new instance of AdjacencyMatrix.



7
8
9
10
11
# File 'lib/pairity/adjacency_matrix.rb', line 7

def initialize
  @han_solo = Person.new(name: "Han Solo")
  @people = [@han_solo]
  @matrix = {}
end

Instance Attribute Details

#han_soloObject

Returns the value of attribute han_solo.



5
6
7
# File 'lib/pairity/adjacency_matrix.rb', line 5

def han_solo
  @han_solo
end

#matrix(solo = false) ⇒ Object

Returns the value of attribute matrix.



5
6
7
# File 'lib/pairity/adjacency_matrix.rb', line 5

def matrix
  @matrix
end

Instance Method Details

#[](*args) ⇒ Object



52
53
54
# File 'lib/pairity/adjacency_matrix.rb', line 52

def [](*args)
  @matrix[args.sort]
end

#[]=(*args, edge) ⇒ Object



56
57
58
# File 'lib/pairity/adjacency_matrix.rb', line 56

def []=(*args, edge)
  @matrix[args.sort] = edge
end

#add_day_to_pair(pair) ⇒ Object



138
139
140
# File 'lib/pairity/adjacency_matrix.rb', line 138

def add_day_to_pair(pair)
  @matrix[pair.sort].days += 1
end

#add_person(new_person) ⇒ Object



70
71
72
73
74
75
76
# File 'lib/pairity/adjacency_matrix.rb', line 70

def add_person(new_person)
  @people.each do |person|
    pair = [person, new_person].sort
    @matrix[pair] = Edge.new
  end
  @people << new_person
end

#add_weight_to_pair(weight, pair) ⇒ Object



134
135
136
# File 'lib/pairity/adjacency_matrix.rb', line 134

def add_weight_to_pair(weight, pair)
  @matrix[pair.sort].weight += resistance(weight, pair)
end

#all_peopleObject



44
45
46
# File 'lib/pairity/adjacency_matrix.rb', line 44

def all_people
  @people
end

#average_daysObject



84
85
86
87
88
# File 'lib/pairity/adjacency_matrix.rb', line 84

def average_days
  people.combination(2).to_a.inject(0) do |sum, pair|
    sum += self[*pair].days
  end / people.combination(2).size
end

#average_weightObject



78
79
80
81
82
# File 'lib/pairity/adjacency_matrix.rb', line 78

def average_weight
  people.combination(2).to_a.inject(0) do |sum, pair|
    sum += self[*pair].weight
  end / people.combination(2).size
end

#find_person(id) ⇒ Object



97
98
99
# File 'lib/pairity/adjacency_matrix.rb', line 97

def find_person(id)
  @people.find { |p| p.id == id }
end

#get_pairs(pairs, first) ⇒ Object



90
91
92
93
94
95
# File 'lib/pairity/adjacency_matrix.rb', line 90

def get_pairs(pairs, first)
  return [] if pairs.empty?
  pairs.first(first).map do |pair|
    [pair, get_pairs(pairs_without_pair(pairs, pair), 1000).flatten]
  end
end

#optimal_pairs(nopes) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/pairity/adjacency_matrix.rb', line 101

def optimal_pairs(nopes)
  set_ids(people)
  pairing_array = matrix.map do |pair, edge|
    next if nopes.include?(pair.sort)
    p1, p2 = pair
    ids = [p1.id, p2.id].sort
    [ids[0], ids[1], edge.weight * -1]
  end

  pairing_array.compact!

  g = GraphMatching::Graph::WeightedGraph[*pairing_array]
  m = g.maximum_weighted_matching(true)
  m.edges.map do |pair|
    [find_person(pair[0]), find_person(pair[1])]
  end
end

#people(solo = false) ⇒ Object



22
23
24
25
26
27
28
# File 'lib/pairity/adjacency_matrix.rb', line 22

def people(solo = false)
  if @people.size.odd? || solo
    @people.reject { |person| person.name == "Han Solo" }
  else
    @people
  end
end

#remove_person(person) ⇒ Object



119
120
121
122
123
124
# File 'lib/pairity/adjacency_matrix.rb', line 119

def remove_person(person)
  @matrix.reject! do |pair, weight|
    pair.include?(person)
  end
  @people.delete(person)
end

#resistance(weight, pair) ⇒ Object



126
127
128
129
130
131
132
# File 'lib/pairity/adjacency_matrix.rb', line 126

def resistance(weight, pair)
  tier_compensation = 0
  if pair.all?{ |p| p.tier == 1} || pair.all?{ |p| p.tier == 3}
    tier_compensation = 1.5
  end
  @matrix[pair.sort].resistance * weight + tier_compensation
end

#set_ids(persons) ⇒ Object



38
39
40
41
42
# File 'lib/pairity/adjacency_matrix.rb', line 38

def set_ids(persons)
  persons.each_with_index do |p, i|
    p.id = i+1
  end
end

#to_sObject



13
14
15
16
17
18
19
20
# File 'lib/pairity/adjacency_matrix.rb', line 13

def to_s
  output = []
  matrix.each do |pair, weight|
    # next if pair.include?(@han_solo)
    output << "#{pair} -> #{weight}"
  end
  output.join("\n")
end

#weight_for_pair(pair) ⇒ Object



66
67
68
# File 'lib/pairity/adjacency_matrix.rb', line 66

def weight_for_pair(pair)
  @matrix[pair.sort].weight
end

#weight_for_pairs(pairs) ⇒ Object



60
61
62
63
64
# File 'lib/pairity/adjacency_matrix.rb', line 60

def weight_for_pairs(pairs)
  pairs.inject(0) do |sum, pair|
    sum += weight_for_pair(pair)
  end
end

#without_soloObject



48
49
50
# File 'lib/pairity/adjacency_matrix.rb', line 48

def without_solo
  @matrix.reject { |pair, edge| pair.include?(han_solo) }
end