Class: BayesNetNode

Inherits:
Object
  • Object
show all
Defined in:
lib/bn4r/bn.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, outcomes = [true, false], extra_info = nil) ⇒ BayesNetNode

create de BayesNetNode name is the identifier of the node in the Bayesian Network outcomes is an array with the posible values that this node can have, by default [true, false].

optional

extra_info extra information that can be putted in the node



172
173
174
175
176
177
178
# File 'lib/bn4r/bn.rb', line 172

def initialize ( name , outcomes = [true, false], extra_info = nil)
  @name = name
  @outcomes = outcomes
  @extra_info = extra_info
  @givens = []
  @relations = []
end

Instance Attribute Details

#extra_infoObject (readonly)

Returns the value of attribute extra_info.



165
166
167
# File 'lib/bn4r/bn.rb', line 165

def extra_info
  @extra_info
end

#nameObject (readonly)

Returns the value of attribute name.



165
166
167
# File 'lib/bn4r/bn.rb', line 165

def name
  @name
end

#outcomesObject (readonly)

Returns the value of attribute outcomes.



165
166
167
# File 'lib/bn4r/bn.rb', line 165

def outcomes
  @outcomes
end

#relationsObject (readonly)

Return node relations



207
208
209
# File 'lib/bn4r/bn.rb', line 207

def relations
  @relations
end

#valueObject (readonly)

Returns the value of attribute value.



165
166
167
# File 'lib/bn4r/bn.rb', line 165

def value
  @value
end

Instance Method Details

#all_parents_with_values?Boolean

Returns true if all parents of the node in the bn have values

Returns:

  • (Boolean)


232
233
234
# File 'lib/bn4r/bn.rb', line 232

def all_parents_with_values?
  parents.select {|v| !v.value.nil? }.size == parents.size
end

#clear_valueObject



197
198
199
# File 'lib/bn4r/bn.rb', line 197

def clear_value
  @value = nil
end

#copyObject

Returns a copy of the node itself



186
187
188
189
190
191
# File 'lib/bn4r/bn.rb', line 186

def copy
  tmp = BayesNetNode.new(@name, @outcomes, @extra_info)
  tmp.set_value(@value)
  tmp.set_probability_table(@givens, @table)
  tmp
end

#deep(node = self) ⇒ Object

Returns de deep of the node ( larger path to root nodes )



217
218
219
220
221
222
223
# File 'lib/bn4r/bn.rb', line 217

def deep(node=self)
  res = 1
  res += node.parents.collect { |parent|
    parent.deep  
  }.max unless node.root?
  return res
end

#get_probability(node_assignment = value, givens_assignments = parents_assignments) ⇒ Object

Returns the probability of an assignment to a node conditioned to given_assignments

P(node = node_assignment | givens = givens_assignments)

All givens_assigments must have value.



280
281
282
283
284
285
286
287
288
# File 'lib/bn4r/bn.rb', line 280

def get_probability(node_assignment = value, givens_assignments = parents_assignments)
#    raise "Node must have a value and a givens_assignments, otherwise put" \
 #         + "them in function call" if node_assignment.nil? or givens_assignments.nil?
  # if there's a cached table take the index
  return @table[get_table_index(node_assignment, givens_assignments)] if @table_is_a_proc.nil? or !@table_is_a_proc
  # if the value is calculated on the fly using a function instead of
  # a table
  return @table[node_assignment, givens_assignments]
end

#get_table_index(node_assignment, givens_assignments) ⇒ Object

Returns the corresponding index for the probability table given node_assignment and givens_assignments



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/bn4r/bn.rb', line 292

def get_table_index(node_assignment, givens_assignments)
  x = []
  indices = []
  index = 0
  
  if givens_assignments.length != @givens.length
    raise "Error. Number of assignments does not match node."
  end

  if @givens.length > 0
    # create a indices array with the position of each value of
    # given assignments.
    givens_assignments.length.times { |i|
      assignment = givens_assignments[i]
      indices[i] = @givens[i].outcomes.index(assignment)
    }

    # create a array with the number of possible values each
    # given node and this node itself can have ( node.outcomes.length )
    # plus all next nodes.
    x[givens_assignments.length-1] = @outcomes.length
    (givens_assignments.length-2).downto(0) { |j|
      x[j] = x[j+1] * @givens[j+1].outcomes.length
    }      

    # to get the index, sum for each assignment the
    # product of each given assignment outcomes size
    # by its value index.
    givens_assignments.length.times { |i|
      index += x[i] * indices[i]
    }
  end
  
  index += @outcomes.index(node_assignment)
  
  return index
end

#get_table_sizeObject

returns the number of cells that conditional probability table ( CPT ) haves.



264
265
266
267
268
# File 'lib/bn4r/bn.rb', line 264

def get_table_size
  num = @outcomes.size
  @givens.each { |given| num = num * given.outcomes.size }
  return num
end

#num_parentsObject

Return the number of parents



212
213
214
# File 'lib/bn4r/bn.rb', line 212

def num_parents
  parents.size
end

#parentsObject

Return node parents



202
203
204
# File 'lib/bn4r/bn.rb', line 202

def parents
  return @givens
end

#parents_assignmentsObject



258
259
260
# File 'lib/bn4r/bn.rb', line 258

def parents_assignments
  parents.collect { |p| p.value }
end

#rename(new_name) ⇒ Object

Renames a node



181
182
183
# File 'lib/bn4r/bn.rb', line 181

def rename(new_name)
  @name = new_name  
end

#root?Boolean

Returns true if the node is a root node ( doesn’t have parents ).

Returns:

  • (Boolean)


226
227
228
229
# File 'lib/bn4r/bn.rb', line 226

def root?
  return true if num_parents == 0
  false
end

#set_probability(number, node_assignment, givens_assignments) ⇒ Object

Sets a probability to the node with a node_assignment conditioned to given_assignments

P (node = node_assignment | givens = givens_assignments) = number


272
273
274
# File 'lib/bn4r/bn.rb', line 272

def set_probability(number, node_assignment, givens_assignments)
  @table[get_table_index(node_assignment, givens_assignments)] = number
end

#set_probability_table(givens, table) ⇒ Object

If givens don’t exist, it adds them

if givens is nil, then internal givens is assumed table must have probability values in order like BAD!!! [g0=pos0 & g1=pos0 & … & node_value=pos0, …, g0=pos0 & g1=pos0 & … & node_value=posN,



246
247
248
249
250
251
252
253
254
255
256
# File 'lib/bn4r/bn.rb', line 246

def set_probability_table (givens, table)
  # perhaps we should do some error checking on the table entries here?
  @table_is_a_proc = (table.class != Array)
  @givens = givens if !givens.nil?
  
  raise "Error table incorrect number of positions (" \
    + table.size.to_s + " of " + self.get_table_size.to_s \
    + ")" if table.size != self.get_table_size

  @table = table
end

#set_value(value) ⇒ Object



193
194
195
# File 'lib/bn4r/bn.rb', line 193

def set_value(value)
  @value = value
end

#to_sObject



236
237
238
# File 'lib/bn4r/bn.rb', line 236

def to_s
  return name + (value.nil? ? "" : (" = " + value.to_s))
end