def num_lattice_points_fast(n): # count with inclusion-exclusion if n == 1: return 1 if (n + 3) % 2 == 1: return 0 a = (n + 3) / 2 half_a = (a - 1) / 2 first_lattice_point_x = 3 - (a % 3) prime_factors_a = [p for p, m in utils.prime_factors(a)] # A is every 3rd point on the line in the lattice, B1 is all points w/ x # coord divisible by prime factor i # #(A and not B) = #A - #(A and (B1 or B2 or ...)) # = #A - #((A and B1) or (A and B2) or ..) # = #A - (#(A and B1) + #(A and B2) + ... - #(A and B1 and B2) - ...) num_lattice_points_half = 0 factor_sets = utils.power_set(prime_factors_a) for factors in factor_sets: sign = 1 if (len(factors) % 2 == 0) else -1 pr = [(3, first_lattice_point_x)] + [(f, 0) for f in factors] num_lattice_points_half += sign * count_elts_in_range_with_remainders(first_lattice_point_x, half_a + 1, pr) return num_lattice_points_half * 2
def all_hypotheses(examples): """Build a list of all the possible hypotheses""" values = values_table(examples) h_powerset = power_set(values.keys()) hypotheses = [] for s in h_powerset: hypotheses.extend(build_attr_combinations(s, values)) hypotheses.extend(build_h_combinations(hypotheses)) return hypotheses
def generalizations(examples_so_far, h): """Generalize the hypothesis. First delete operations (including disjunctions) from the hypothesis. Then, add OR operations.""" hypotheses = [] # Delete disjunctions disj_powerset = power_set(range(len(h))) for disjs in disj_powerset: h2 = h.copy() for d in reversed(list(disjs)): del h2[d] if check_all_consistency(examples_so_far, h2): hypotheses += h2 # Delete AND operations in disjunctions for i, disj in enumerate(h): a_powerset = power_set(disj.keys()) for attrs in a_powerset: h2 = h[i].copy() for a in attrs: del h2[a] if check_all_consistency(examples_so_far, [h2]): h3 = h.copy() h3[i] = h2.copy() hypotheses += h3 # Add OR operations if hypotheses == [] or hypotheses == [{}]: hypotheses = add_or(examples_so_far, h) else: hypotheses.extend(add_or(examples_so_far, h)) shuffle(hypotheses) return hypotheses
def build_h_combinations(hypotheses): """Given a set of hypotheses, builds and returns all the combinations of the hypotheses.""" h = [] h_powerset = power_set(range(len(hypotheses))) for s in h_powerset: t = [] for i in s: t.extend(hypotheses[i]) h.append(t) return h
def add_or(examples_so_far, h): """Add an OR operation to the hypothesis. The AND operations in the disjunction are generated by the last example (which is the problematic one).""" ors = [] e = examples_so_far[-1] attrs = {k: v for k, v in e.items() if k != 'GOAL'} a_powerset = power_set(attrs.keys()) for c in a_powerset: h2 = {} for k in c: h2[k] = attrs[k] if check_negative_consistency(examples_so_far, h2): h3 = h.copy() h3.append(h2) ors.append(h3) return ors
def test_power_set(self): assert list(utils.power_set([1, 2, 3])) == [(), (1, ), (2, ), (3, ), (1, 2), (1, 3), (2, 3), (1, 2, 3)]