Пример #1
0
def create_coarse_graph(graph, groups, coarse_graph_size):
    '''create the coarser graph and return it based on the groups array and coarse_graph_size'''
    coarse_graph = Graph(coarse_graph_size, graph.edge_num)
    coarse_graph.finer = graph
    graph.coarser = coarse_graph
    cmap = graph.cmap
    adj_list = graph.adj_list
    adj_idx = graph.adj_idx
    adj_wgt = graph.adj_wgt
    node_wgt = graph.node_wgt

    coarse_adj_list = coarse_graph.adj_list
    coarse_adj_idx = coarse_graph.adj_idx
    coarse_adj_wgt = coarse_graph.adj_wgt
    coarse_node_wgt = coarse_graph.node_wgt
    coarse_degree = coarse_graph.degree

    coarse_adj_idx[0] = 0
    nedges = 0  # number of edges in the coarse graph
    for idx in range(len(groups)):  # idx in the graph
        coarse_node_idx = idx
        neigh_dict = dict(
        )  # coarser graph neighbor node --> its location idx in adj_list.
        group = groups[idx]
        for i in range(len(group)):
            merged_node = group[i]
            if (i == 0):
                coarse_node_wgt[coarse_node_idx] = node_wgt[merged_node]
            else:
                coarse_node_wgt[coarse_node_idx] += node_wgt[merged_node]

            istart = adj_idx[merged_node]
            iend = adj_idx[merged_node + 1]
            for j in range(istart, iend):
                k = cmap[adj_list[
                    j]]  # adj_list[j] is the neigh of v; k is the new mapped id of adj_list[j] in coarse graph.
                if k not in neigh_dict:  # add new neigh
                    coarse_adj_list[nedges] = k
                    coarse_adj_wgt[nedges] = adj_wgt[j]
                    neigh_dict[k] = nedges
                    nedges += 1
                else:  # increase weight to the existing neigh
                    coarse_adj_wgt[neigh_dict[k]] += adj_wgt[j]
                # add weights to the degree. For now, we retain the loop.
                coarse_degree[coarse_node_idx] += adj_wgt[j]

        coarse_node_idx += 1
        coarse_adj_idx[coarse_node_idx] = nedges

    coarse_graph.edge_num = nedges

    coarse_graph.resize_adj(nedges)
    C = cmap2C(cmap)  # construct the matching matrix.
    graph.C = C
    coarse_graph.A = C.transpose().dot(graph.A).dot(C)
    return coarse_graph
Пример #2
0
def _read_graph_from_metis(ctrl, file_path):
    '''Assume idx starts from *1* and are continuous. Edge shows up twice. Assume single connected component.'''
    #    logging.info("Reading graph from metis...")
    in_file = open(file_path)
    first_line = [int(ele) for ele in in_file.readline().strip().split()]
    weighted = False
    if len(first_line) == 3 and first_line[-1] == 1:
        weighted = True
    node_num, edge_num = first_line[:2]
    edge_num *= 2
    graph = Graph(node_num, edge_num)
    edge_cnt = 0
    graph.adj_idx[0] = 0
    for idx in range(node_num):
        graph.node_wgt[idx] = 1
        eles = in_file.readline().strip().split()
        j = 0
        while j < len(eles):
            neigh = int(
                eles[j]) - 1  # needs to minus 1 as metis starts with 1.
            if weighted:
                wgt = float(eles[j + 1])
            else:
                wgt = 1.0
            graph.adj_list[edge_cnt] = neigh  # self-loop included.
            graph.adj_wgt[edge_cnt] = wgt
            graph.degree[idx] += wgt
            edge_cnt += 1
            if weighted:
                j += 2
            else:
                j += 1
        graph.adj_idx[idx + 1] = edge_cnt
    graph.A = graph_to_adj(graph, self_loop=False)
    # check connectivity in debug mode
    if ctrl.debug_mode:
        assert nx.is_connected(graph2nx(graph))

    return graph, None
