def max_clique(self, solver): """Computes the maximum clique of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ #python graph.py ./maxino-static instances/example.dmg #Initialize formula formula = wcnf.WCNFFormula() #Create variables nodes = [ formula.new_var() for _ in range(self.n_nodes) ] #Add new variable to the list in the range of the nodes we have. #Create soft clausules for n in nodes: formula.add_clause([n], weight=1) #Create hard clauses completeGraph = self.fillGraph(nodes) for n1, n2 in completeGraph: if ( n1, n2 ) not in self.edges: #Checks the edges that miss on the graph to make it complete. v1, v2 = nodes[n1 - 1], nodes[n2 - 1] formula.add_clause([-v1, -v2], weight=wcnf.TOP_WEIGHT) #formula.write_dimacs() opt, model = solver.solve(formula) #print("OPT:",opt) #print("MODEL:",model) return [n for n in model if n > 0] #Mirar que la respuesta sea esta
def softwarePackageUpgrades(self, solver): packages = {} result = [] formula = wcnf.WCNFFormula() for el in self.packages: packages[el[0]] = formula.new_var() #Soft Clauses for p in packages.values(): formula.add_clause([p], weight=1) #Hard Clauses for d in self.dependences: pklist = [] for pk in d: if d[0] == pk: pklist.append(-packages[pk]) else: pklist.append(packages[pk]) formula.add_clause(pklist, weight=wcnf.TOP_WEIGHT) for c1, c2 in self.conflicts: v1, v2 = packages[c1], packages[c2] formula.add_clause([-v1, -v2], weight=wcnf.TOP_WEIGHT) opt, model = solver.solve(formula) print(len(self.packages)) for i in model: #Search the values of files that can't be used and then gets their name if i < 0: result.append( list(packages.keys())[list(packages.values()).index(-i)]) print("o:", opt) print("v:", " ".join(sorted(result)))
def _as_WCNF(self): """ Return the SPU as WCNF. The function returns the WCNF instance and the variable mapping. """ import wcnf formula = wcnf.WCNFFormula() # Add as many variables as packages for package in self.packages: self.mapping[package] = formula.new_var() # Add packages as soft for var in self.mapping.values(): formula.add_clause([var], 1) # Add dependencies as hard for dep in self.dep: c = [self.mapping[dep[0]] * -1] + \ [self.mapping[predicate] for predicate in dep[1:]] formula.add_clause(c, 0) # Add conflicts as hard for con in self.con: con1, con2 = self.mapping[con[0]], self.mapping[con[1]] formula.add_clauses([[con1, con2], [-con1, -con2]]) return formula
def max_clique(self, solver): """Computes the maximum clique of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ # Initialize formula formula = wcnf.WCNFFormula() # Creates Variables nodes = [formula.new_var() for _ in range(self.n_nodes)] # Creates soft calusules list(map(lambda x: formula.add_clause([x], weight=1), nodes)) # Creates negated edges. All edges is a generator. # Sorted edges is a dictionary so cost for in is O(1). all_edges = ((x, y) for i, x in enumerate(nodes) for y in nodes[i + 1:]) sorted_edges = {tuple((sorted(edge))): edge for edge in self.edges} # It uses list so it's not a generator. negated_edges = (edge for edge in all_edges if edge not in sorted_edges) list( map( lambda x: formula.add_clause( [-nodes[x[0] - 1], -nodes[x[1] - 1]], weight=wcnf.TOP_WEIGHT), negated_edges)) # formula.write_dimacs() # Prints for debug. _, model = solver.solve(formula) # print("Opt: ", opt) # print("Model: ", model) return list(filter(lambda x: x > 0, model))
def max_clique(self, solver): """Compute the maximum clique of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ formula = wcnf.WCNFFormula() nodes = [formula.new_var() for _ in range(self.n_nodes)] # Soft clauses formula.add_clauses([[i] for i in nodes], 1) # Generate all edges in complete graph combinations = [] for i in nodes: for j in nodes[i:]: combinations.append((i, j)) # Hard clauses for i, j in combinations: if (i, j) not in self.edges: formula.add_clause([-i, -j], wcnf.TOP_WEIGHT) solution = msat_runner.solve_formula(solver, formula)[1] return list(filter(lambda x: x > 0, solution))
def package_dependencies(self, solver): """ Computes the packages that cannot be installed. :param solver : An instance of MaxSatRunner. :return: A solution of packages not needed to install. The format is: o <n> v [pkg, ...] where n is the number of packages not installed and pkg is the package not installed """ formula = wcnf.WCNFFormula() generated = collections.defaultdict(formula.new_var) list( map(lambda pkg: formula.add_clause([generated[pkg]], weight=1), self.pkg_toinstall)) func = lambda pkgs: formula.add_clause( [-generated[pkgs[0]], *[generated[x] for x in pkgs[1]]], weight=wcnf.TOP_WEIGHT) list(map(func, self.dependencies)) list( map( lambda pkgs: formula.add_clause([-generated[x] for x in pkgs], weight=wcnf.TOP_WEIGHT), self.conflicts)) opt, model = solver.solve(formula) inv_map = {v: k for k, v in generated.items()} res = list(map(lambda x: inv_map[-x], filter(lambda x: x < 0, model))) res.sort() pkgs = ' '.join(res) return '\to ' + str(opt) + '\n\tv ' + pkgs
def min_vertex_cover(self, solver): """Computes the minimum vertex cover of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ #Initialize formula formula = wcnf.WCNFFormula() #Create variables nodes = [ formula.new_var() for _ in range(self.n_nodes) ] #Add new variable to the list in the range of the nodes we have. #Create soft clausules for n in nodes: formula.add_clause([-n], weight=1) #Create hard clauses for n1, n2 in self.edges: #list with tuples, we extract the tuple in two values v1, v2 = nodes[n1 - 1], nodes[n2 - 1] formula.add_clause([v1, v2], weight=wcnf.TOP_WEIGHT) #formula.write_dimacs() opt, model = solver.solve(formula) #print("OPT:",opt) #print("MODEL:",model) return [n for n in model if n > 0]
def max_cut(self, solver): """Computes the maximum cut of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ #Initialize formula formula = wcnf.WCNFFormula() #Create variables nodes = [ formula.new_var() for _ in range(self.n_nodes) ] #Add new variable to the list in the range of the nodes we have. #Create clausules for a in nodes: for b in nodes[a:]: if (a, b) in self.edges or (b, a) in self.edges: formula.add_clause([a, b], weight=1) formula.add_clause([-a, -b], weight=1) opt, model = solver.solve(formula) #formula.write_dimacs() #print("OPT:",opt) #print("MODEL:",model) return [n for n in model if n > 0]
def __init__(self, solver_path=None, problem_path=None): """ """ #print("Constructor") self.formula = wcnf.WCNFFormula() self.solver = msat_runner.MaxSATRunner(solver_path) self.problem = self.parser(problem_path)
def max_clique_to_maxsat(self): msat = wcnf.WCNFFormula() for _ in self.edges: msat.add_clause([msat.new_var()], 1) for x in xrange(1, self.num_nodes): for y in xrange(x + 1, self.num_nodes + 1): if [x, y] not in self.edges and [y, x] not in self.edges: msat.add_clause([-x, -y], 0) return msat
def min_vertex_cover_to_maxsat(self): msat = wcnf.WCNFFormula() # Soft: Including a vertex in the cover has a cost of 1 for _ in xrange(self.num_nodes): msat.add_clause([-msat.new_var()], 1) # clause weight = 1 # Hard: All edges must be covered for n1, n2 in self.edges: msat.add_clause([n1, n2], 0) # 0 weight means top return msat
def max_cut_to_maxsat(self): msat = wcnf.WCNFFormula() for _ in xrange(self.num_nodes): msat.new_var() for n1, n2 in self.edges: msat.add_clause([n1, n2], 1) msat.add_clause([-n1, n2], 1) return msat
def max_cut_to_maxsat(self): # maxcut = r - e msat = wcnf.WCNFFormula() added = [] for _ in xrange(self.num_nodes): msat.new_var() for n1, n2 in self.edges: if [n2, n1] not in added: msat.add_clause([-n1, -n2], 1) msat.add_clause([n1, n2], 1) added.append([n1, n2]) print msat.soft return msat
def max_cut(self, solver): """Compute the maximum cut of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ formula = wcnf.WCNFFormula() [formula.new_var() for _ in range(self.n_nodes)] # Soft clauses formula.add_clauses([[i, j] for i, j in self.edges] + [[-i, -j] for i, j in self.edges], 1) solution = msat_runner.solve_formula(solver, formula)[1] return list(filter(lambda x: x > 0, solution))
def max_clique_to_maxsat(self): msat = wcnf.WCNFFormula() # **** Your code here **** # Soft: for _ in xrange(self.num_nodes): msat.add_clause([msat.new_var()], 1) # clause weight = 1 # Hard: for i in range(self.num_nodes): for j in range(i+1, self.num_nodes): if [i+1,j+1] not in self.edges and [j+1,i+1] not in self.edges: msat.add_clause([-(i+1), -(j+1)], 0) return msat
def max_cut(self, solver): """Computes the maximum cut of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ def soft_clause(edge): formula.add_clause([nodes[edge[0] - 1], nodes[edge[1] - 1]], weight=1) formula.add_clause([-nodes[edge[0] - 1], -nodes[edge[1] - 1]], weight=1) # Initialize formula formula = wcnf.WCNFFormula() # Creates Variables nodes = [formula.new_var() for _ in range(self.n_nodes)] # Creates soft calusules list(map(soft_clause, self.edges)) _, model = solver.solve(formula) return list(filter(lambda x: x > 0, model))
def min_vertex_cover(self, solver): """Compute the minimum vertex cover of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ # Initialization formula = wcnf.WCNFFormula() nodes = [formula.new_var() for _ in range(self.n_nodes)] # Add nodes to formula as soft clauses formula.add_clauses([[-n] for n in nodes], 1) # Add edges as hard clauses # (works because edges have same domain as ctf vars) formula.add_clauses([[i, j] for i, j in self.edges]) # Find solution solution = msat_runner.solve_formula(solver, formula)[1] # Translate back to problem domain return list(filter(lambda x: x > 0, solution))
def min_vertex_cover(self, solver): """Computes the minimum vertex cover of the graph. :param solver: An instance of MaxSATRunner. :return: A solution (list of nodes). """ # Initialize formula formula = wcnf.WCNFFormula() # Creates Variables nodes = [formula.new_var() for _ in range(self.n_nodes)] # Creates soft calusules list(map(lambda x: formula.add_clause([-x], weight=1), nodes)) list( map( lambda x: formula. add_clause([nodes[x[0] - 1], nodes[x[1] - 1]], weight=wcnf.TOP_WEIGHT), self.edges)) # formula.write_dimacs() # Prints for debug. _, model = solver.solve(formula) # print("Opt: ", opt) # print("Model: ", model) return list(filter(lambda x: x > 0, model))
def __init__(self): self.wcnfformula = wcnf.WCNFFormula() self.nodes = {} #dict key=str, value=int self.dependencies = [] #list of list of int self.conflicts = [] #list of list of int