Пример #1
0
def get_upper_bound_peo_pace2017(old_graph,
                                 method="tamaki",
                                 wait_time=60,
                                 print_stats=False):
    """
    Calculates a PEO and treewidth using one of the external solvers

    Parameters
    ----------
    graph : networkx.Graph
           graph to estimate
    method : str
           one of {"tamaki"}
    wait_time : float
           allowed running time (in seconds)

    Returns
    -------
    peo : list

    treewidth : int
           treewidth
    """
    from qtree.graph_model.clique_trees import get_peo_from_tree
    import qtree.graph_model.pace2017_solver_api as api
    method_args = {
        'tamaki': {
            'command': './tw-heuristic',
            'cwd': defs.TAMAKI_SOLVER_PATH,
            'wait_time': wait_time
        }
    }

    assert (method in method_args.keys())
    # ensure graph is labelad starting from 1 with integers
    graph, inv_dict = relabel_graph_nodes(
        old_graph,
        dict(zip(old_graph.nodes, range(1,
                                        old_graph.number_of_nodes() + 1))))

    # Remove selfloops and parallel edges. Critical
    graph = get_simple_graph(graph)

    data = generate_gr_file(graph)
    out_data = api.run_heuristic_solver(data, **method_args[method])
    try:
        stats = get_stats_from_td_file(out_data)
        if print_stats:
            print('stats', stats)
        tree, treewidth = read_td_file(out_data, as_data=True)
    except ValueError:
        print(out_data)
        raise
    peo = get_peo_from_tree(tree)

    # return to the original labelling
    peo = [inv_dict[pp] for pp in peo]

    return peo, treewidth
Пример #2
0
def get_peo(old_graph, method="tamaki"):
    """
    Calculates a perfect elimination order using one of the
    external methods.

    Parameters
    ----------
    graph : networkx.Graph
           graph to estimate
    method : str
           one of {"tamaki"}
    Returns
    -------
    peo : list
           list of nodes in perfect elimination order
    treewidth : int
           treewidth corresponding to peo
    """
    from qtree.graph_model.clique_trees import get_peo_from_tree
    import qtree.graph_model.pace2017_solver_api as api
    method_args = {
        'tamaki': {
            'command': './tw-exact',
            'cwd': defs.TAMAKI_SOLVER_PATH
        }
    }

    assert (method in method_args.keys())
    # ensure graph is labeled starting from 1 with integers
    graph, inv_dict = relabel_graph_nodes(
        old_graph,
        dict(zip(old_graph.nodes, range(1,
                                        old_graph.number_of_nodes() + 1))))

    # Remove selfloops and parallel edges. Critical
    graph = get_simple_graph(graph)

    data = generate_gr_file(graph)
    out_data = api.run_exact_solver(data, **method_args[method])
    tree, treewidth = read_td_file(out_data, as_data=True)
    peo = get_peo_from_tree(tree)
    peo = [inv_dict[pp] for pp in peo]

    try:
        peo_vars = [
            Var(var,
                size=old_graph.nodes[var]['size'],
                name=old_graph.nodes[var]['name']) for var in peo
        ]
    except:
        peo_vars = peo

    return peo_vars, treewidth
Пример #3
0
def get_upper_bound_peo_pace2017_interactive(old_graph,
                                             method="tamaki",
                                             max_time=60,
                                             max_width=None,
                                             print_stats=False):
    """
    Calculates a PEO and treewidth using one of the external solvers

    Parameters
    ----------
    graph : networkx.Graph
           graph to estimate
    method : str
           one of {"tamaki", "tamaki_exact"}
    max_time : float
            Run until not reached time
    max_width : int
           Run until not reached width

    Returns
    -------
    peo : list

    treewidth : int
           treewidth
    """
    from qtree.graph_model.clique_trees import get_peo_from_tree
    import qtree.graph_model.pace2017_solver_api as api
    # ensure graph is labelad starting from 1 with integers
    graph, inv_dict = relabel_graph_nodes(
        old_graph,
        dict(zip(old_graph.nodes, range(1,
                                        old_graph.number_of_nodes() + 1))))

    # Remove selfloops and parallel edges. Critical
    graph = get_simple_graph(graph)

    data = generate_gr_file(graph)
    start = time.time()

    def callback(line_info):
        ts, width = line_info
        print(f'Time={ts}, width={width}', file=sys.stderr)
        elapsed = time.time() - start
        if max_time:
            if elapsed > max_time:
                raise StopIteration('Timeout')
        if max_width and width:
            if width <= max_width:
                raise StopIteration('Solution is good enough')

    method_args = {
        'tamaki': {
            'command': './tw-heuristic',
            'cwd': defs.TAMAKI_SOLVER_PATH,
            'callback': callback,
        },
        'tamaki_exact': {
            'command':
            './tw-exact',
            'cwd':
            defs.TAMAKI_SOLVER_PATH,
            'callback':
            lambda x: print(f'Time={time.time()-start}', file=sys.stderr),
            'callback_delay':
            2
        }
    }

    assert (method in method_args.keys())

    out_data = api.run_heuristic_solver_interactive(data,
                                                    **method_args[method])
    try:
        stats = get_stats_from_td_file(out_data)
        if print_stats:
            print('stats', stats)
        tree, treewidth = read_td_file(out_data, as_data=True)
    except ValueError:
        print(out_data)
        raise
    peo = get_peo_from_tree(tree)

    # return to the original labelling
    peo = [inv_dict[pp] for pp in peo]

    return peo, treewidth