def decompose(num_vertices, edges, htd, node_map=None, minor_graph=None, **kwargs): logger.debug(f"Using tree decomposition seed: {kwargs['runid']}") # Run htd p = subprocess.Popen([htd["path"], "--seed", str(kwargs["runid"]), *htd["parameters"]], stdin=subprocess.PIPE, stdout=subprocess.PIPE) if "gr_file" in kwargs and kwargs["gr_file"]: logger.debug("Writing graph file") with FileWriter(kwargs["gr_file"]) as fw: fw.write_gr(num_vertices,edges) logger.debug("Running htd") StreamWriter(p.stdin).write_gr(num_vertices,edges) p.stdin.close() tdr = TdReader.from_stream(p.stdout) p.wait() if node_map: logger.debug("De-normalizing tree decomposition") tdr.bags = {k: [node_map[vv] for vv in v] for k, v in tdr.bags.items()} logger.debug("Parsing tree decomposition") #td = TreeDecomp(tdr.num_bags, tdr.tree_width, tdr.num_orig_vertices, problem.get_root(tdr.bags, tdr.adjacency_list, tdr.root), tdr.bags, tdr.adjacency_list) td = TreeDecomp(tdr.num_bags, tdr.tree_width, tdr.num_orig_vertices, tdr.root, tdr.bags, tdr.adjacency_list, minor_graph) logger.info(f"Tree decomposition #bags: {td.num_bags} tree_width: {td.tree_width} #vertices: {td.num_orig_vertices} #leafs: {len(td.leafs)} #edges: {len(td.edges)}") if "td_file" in kwargs and kwargs["td_file"]: with FileWriter(kwargs["td_file"]) as fw: fw.write_td(tdr.num_bags, tdr.tree_width, tdr.num_orig_vertices, tdr.root, tdr.bags, td.edges) return td
def prepare_input(self, fname): if self.input_format == "td": input = TdReader.from_file(fname) elif self.input_format == "tw": input = TwReader.from_file(fname) elif self.input_format == "edge": input = EdgeReader.from_file(fname) self.num_vertices = input.num_vertices self.edges = input.adjacency_list return (input.num_vertices, input.edges)
def solve_problem(cfg, cls, file, **kwargs): def signal_handler(sig, frame): if sig == signal.SIGUSR1: logger.warning("Terminating because of error in worker thread") else: logger.warning("Killing all connections") problem.interrupt() app_name = None if "application_name" in cfg["db"]["dsn"]: app_name = cfg["db"]["dsn"]["application_name"] admin_db.killall(app_name) sys.exit(0) admin_db = DBAdmin.from_cfg(cfg["db_admin"]) signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) signal.signal(signal.SIGUSR1, signal_handler) pool = BlockingThreadedConnectionPool(1,cfg["db"]["max_connections"],**cfg["db"]["dsn"]) problem = cls(file,pool, **cfg["dpdb"], **kwargs) logger.info("Using tree decomposition seed: {}".format(kwargs["runid"])) # Run htd p = subprocess.Popen([cfg["htd"]["path"], "--seed", str(kwargs["runid"]), *cfg["htd"]["parameters"]], stdin=subprocess.PIPE, stdout=subprocess.PIPE) logger.info("Parsing input file") input = problem.prepare_input(file) if "gr_file" in kwargs and kwargs["gr_file"]: logger.info("Writing graph file") with FileWriter(kwargs["gr_file"]) as fw: fw.write_gr(*input) logger.info("Running htd") StreamWriter(p.stdin).write_gr(*input) p.stdin.close() tdr = TdReader.from_stream(p.stdout) p.wait() # solve it logger.info("Parsing tree decomposition") td = TreeDecomp(tdr.num_bags, tdr.tree_width, tdr.num_orig_vertices, tdr.root, tdr.bags, tdr.adjacency_list) logger.info(f"#bags: {td.num_bags} tree_width: {td.tree_width} #vertices: {td.num_orig_vertices} #leafs: {len(td.leafs)} #edges: {len(td.edges)}") if "td_file" in kwargs and kwargs["td_file"]: with FileWriter(kwargs["td_file"]) as fw: fw.write_td(tdr.num_bags, tdr.tree_width, tdr.num_orig_vertices, tdr.root, tdr.bags, td.edges) if td.tree_width <= tw_limit: problem.set_td(td) problem.setup() if "faster" not in kwargs or not kwargs["faster"]: problem.store_cfg(flatten_cfg(cfg,("db.dsn","db_admin","htd.path"))) problem.solve() else: print("Treewidth Limit Reached")