# Graphs.jl interface

```
julia> using Graphs
julia> using MetaGraphsNext
```

`MetaGraph`

s inherit many methods from Graphs.jl. In general, inherited methods refer to vertices by codes, not labels, for compatibility with the `AbstractGraph`

interface.

Note that vertex codes get reassigned after `rem_vertex!`

operations to remain contiguous, so we recommend systematically converting to and from labels.

## Undirected graphs

We can make `MetaGraph`

s based on (undirected) `Graph`

s.

`julia> cities = MetaGraph(Graph(), VertexData = String, EdgeData = Int, weight_function = identity, default_weight = 0);`

Let us add some cities and the distance between them:

```
julia> cities[:Paris] = "France";
julia> cities[:London] = "UK";
julia> cities[:Berlin] = "Germany";
julia> cities[:Paris, :London] = 344;
julia> cities[:Paris, :Berlin] = 878;
```

The general properties of the graph are as expected:

```
julia> is_directed(cities)
false
julia> eltype(cities)
Int64
julia> edgetype(cities)
Graphs.SimpleGraphs.SimpleEdge{Int64}
julia> SimpleGraph(cities)
{3, 2} undirected simple Int64 graph
```

We can check the set of vertices:

```
julia> nv(cities)
3
julia> Tuple(collect(vertices(cities)))
(1, 2, 3)
julia> has_vertex(cities, 2)
true
julia> has_vertex(cities, 4)
false
```

Note that we can't add the same city (i.e. vertex label) twice:

```
julia> add_vertex!(cities, :London, "Italy")
false
julia> nv(cities)
3
```

We then check the set of edges:

```
julia> ne(cities)
2
julia> Tuple(collect(edges(cities)))
(Edge 1 => 2, Edge 1 => 3)
julia> has_edge(cities, 1, 2)
true
julia> has_edge(cities, 2, 3)
false
```

From this initial graph, we can create some others:

```
julia> copy(cities) == cities
true
julia> zero(cities) == cities
false
julia> nv(zero(cities))
0
```

Since `cities`

is a weighted graph, we can leverage the whole Graphs.jl machinery of graph analysis and traversal:

```
julia> diameter(cities)
1222
julia> ds = dijkstra_shortest_paths(cities, 2); Tuple(ds.dists)
(344, 0, 1222)
```

Finally, let us remove some edges and vertices

```
julia> rem_edge!(cities, 1, 3)
true
julia> rem_vertex!(cities, 3)
true
julia> rem_vertex!(cities, 3)
false
julia> has_vertex(cities, 1)
true
julia> has_vertex(cities, 3)
false
```

## Directed graphs

We can make `MetaGraph`

s based on `DiGraph`

s as well.

```
julia> rock_paper_scissors = MetaGraph(DiGraph(), Label = Symbol, EdgeData = Symbol);
julia> for label in [:rock, :paper, :scissors]; rock_paper_scissors[label] = nothing; end;
julia> rock_paper_scissors[:rock, :scissors] = :rock_beats_scissors; rock_paper_scissors[:scissors, :paper] = :scissors_beat_paper; rock_paper_scissors[:paper, :rock] = :paper_beats_rock;
```

We see that the underlying graph has changed:

```
julia> is_directed(rock_paper_scissors)
true
julia> SimpleDiGraph(rock_paper_scissors)
{3, 3} directed simple Int64 graph
```

Directed graphs can be reversed:

```
julia> haskey(rock_paper_scissors, :scissors, :rock)
false
julia> haskey(reverse(rock_paper_scissors), :scissors, :rock)
true
```

Finally, let us take a subgraph:

```
julia> rock_paper, _ = induced_subgraph(rock_paper_scissors, [1, 2]);
julia> issubset(rock_paper, rock_paper_scissors)
true
julia> haskey(rock_paper, :paper, :rock)
true
julia> haskey(rock_paper, :rock, :scissors)
false
```