Type Definition net_ensembles::graph::Graph

source · []
pub type Graph<T> = GenericGraph<T, NodeContainer<T>>;
Expand description

Contains the topology and implements functions for analyzing topology

used for graph ensembles

Example:

A graph, where each node stores a phase

use net_ensembles::{Graph, Node, AdjContainer};
use net_ensembles::traits::DotExtra;

use std::fs::File;

// Note: feature "serde_support" is enabled on default
#[cfg(feature = "serde_support")]
use serde_json;
#[cfg(feature = "serde_support")]
use serde::{Serialize, Deserialize};

// define your own vertices, if you need to store extra information at each vertex
// if you do not use the feature "serde_support", you do not need to derive Serialize and Deserialize
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde_support", derive(Serialize, Deserialize))]
pub struct PhaseNode {phase: f64,}

// implement whatever you need
impl PhaseNode {
    pub fn set_phase(&mut self, phase: f64) {
        self.phase = phase;
    }

    pub fn get_phase(&self) -> f64 {
        self.phase
    }
}

// implement the trait `Node`
impl Node for PhaseNode {
    fn new_from_index(index: usize) -> Self {
        PhaseNode { phase: index as f64 * 10.0}
    }

}

// now you can create an empty graph
let mut graph: Graph<PhaseNode> = Graph::new(4);
for i in 0..4 {
    assert_eq!(
      graph.at(i).get_phase(),
      i as f64 * 10.0
    );
}

// and fill it with edges
for i in 0..4 {
    graph.add_edge(i, (i + 1) % 4).unwrap();
}


// you can manipulate the extra information stored at each Vertex
for i in 0..4 {
    graph.at_mut(i).set_phase(i as f64 * 0.5);
}

// you can, of course, also access the information
for i in 0..4 {
    assert_eq!(
        graph.at(i).get_phase(),
        i as f64 * 0.5
    );
}

// if you want to visualize your graph, you can generate a file with graphviz representation
let mut f = File::create("phase_example.dot").expect("Unable to create file");
graph.dot_from_contained_index(
    f,
    "",
    |index, contained|
        format!(
                "Phase: {} at index {}",
                contained.get_phase(),
                index
        )
).unwrap();

// storing the graph only works, if the feature "serde_support" is enabled (enabled by default)
#[cfg(feature = "serde_support")]
{
    let mut graph_file = File::create("store_graph_example.dat")
           .expect("Unable to create file");
    let s = serde_json::to_writer_pretty(graph_file, &graph).unwrap();

    // loading stored graph:
    let mut read_in = File::open("store_graph_example.dat")
        .expect("Unable to open file");


    let graph2:  Graph<PhaseNode> = serde_json::from_reader(read_in).unwrap();


    // now, to show, that the graphs are equal, here is one of my test functions:
    // modified for this example, which is a doc-test, so this example also serves as unit test

    fn assert_equal_graphs(g1: &Graph<PhaseNode>, g2: &Graph<PhaseNode>) {
        assert_eq!(g1.edge_count(), g2.edge_count());
        assert_eq!(g1.vertex_count(), g2.vertex_count());
        for (n0, n1) in g2.container_iter().zip(g1.container_iter()) {
            assert_eq!(n1.id(), n0.id());
            assert_eq!(n0.degree(), n1.degree());

            for (i, j) in n1.neighbors().zip(n0.neighbors()) {
                assert_eq!(i, j);
            }
        }

        for i in 0..g2.vertex_count() {
            assert_eq!(
                g1.at(i).get_phase(),
                g2.at(i).get_phase()
            );
        }
    }

    // lets use it
    assert_equal_graphs(&graph, &graph2);

    // you can also clone the graph, if you need:
    let clone = graph.clone();
    assert_equal_graphs(&graph, &clone);
    let clone2 = graph2.clone();
    assert_equal_graphs(&clone, &clone2);
}

phase_example.dot will contain

graph G{

    0 1 2 3 ;
    "0" [label="Phase: 0 at index 0"];
    "1" [label="Phase: 0.5 at index 1"];
    "2" [label="Phase: 1 at index 2"];
    "3" [label="Phase: 1.5 at index 3"];
    0 -- 1
    0 -- 3
    1 -- 2
    2 -- 3
}

Now you can use circo or similar programs to create a pdf from that. Search for graphviz for more info.

Note

You can also use collect to create a new graph:

use net_ensembles::Graph;
 
let mut graph: Graph<_> = (0..3).collect();
// you have to add the edges yourself
graph.add_edge(0, 1).unwrap();

Implementations

Efficiently create a complete graph with n nodes

Trait Implementations

Converts to this type from the input type.
Creates a value from an iterator. Read more