// Copyright (c) CypherCore All rights reserved. // Licensed under the GNU GENERAL PUBLIC LICENSE. See LICENSE file in the project root for full license information. using System; using System.Collections.Generic; using System.Text; namespace Framework.Collections { /// /// The EdgeWeightedDigrpah class represents an edge-weighted directed graph of vertices named 0 through V-1, where each directed edge /// is of type DirectedEdge and has real-valued weight. /// /// EdgeWeightedDigraph class from Princeton University's Java Algorithms public class EdgeWeightedDigraph { private readonly LinkedList[] _adjacent; /// /// Constructs an empty edge-weighted digraph with the specified number of vertices and 0 edges /// /// Number of vertices in the Graph public EdgeWeightedDigraph(int vertices) { NumberOfVertices = vertices; NumberOfEdges = 0; _adjacent = new LinkedList[NumberOfVertices]; for (int v = 0; v < NumberOfVertices; v++) { _adjacent[v] = new LinkedList(); } } /// /// The number of vertices in the edge-weighted digraph /// public int NumberOfVertices { get; private set; } /// /// The number of edges in the edge-weighted digraph /// public int NumberOfEdges { get; private set; } /// /// Adds the specified directed edge to the edge-weighted digraph /// /// The DirectedEdge to add /// DirectedEdge cannot be null public void AddEdge(DirectedEdge edge) { if (edge == null) { throw new ArgumentNullException("edge", "DirectedEdge cannot be null"); } _adjacent[edge.From].AddLast(edge); } /// /// Returns an IEnumerable of the DirectedEdges incident from the specified vertex /// /// The vertex to find incident DirectedEdges from /// IEnumerable of the DirectedEdges incident from the specified vertex public IEnumerable Adjacent(int vertex) { return _adjacent[vertex]; } /// /// Returns an IEnumerable of all directed edges in the edge-weighted digraph /// /// IEnumerable of of all directed edges in the edge-weighted digraph public IEnumerable Edges() { for (int v = 0; v < NumberOfVertices; v++) { foreach (DirectedEdge edge in _adjacent[v]) { yield return edge; } } } /// /// Returns the number of directed edges incident from the specified vertex /// This is known as the outdegree of the vertex /// /// The vertex to find find the outdegree of /// The number of directed edges incident from the specified vertex public int OutDegree(int vertex) { return _adjacent[vertex].Count; } /// /// Returns a string that represents the current edge-weighted digraph /// /// /// A string that represents the current edge-weighted digraph /// public override string ToString() { var formattedString = new StringBuilder(); formattedString.AppendFormat("{0} vertices, {1} edges {2}", NumberOfVertices, NumberOfEdges, Environment.NewLine); for (int v = 0; v < NumberOfVertices; v++) { formattedString.AppendFormat("{0}: ", v); foreach (DirectedEdge edge in _adjacent[v]) { formattedString.AppendFormat("{0} ", edge.To); } formattedString.AppendLine(); } return formattedString.ToString(); } } /// /// The DirectedEdge class represents a weighted edge in an edge-weighted directed graph. /// /// DirectedEdge class from Princeton University's Java Algorithms public class DirectedEdge { /// /// Constructs a directed edge from one specified vertex to another with the given weight /// /// The start vertex /// The destination vertex /// The weight of the DirectedEdge public DirectedEdge(uint from, uint to, double weight) { From = from; To = to; Weight = weight; } /// /// Returns the destination vertex of the DirectedEdge /// public uint From { get; private set; } /// /// Returns the start vertex of the DirectedEdge /// public uint To { get; private set; } /// /// Returns the weight of the DirectedEdge /// public double Weight { get; private set; } /// /// Returns a string that represents the current DirectedEdge /// /// /// A string that represents the current DirectedEdge /// public override string ToString() { return $"From: {From}, To: {To}, Weight: {Weight}"; } } }