Beispiel #1
0
    def to_cnf(self, x_vars, cnf):
        d_vars = [[cnf.nv + 1 + j + (j * i) for j in range(self.out_dim)]
                  for i in range(self.out_dim)]
        cnf.nv += self.out_dim**2

        for j in range(self.out_dim):
            for i in range(self.out_dim):
                E_ij = np.ceil((self.b[i] - self.b[j] + np.sum(self.A[i]) -
                                np.sum(self.A[j])) / 2)

                lits = [
                    x if (ai > 0 and aj < 0) else -x
                    for (x, ai, aj) in zip(x_vars, self.A[i], self.A[j])
                    if not (np.sign(ai) == np.sign(aj))
                ]

                ale = CardEnc.atleast(lits, np.ceil(E_ij / 2.0), cnf.nv,
                                      EncType.seqcounter)

                r = ale.nv  # TODO: Check assumption that this is "r(n, D)" of AAAI paper

                cnf.extend(ale.clauses)
                cnf.append([-r, d_vars[i][j]])
                cnf.append([r, -d_vars[i][j]])

        return d_vars
Beispiel #2
0
def get_constraint(idpool: IDPool, id2varmap,
                   constraint: tConstraint) -> CNFPlus:
    """ Generate formula for a given cardinality constraint"""
    validate_constraint(constraint)
    lits = []
    for ta in constraint.tas:
        t1 = tuple((constraint.course_name, ta))
        if t1 not in id2varmap.keys():
            id1 = idpool.id(t1)
            id2varmap[t1] = id1
        else:
            id1 = id2varmap[t1]
        lits.append(id1)

    if constraint.type == tCardType.GREATEROREQUALS:
        if (constraint.bound == 1):
            cnf = CNFPlus()
            cnf.append(lits)
        elif (constraint.bound > len(lits)):
            msg = "Num TAs available for constraint:" + constraint.con_str + "is more than the bound in the constraint. \
            Changing the bound to " + str(len(lits)) + ".\n"
            print(msg, file=sys.stderr)
            constraint.bound = len(lits)

        cnf = CardEnc.atleast(lits, vpool=idpool, bound=constraint.bound)
    elif constraint.type == tCardType.LESSOREQUALS:
        cnf = CardEnc.atmost(lits, vpool=idpool, bound=constraint.bound)
    return cnf
def closest_string(bitarray_list, distance=4):
    """
    Return if a bitarray exists of distance at most 'distance'.
    Use example:

    s1=bitarray('0010')
    s2=bitarray('0011')
    closest_string([s1,s2], distance=0)
    > False
    closest_string([s1,s2], distance=2)
    > True
    """
    if distance < 0:
        raise ValueError('Distance must be positive integer')

    logging.info('\nCodifying SAT Solver...')

    length = max(len(bit_arr) for bit_arr in bitarray_list)
    solver = Solver(name='mcm')
    vpool = IDPool()
    local_list = bitarray_list.copy()

    logging.info(' -> Codifying: normalizing strings')
    for index, bitarr in enumerate(bitarray_list):
        aux = (length - len(bitarr)) * bitarray('0')
        local_list[index] = bitarr + aux

    logging.info(' -> Codifying: imposing distance condition')
    for index, word in enumerate(local_list):
        for pos in range(length):
            vpool.id(ut.xvar(index, pos))

    for pos in range(length):
        vpool.id(ut.yvar(pos))

    for index, word in enumerate(local_list):
        for pos in range(length):
            vpool.id(ut.zvar(index, pos))

    for index, word in enumerate(local_list):
        for pos in range(length):
            for clause in ut.triple_equal(ut.xvar(index, pos),
                                          ut.yvar(pos),
                                          ut.zvar(index, pos),
                                          vpool=vpool):
                solver.add_clause(clause)
        cnf = CardEnc.atleast(
            lits=[vpool.id(ut.zvar(index, pos)) for pos in range(length)],
            bound=length - distance,
            vpool=vpool)
        solver.append_formula(cnf)

    logging.info(' -> Codifying: Words Value')
    assumptions = []
    for index, word in enumerate(local_list):
        for pos in range(length):
            assumptions += [
                vpool.id(ut.xvar(index, pos)) * (-1)**(not word[pos])
            ]

    logging.info('Running SAT Solver...')
    return solver.solve(assumptions=assumptions)