示例#1
0
def convert_ensmallen_graph_to_networkx_graph(graph: Graph) -> nx.Graph:
    """Return networkX graph derived from the provided Ensmallen Graph.
    
    Parameters
    -----------
    graph: Graph
        The graph to be converted.
    """
    if graph.is_directed():
        result_graph = nx.DiGraph()
    else:
        result_graph = nx.Graph()

    result_graph.add_nodes_from(graph.get_node_ids())

    if graph.has_edge_weights():
        result_graph.add_weighted_edges_from([
            (src_name, dst_name, edge_weight)
            for (src_name, dst_name), edge_weight in zip(
                graph.get_directed_edge_node_ids(), graph.get_edge_weights())
        ])
    else:
        result_graph.add_edges_from(
            graph.get_edge_node_ids(directed=graph.is_directed()))

    return result_graph
示例#2
0
def graph_to_sparse_tensor(
    graph: Graph,
    use_weights: bool,
    use_simmetric_normalized_laplacian: bool,
    handling_multi_graph: str = "warn",
) -> tf.SparseTensor:
    """Returns provided graph as sparse Tensor.

    Parameters
    -------------------
    graph: Graph,
        The graph to convert.
    use_weights: bool,
        Whether to load the graph weights.
    use_simmetric_normalized_laplacian: bool
        Whether to use the symmetrically normalized laplacian 
    handling_multi_graph: str = "warn"
        How to behave when dealing with multigraphs.
        Possible behaviours are:
        - "warn", which warns the user and drops the multi-edges.
        - "raise"
        - "drop"

    Raises
    -------------------
    ValueError,
        If the weights are requested but the graph does not contain any.
    ValueError,
        If the graph contains singletons.
    ValueError,
        If the graph is a multigraph.

    Returns
    -------------------
    SparseTensor with (weighted) adjacency matrix.
    """
    if use_weights and not graph.has_edge_weights():
        raise ValueError("Edge weights were requested but the provided graph "
                         "does not contain any edge weight.")

    if graph.has_singleton_nodes():
        raise ValueError(
            f"In the provided {graph.get_name()} graph there are "
            f"{graph.get_number_of_singleton_nodes()} singleton nodes."
            "The GCN model does not support operations on graph containing "
            "singletons. You can either choose to drop singletons from "
            "the graph by using the `graph.remove_singleton_nodes()` "
            "method or alternatively you can add selfloops to them by "
            "using the `graph.add_selfloops()` method.")

    if graph.is_multigraph():
        message = (
            "The GCN model does not currently support convolutions on a multigraph. "
            "We are dropping the parallel edges before computing the adjacency matrix."
        )
        if handling_multi_graph == "warn":
            warnings.warn(message)
        elif handling_multi_graph == "raise":
            raise ValueError(message)

        graph = graph.remove_parallel_edges()

    if use_simmetric_normalized_laplacian:
        edge_node_ids, weights = graph.get_symmetric_normalized_laplacian_coo_matrix(
        )
        return tf.sparse.reorder(
            tf.SparseTensor(
                edge_node_ids, np.abs(weights),
                (graph.get_number_of_nodes(), graph.get_number_of_nodes())))

    return tf.SparseTensor(
        graph.get_directed_edge_node_ids(),
        (graph.get_edge_weights()
         if use_weights else tf.ones(graph.get_number_of_directed_edges())),
        (graph.get_number_of_nodes(), graph.get_number_of_nodes()))