Пример #3
0
def read_graph_from_adj(adj, dataset_name):
    '''Assume idx starts from *1* and are continuous. Edge shows up twice. Assume single connected component.'''
    #    logging.info("Reading graph from metis...")
    with open("data/ind.{}.{}".format(dataset_name, 'graph'), 'rb') as f:
        if sys.version_info > (3, 0):
            in_file = pkl.load(f, encoding='latin1')
        else:
            in_file = pkl.load(f)
    weighted = False
    node_num = adj.shape[0]
    edge_num = np.count_nonzero(adj.toarray()) * 2
    graph = Graph(node_num, edge_num)
    edge_cnt = 0
    graph.adj_idx[0] = 0
    for idx in range(node_num):
        graph.node_wgt[idx] = 1
        eles = in_file[idx]
        j = 0
        while j < len(eles):
            neigh = int(eles[j])  #
            if weighted:
                wgt = float(eles[j + 1])
            else:
                wgt = 1.0
            graph.adj_list[edge_cnt] = neigh  # self-loop included.
            graph.adj_wgt[edge_cnt] = wgt
            graph.degree[idx] += wgt
            edge_cnt += 1
            if weighted:
                j += 2
            else:
                j += 1
        graph.adj_idx[idx + 1] = edge_cnt
    graph.A = graph_to_adj(graph, self_loop=False)
    # check connectivity in debug mode
    # if ctrl.debug_mode:
    #     assert nx.is_connected(graph2nx(graph))
    return graph, None
Пример #4
0
def _read_graph_from_edgelist(ctrl, file_path):
    '''Assume each edge shows up ONLY once: small-id<space>large-id, or small-id<space>large-id<space>weight. 
    Indices are not required to be continuous.'''
    #    logging.info("Reading graph from edgelist...")
    in_file = open(file_path)
    neigh_dict = defaultdict(list)
    max_idx = -1
    edge_num = 0
    for line in in_file:
        eles = line.strip().split()
        n0, n1 = [int(ele) for ele in eles[:2]]
        assert n0 <= n1, "first id in a row should be the smaller one..."
        if len(eles) == 3:  # weighted graph
            wgt = float(eles[2])
            neigh_dict[n0].append((n1, wgt))
            if n0 != n1:
                neigh_dict[n1].append((n0, wgt))
        else:
            neigh_dict[n0].append(n1)
            if n0 != n1:
                neigh_dict[n1].append(n0)
        if n0 != n1:
            edge_num += 2
        else:
            edge_num += 1
        max_idx = max(max_idx, n1)
    in_file.close()
    weighted = (len(eles) == 3)
    continuous_idx = (max_idx + 1 == len(neigh_dict))  # starting from zero
    mapping = None
    if not continuous_idx:
        old2new = dict()
        new2old = dict()
        cnt = 0
        sorted_keys = sorted(neigh_dict.keys())
        for key in sorted_keys:
            old2new[key] = cnt
            new2old[cnt] = key
            cnt += 1
        new_neigh_dict = defaultdict(list)
        for key in sorted_keys:
            for tpl in neigh_dict[key]:
                node_u = old2new[key]
                if weighted:
                    new_neigh_dict[node_u].append((old2new[tpl[0]], tpl[1]))
                else:
                    new_neigh_dict[node_u].append(old2new[tpl])
        del sorted_keys
        neigh_dict = new_neigh_dict  # remapped
        mapping = Mapping(old2new, new2old)

    node_num = len(neigh_dict)
    graph = Graph(node_num, edge_num)
    edge_cnt = 0
    graph.adj_idx[0] = 0
    for idx in range(node_num):
        graph.node_wgt[idx] = 1  # default weight to nodes
        for neigh in neigh_dict[idx]:
            if weighted:
                graph.adj_list[edge_cnt] = neigh[0]
                graph.adj_wgt[edge_cnt] = neigh[1]
            else:
                graph.adj_list[edge_cnt] = neigh
                graph.adj_wgt[edge_cnt] = 1.0
            edge_cnt += 1
        graph.adj_idx[idx + 1] = edge_cnt

    if ctrl.debug_mode:
        assert nx.is_connected(
            graph2nx(graph)
        ), "Only single connected component is allowed for embedding."

    graph.A = graph_to_adj(graph, self_loop=False)
    return graph, mapping