Exemplo n.º 1
0
Arquivo: ilp.py Projeto: ychalier/dice
class Ilp:
    """
    Attributes and their signification @
    http://www.gurobi.com/documentation/8.1/refman/attributes.html#sec:Attributes
    """

    gurobi_log_file = "gurobi.log"
    vars_attrs = [
        "VarName",
        "VType",
        "LB",
        "UB",
        "Obj",
        "X",
        "Xn",
        "RC",
        "BarX",
        "Start",
        "VarHintVal",
        "VarHintPri",
        "BranchPriority",
        "Partition",
        "VBasis",
        "PStart",
        "IISLB",
        "IISUB",
        "PWLObjCvx",
        "SAObjLow",
        "SAObjUp",
        "SALBLow",
        "SALBUp",
        "SAUBLow",
        "SAUBUp",
        "UnbdRay",
    ]
    cstr_attrs = [
        "ConstrName",
        "Sense",
        "RHS",
        "Pi",
        "Slack",
        "CBasis",
        "DStart",
        "Lazy",
        "IISConstr",
        "SARHSLow",
        "SARHSUp",
        "FarkasDual",
    ]

    def __init__(self, variables, model, verbose=True):
        self.variables = variables
        self.model = model
        self.verbose = verbose
        self.assignment = None

    def solve(self, variables_path=None, constraints_path=None):
        open(self.gurobi_log_file, "w").close()
        self.model.params.Threads = 12
        self.model.optimize()
        self.assignment = Assignment(self.variables)
        f_vars, f_cstr = None, None
        if constraints_path is not None:
            f_cstr = open(constraints_path, "w")
            f_cstr.write("\t".join(Ilp.cstr_attrs) + "\n")
        if f_cstr is not None:
            for constraint in self.model.getConstrs():
                for attr in Ilp.cstr_attrs:
                    value = ""
                    try:
                        value = constraint.getAttr(attr)
                    except:
                        pass
                    f_cstr.write(str(value) + "\t")
                f_cstr.write("\n")
            f_cstr.close()
        if variables_path is not None:
            f_vars = open(variables_path, "w")
            f_vars.write("\t".join(Ilp.vars_attrs) + "\n")
        inner_confidence = []
        for gurobi_var in self.model.getVars():
            if gurobi_var.varName[0] not in "PTRS":
                continue
            if gurobi_var.rc == 0:
                up = min(2, gurobi_var.SAObjUp)
                low = max(-2, gurobi_var.SAObjLow)
                inner_confidence.append((gurobi_var.x - .51) * (up - low))
            if len(inner_confidence) == 0:
                a, b = 0, 1
            else:
                a, b = min(inner_confidence), max(inner_confidence)
        for gurobi_var in self.model.getVars():
            if f_vars is not None:
                for attr in Ilp.vars_attrs:
                    value = ""
                    try:
                        value = gurobi_var.getAttr(attr)
                    except:
                        pass
                    f_vars.write(str(value) + "\t")
                f_vars.write("\n")
            letter = gurobi_var.varName[0]
            if letter not in "PTRS":
                continue
            index = int(gurobi_var.varName[2:-1])
            confidence = 0
            if gurobi_var.rc != 0:
                confidence = gurobi_var.rc
            else:
                confidence = gurobi_var.x + gurobi_var.obj + Parameters.EVIDENCE_OFFSET
            self.assignment.assign(
                Variable(index, Dimensions.from_letter(letter)),
                gurobi_var.x >= .5,
                confidence,
            )
        if f_vars is not None:
            f_vars.close()
        return self.assignment

    def report(self):
        with open(self.gurobi_log_file) as file:
            text = file.read()
        report = Report()
        report.add(text)
        return report
Exemplo n.º 2
0
class MaxSat:
    def __init__(self, variables, clauses, verbose=True):
        self.verbose = verbose
        self.variables = variables
        self.clauses = ClauseSet(variables, clauses)
        self.assignment = Assignment(variables)
        self.queue = self.variables[:]
        self.counts = [dict(), dict()]

    def update_counts(self, mask=None):
        clauses = self.clauses.get_units()
        if mask is not None:
            clauses = clauses.intersection(mask)
        for x in self.assignment.get_unassigned():
            self.counts[1][x] = 0.
            self.counts[0][x] = 0.
            for c in clauses:
                if x in c.positives:
                    self.counts[1][x] += c.get_weight()
                if x in c.negatives:
                    self.counts[0][x] += c.get_weight()

    def update_queue(self):
        self.queue.sort(
            key=lambda x: abs(self.counts[1][x] - self.counts[0][x]))

    def find_safe_var(self):
        for x in self.assignment.get_unassigned():
            for truth_value in [True, False]:
                if truth_value:
                    units = self.clauses.get_pos_units(x)
                    unsatisfieds = self.clauses.get_neg_unsatisfieds(x)
                else:
                    units = self.clauses.get_neg_units(x)
                    unsatisfieds = self.clauses.get_pos_unsatisfieds(x)
                confidence = sum([c.get_weight() for c in units]) - sum(
                    [c.get_weight() for c in unsatisfieds])
                if confidence >= 0:
                    return x, truth_value, {
                        True: 1.,
                        False: -1.
                    }[truth_value] * confidence
        return None, None, None

    def solve(self):
        self.update_counts()
        self.update_queue()
        if self.verbose:
            bar = ProgressBar(len(self.queue))
            print("Starting reasoning...")
            bar.start()
        while len(self.queue) > 0:
            x = self.queue.pop()
            if self.verbose:
                bar.increment()
            self.assignment.assign(x, self.counts[1][x] > self.counts[0][x],
                                   self.counts[1][x] - self.counts[0][x])
            self.clauses.update(x, self.counts[1][x] > self.counts[0][x])
            while True:
                safe_var, truth_value, confidence = self.find_safe_var()
                if safe_var is None:
                    break
                self.assignment.assign(safe_var, truth_value, confidence)
                self.clauses.update(safe_var, truth_value)
                self.queue.remove(safe_var)
                if self.verbose:
                    bar.increment()
            self.update_counts(self.clauses.get_occurences(x))
            self.update_queue()
        if self.verbose:
            bar.stop()
        return self.assignment

    def report(self):
        report = Report()
        unsatisfieds = self.clauses.get_unsatisfieds()
        n_clauses = len(self.clauses)
        n_satisfieds = n_clauses - len(unsatisfieds)
        w_total = sum([c.get_weight() for c in self.clauses])
        w_satisfieds = w_total - sum([c.get_weight() for c in unsatisfieds])
        report.add_value_ratio("Satisfied weight", w_satisfieds, w_total)
        report.add_value_ratio("Satisfied clauses", n_satisfieds, n_clauses)
        return report