SharpGraph 1.4.4
dotnet add package SharpGraph --version 1.4.4
NuGet\Install-Package SharpGraph -Version 1.4.4
<PackageReference Include="SharpGraph" Version="1.4.4" />
paket add SharpGraph --version 1.4.4
#r "nuget: SharpGraph, 1.4.4"
// Install SharpGraph as a Cake Addin #addin nuget:?package=SharpGraph&version=1.4.4 // Install SharpGraph as a Cake Tool #tool nuget:?package=SharpGraph&version=1.4.4
SharpGraph
A powerful C# graph library, made by Dirk-Jan Meijer.
Nuget
Getting started
You only need to create two classes in order to use the SharpGraph library.
- A vertex class, which represents a node.
- An edge class, which represents a connection between two vertices.
The vertex class should extend the Vertex base class and the edge class should extend either the Line class (undirected edge) or the Arrow class (directed edge).
Example code
This is a simplified example of how to create a graph with SharpGraph and search for the shortest path between two cities.
using SharpGraph.Core;
using SharpGraph.Core.Elements;
using SharpGraph.Core.Elements.ValueTypes;
// Initialize the graph.
var graph = new Graph<City, Road>();
var amsterdam = new City("Amsterdam");
var london = new City("London");
var berlin = new City("Berlin");
var paris = new City("Paris");
var amsterdamLondon = new Road(amsterdam, london, "AMS-LON", 540);
var amsterdamBerlin = new Road(amsterdam, berlin, "AMS-BER", 660);
var amsterdamParis = new Road(amsterdam, paris, "AMS-PAR", 506);
var londonBerlin = new Road(london, berlin, "LON-BER", 1100);
var londonParis = new Road(london, paris, "LON-PAR", 470);
var berlinParis = new Road(berlin, paris, "BER-PAR", 1058);
graph
.AddVertex(amsterdam)
.AddVertex(london)
.AddVertex(berlin)
.AddVertex(paris)
.AddEdge(amsterdamLondon)
.AddEdge(amsterdamBerlin)
.AddEdge(amsterdamParis)
.AddEdge(londonBerlin)
.AddEdge(londonParis)
.AddEdge(berlinParis);
// Find the shortest path between Paris and Berlin.
var shortestPath = graph.ShortestPath(paris, berlin, r => r.Distance);
var roads = string.Join(",", shortestPath.Path.Select(r => r.Name));
var description = $"{roads} in {shortestPath.Path.Sum(p => p.Distance)} distance";
Console.WriteLine(description);
// Increase the distance between Paris and Berlin.
berlinParis.Distance = 3000;
// The shortest path is a different one now.
shortestPath = graph.ShortestPath(paris, berlin, r => r.Distance);
roads = string.Join(",", shortestPath.Path.Select(r => r.Name));
description = $"{roads} in {shortestPath.Path.Sum(p => p.Distance)} distance";
Console.WriteLine(description);
public class City(string name) : StringValueTypeVertex(name);
public class Road(City source, City target, string name, int distance) : Line<City>(source, target)
{
public string Name { get; } = name;
public int Distance { get; set; } = distance;
public override int GetHashCode() => Name.GetStableHashCode();
public override bool Equals(Line<City>? other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
if (other.GetType() != GetType()) return false;
var otherCasted = (Road)other;
return string.Equals(Name, otherCasted.Name, StringComparison.OrdinalIgnoreCase);
}
}
This gives the following result on the console.
BER-PAR in 1058 distance
AMS-PAR,AMS-BER in 1166 distance
All features
Adjacency list
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var graph = GraphFactory
.CreateNewStringArrowType()
.AddVertex("A")
.AddVertex("B")
.AddVertex("C")
.AddEdge("A", "B")
.AddEdge("A", "C")
.AddEdge("B", "C");
Console.WriteLine(graph.ToAdjacencyListString());
This will output the following adjacency matrix.
A ->B ->C
B ->C
C
Adjacency matrix
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var graph = GraphFactory
.CreateNewStringArrowType()
.AddVertex("A")
.AddVertex("B")
.AddVertex("C")
.AddEdge("A", "B")
.AddEdge("A", "C")
.AddEdge("B", "C");
Console.WriteLine(graph.ToAdjacencyMatrixString());
This will output the following adjacency matrix.
A B C
A 0 1 1
B 0 0 1
C 0 0 0
All edge paths
using MoreLinq.Extensions;
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var vertexA = new StringValueTypeVertex("A");
var vertexB = new StringValueTypeVertex("B");
var vertexC = new StringValueTypeVertex("C");
var vertexD = new StringValueTypeVertex("D");
var edgeAtoB = new StringValueTypeArrow("AB", vertexA, vertexB);
var edgeAtoC = new StringValueTypeArrow("AC", vertexA, vertexC);
var edgeBtoD = new StringValueTypeArrow("BD", vertexB, vertexD);
var edgeCtoD = new StringValueTypeArrow("CD", vertexC, vertexD);
var graph = GraphFactory
.CreateNewStringArrowType()
.AddVertex(vertexA)
.AddVertex(vertexB)
.AddVertex(vertexC)
.AddVertex(vertexD)
.AddEdge(edgeAtoB)
.AddEdge(edgeAtoC)
.AddEdge(edgeBtoD)
.AddEdge(edgeCtoD);
var allEdgePaths = graph
.AllEdgePaths(new StringValueTypeVertex("A"), new StringValueTypeVertex("D"), 10);
allEdgePaths.ForEach(Console.WriteLine);
This will output the following paths.
A->B(AB), B->D(BD)
A->C(AC), C->D(CD)
All vertex paths
using MoreLinq.Extensions;
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var vertexA = new StringValueTypeVertex("A");
var vertexB = new StringValueTypeVertex("B");
var vertexC = new StringValueTypeVertex("C");
var vertexD = new StringValueTypeVertex("D");
var edgeAtoB = new StringValueTypeArrow("AB", vertexA, vertexB);
var edgeAtoC = new StringValueTypeArrow("AC", vertexA, vertexC);
var edgeBtoD = new StringValueTypeArrow("BD", vertexB, vertexD);
var edgeCtoD = new StringValueTypeArrow("CD", vertexC, vertexD);
var graph = GraphFactory
.CreateNewStringArrowType()
.AddVertex(vertexA)
.AddVertex(vertexB)
.AddVertex(vertexC)
.AddVertex(vertexD)
.AddEdge(edgeAtoB)
.AddEdge(edgeAtoC)
.AddEdge(edgeBtoD)
.AddEdge(edgeCtoD);
var allEdgePaths = graph
.AllVertexPaths(new StringValueTypeVertex("A"), new StringValueTypeVertex("D"), 10);
allEdgePaths.ForEach(Console.WriteLine);
This will output the following paths.
A, B, D
A, C, D
Depth first search
using System.Text;
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var graph = GraphFactory
.CreateNewStringArrowType()
.AddVertex("A")
.AddVertex("B")
.AddVertex("C")
.AddVertex("D")
.AddVertex("E")
.AddVertex("F")
.AddEdge("A", "B")
.AddEdge("B", "C")
.AddEdge("C", "D")
.AddEdge("C", "E")
.AddEdge("E", "F");
var graphWalkedString = new StringBuilder();
graph.DepthFirstSearch().SetVertexCallback((_, v) => graphWalkedString.Append(v.Name)).Compute(v => string.Equals(v.Name, "D", StringComparison.OrdinalIgnoreCase));
Console.WriteLine(graphWalkedString);
This will output the following string.
ABCD
Hamiltonian property
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var graph = GraphFactory
.CreateNewStringLineType()
.AddVertex("A")
.AddVertex("B")
.AddVertex("C")
.AddVertex("D")
.AddVertex("E")
.AddVertex("F")
.AddEdge("A", "B")
.AddEdge("B", "E")
.AddEdge("E", "D")
.AddEdge("D", "F")
.AddEdge("F", "C")
.AddEdge("C", "A");
Console.WriteLine(graph.IsHamiltonian());
This will output the following boolean.
True
Hamiltonian cycles
using SharpGraph.Core;
using SharpGraph.Core.Elements.ValueTypes;
var graph = GraphFactory
.CreateNewStringLineType()
.AddVertex("A")
.AddVertex("B")
.AddVertex("C")
.AddVertex("D")
.AddVertex("E")
.AddVertex("F")
.AddEdge("A", "B")
.AddEdge("B", "E")
.AddEdge("E", "D")
.AddEdge("D", "F")
.AddEdge("F", "C")
.AddEdge("C", "A");
foreach (var cycle in graph.HamiltonianCycles())
{
Console.WriteLine(string.Join(" -> ", cycle));
}
A -> C -> F -> D -> E -> B
A -> B -> E -> D -> F -> C
B -> E -> D -> F -> C -> A
B -> A -> C -> F -> D -> E
C -> F -> D -> E -> B -> A
C -> A -> B -> E -> D -> F
D -> F -> C -> A -> B -> E
D -> E -> B -> A -> C -> F
E -> D -> F -> C -> A -> B
E -> B -> A -> C -> F -> D
F -> D -> E -> B -> A -> C
F -> C -> A -> B -> E -> D
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net9.0 is compatible. |
-
net9.0
- Newtonsoft.Json (>= 13.0.3)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on SharpGraph:
Package | Downloads |
---|---|
SharpMachineLearning
Package Description |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.4.4 | 131 | 11/17/2024 |
1.4.3 | 93 | 11/17/2024 |
1.4.2 | 85 | 11/17/2024 |
1.4.1 | 92 | 11/17/2024 |
1.4.0 | 81 | 11/17/2024 |
1.3.13 | 89 | 11/16/2024 |
1.3.12 | 89 | 11/16/2024 |
1.3.11 | 134 | 9/19/2024 |
1.3.10 | 99 | 9/19/2024 |
1.3.9 | 94 | 9/19/2024 |
1.3.8 | 784 | 9/5/2024 |
1.3.7 | 130 | 9/5/2024 |
1.3.6 | 123 | 9/5/2024 |
1.3.5 | 119 | 9/5/2024 |
1.3.4 | 111 | 9/4/2024 |
1.3.3 | 116 | 9/1/2024 |
1.3.2 | 105 | 9/1/2024 |
1.3.1 | 108 | 9/1/2024 |
1.3.0 | 182 | 2/19/2024 |
1.2.9 | 150 | 2/13/2024 |
1.2.8 | 113 | 2/13/2024 |
1.2.7 | 191 | 12/20/2023 |
1.2.6 | 120 | 12/20/2023 |
1.2.5 | 285 | 3/27/2023 |
1.2.3 | 296 | 12/22/2022 |
1.2.2 | 427 | 6/1/2022 |
1.2.1 | 425 | 5/25/2022 |
1.2.0 | 429 | 5/1/2022 |
1.1.7 | 440 | 2/16/2022 |
1.1.6 | 434 | 2/16/2022 |
1.1.5 | 438 | 2/15/2022 |
1.1.4 | 437 | 2/15/2022 |
1.1.3 | 422 | 2/15/2022 |
1.1.2 | 414 | 2/15/2022 |
1.1.1 | 437 | 2/14/2022 |
1.1.0 | 434 | 2/13/2022 |
1.0.9 | 436 | 2/13/2022 |
1.0.8 | 451 | 1/15/2022 |
1.0.7 | 284 | 12/19/2021 |
1.0.6 | 309 | 11/19/2021 |
1.0.5 | 386 | 10/10/2021 |
1.0.4 | 347 | 10/10/2021 |