Esempio n. 1
0
 def neighbors(self, node):
     """returns a list of the neighboring nodes of node.
     """
     var = self.variables[len(node)]  # the next variable
     res = []
     for val in self.csp.domains[var]:
         new_env = dict_union(node, {var: val})  #dictionary union
         if self.csp.consistent(new_env):
             res.append(Arc(node, new_env))
     return res
Esempio n. 2
0
 def query(self,var,obs={},elim_order=None):
     """computes P(var|obs) where
     var is a variable
     obs is a variable:value dictionary
     elim_order is a list of the non-observed non-query variables in gm"""
     if var in obs:
         return {val:(1 if val == obs[var] else 0) for val in var.domain}
     else:
        if elim_order == None:
             elim_order = [v for v in self.gm.variables if (v not in obs) and v != var]
        unnorm = [self.rc(dict_union({var:val},obs), self.gm.factors, elim_order) for val in var.domain]
        p_obs = sum(unnorm)
        return {val:pr/p_obs for val,pr in zip(var.domain, unnorm)}
Esempio n. 3
0
 def rc0(self, context, factors, elim_order):
     """simplest search algorithm"""
     self.display(1,"calling rc,",(context,factors))
     if elim_order == []:
         # evaluate factors when all variables are assigned
         self.display(2,"rc evaluating factors")
         return prod(fac.get_value(context) for fac in factors) 
     else:
         total = 0
         var = elim_order[-1]
         self.display(2, "rc branching on", var)
         for val in var.domain:
             total += self.rc0(dict_union({var:val},context), factors, elim_order[:-1])
         self.display(2, "rc branching on", var,"returning", total)
         return total
Esempio n. 4
0
 def rc(self, context, factors, elim_order):
     """ returns the number \sum_{elim_order} \prod_{factors} given assignments in context
     context is a variable:value dictionary
     factors is a list of factors
     elim_order is a list of variables in factors that are not in context
     """
     self.display(1,"calling rc,",(context,factors))
     ce = CacheElt(context, factors)   # key for the appropriate cache entry
     if ce in self.cache:
         self.display(2,"rc cache lookup")
         return self.cache[ce]
     elif factors == []:  # needed if you don't have forgetting and caching
         return 1
     vars_not_in_any_factor = [var for var in context if not any(var in fac.variables for fac in factors)]
     if vars_not_in_any_factor != []:
          # forget variables not in any factor
         self.display(2,"rc forgetting variables", vars_not_in_any_factor)
         return self.rc({key:val for (key,val) in context.items() if key not in vars_not_in_any_factor},
                         factors, elim_order)
     to_eval = [fac for fac in factors if all(v in context for v in fac.variables)]
     if to_eval:
         # evaluate factors when all variables are assigned
         self.display(2,"rc evaluating factors")
         val = prod(fac.get_value(context) for fac in to_eval)
         if val == 0:
             return 0
         else:
          return val * self.rc(context, [fac for fac in factors if fac not in to_eval], elim_order)
     comp = connected_components(context, factors, elim_order)
     if len(comp) >= 1:
         # there are disconnected components
         self.display(2,"splitting into conected components",comp)
         return(prod(self.rc(context,f,eo) for (f,eo) in comp))
     else:
         assert elim_order, "elim_order should not be empty to get here"
         total = 0
         var = elim_order[-1]
         self.display(2, "rc branching on", var)
         for val in var.domain:
             total += self.rc(dict_union({var:val},context), factors, elim_order[:-1])
         self.cache[ce] = total
         self.display(2, "rc branching on", var,"returning", total)
         return total
Esempio n. 5
0
            else:
                return val * self.rc(
                    context, [fac for fac in factors if fac not in to_eval],
                    elim_order)
        elif len(comp := connected_components(context, factors,
                                              elim_order)) >= 1:
            # there are disconnected components
            self.display(2, "splitting into conected components", comp)
            return (prod(self.rc(context, f, eo) for (f, eo) in comp))
        else:
            assert elim_order, "elim_order should not be empty to get here"
            total = 0
            var = elim_order[-1]
            self.display(2, "rc branching on", var)
            for val in var.domain:
                total += self.rc(dict_union({var: val}, context), factors,
                                 elim_order[:-1])
            self.cache[ce] = total
            self.display(2, "rc branching on", var, "returning", total)
            return total

    def rc0(self, context, factors, elim_order):
        """simplest search algorithm"""
        self.display(1, "calling rc,", (context, factors))
        if elim_order == []:
            # evaluate factors when all variables are assigned
            self.display(2, "rc evaluating factors")
            return prod(fac.get_value(context) for fac in factors)
        else:
            total = 0
            var = elim_order[-1]