Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Add customized edge weight support for graphs. #78

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
Loading
from
18 changes: 16 additions & 2 deletions 18 Algorithms/Graphs/DijkstraShortestPaths.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,20 @@ public class DijkstraShortestPaths<TGraph, TVertex>
private readonly TGraph _graph;
private readonly TVertex _source;

private long GetEdgeWeight(IEdge<TVertex> edge)
{
// TODO: Change Dijkstra algorithm to support edge weights that are not Int64 compatible.
if (edge.IsWeighted)
{
var e = edge as WeightedEdge<TVertex>;
return e.Weight;
}
else
{
return 1;
}
}

public DijkstraShortestPaths(TGraph graph, TVertex source)
{
if (graph == null)
Expand All @@ -38,7 +52,7 @@ public DijkstraShortestPaths(TGraph graph, TVertex source)
if (!graph.HasVertex(source))
throw new ArgumentException("The source vertex doesn't belong to graph.");

if (graph.Edges.Any(edge => edge.Weight < 0))
if (graph.Edges.Any(edge => GetEdgeWeight(edge) < 0))
throw new ArgumentException("Negative edge weight detected.");

_graph = graph;
Expand All @@ -62,7 +76,7 @@ private void _dijkstra()
foreach (var outgoingEdge in outgoingEdges)
{
var adjacentIndex = _nodesToIndices[outgoingEdge.Destination];
var delta = _distances[currentVertexIndex] != Infinity ? _distances[currentVertexIndex] + outgoingEdge.Weight : Infinity;
var delta = _distances[currentVertexIndex] != Infinity ? _distances[currentVertexIndex] + GetEdgeWeight(outgoingEdge) : Infinity;

if (delta < _distances[adjacentIndex])
{
Expand Down
1 change: 0 additions & 1 deletion 1 DataStructures/Graphs/CliqueGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,6 @@ static V Pick<V>(IEnumerable<V> Set)
enumerator.Dispose();
return ret;
}

}

internal class UnordererPair<T> : Tuple<T, T>, IEquatable<UnordererPair<T>> where T : IEquatable<T>
Expand Down
47 changes: 25 additions & 22 deletions 47 DataStructures/Graphs/DirectedWeightedDenseGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,18 @@ namespace DataStructures.Graphs
/// <summary>
/// This class represents the graph as an adjacency-matrix (two dimensional integer array).
/// </summary>
public class DirectedWeightedDenseGraph<T> : DirectedDenseGraph<T>, IWeightedGraph<T> where T : IComparable<T>
public class DirectedWeightedDenseGraph<T, W> : DirectedDenseGraph<T>, IWeightedGraph<T, W> where T : IComparable<T> where W : IComparable<W>
{
/// <summary>
/// INSTANCE VARIABLES
/// </summary>
private const long EMPTY_EDGE_SLOT = 0;
private static readonly W EMPTY_EDGE_SLOT = default(W);
private const object EMPTY_VERTEX_SLOT = (object)null;

// Store edges and their weights as integers.
// Any edge with a value of zero means it doesn't exist. Otherwise, it exist with a specific weight value.
// Default value for positive edges is 1.
protected new long[,] _adjacencyMatrix { get; set; }
protected new W[,] _adjacencyMatrix { get; set; }


/// <summary>
Expand All @@ -47,7 +47,7 @@ public DirectedWeightedDenseGraph(uint capacity = 10)
_verticesCapacity = (int)capacity;

_vertices = new ArrayList<object>(_verticesCapacity);
_adjacencyMatrix = new long[_verticesCapacity, _verticesCapacity];
_adjacencyMatrix = new W[_verticesCapacity, _verticesCapacity];
_adjacencyMatrix.Populate(rows: _verticesCapacity, columns: _verticesCapacity, defaultValue: EMPTY_EDGE_SLOT);
}

Expand All @@ -57,13 +57,13 @@ public DirectedWeightedDenseGraph(uint capacity = 10)
/// </summary>
protected override bool _doesEdgeExist(int source, int destination)
{
return (_adjacencyMatrix[source, destination] != EMPTY_EDGE_SLOT);
return (EMPTY_EDGE_SLOT.Equals(_adjacencyMatrix[source, destination]));
}

/// <summary>
/// Helper function. Gets the weight of a directed edge.
/// </summary>
private long _getEdgeWeight(int source, int destination)
private W _getEdgeWeight(int source, int destination)
{
return _adjacencyMatrix[source, destination];
}
Expand All @@ -80,7 +80,7 @@ public override bool IsWeighted
/// <summary>
/// An enumerable collection of all weighted directed edges in graph.
/// </summary>
public virtual IEnumerable<WeightedEdge<T>> Edges
public new virtual IEnumerable<WeightedEdge<T, W>> Edges
{
get
{
Expand All @@ -93,7 +93,7 @@ public virtual IEnumerable<WeightedEdge<T>> Edges
/// <summary>
/// Get all incoming unweighted edges to a vertex.
/// </summary>
public virtual IEnumerable<WeightedEdge<T>> IncomingEdges(T vertex)
public new virtual IEnumerable<WeightedEdge<T, W>> IncomingEdges(T vertex)
{
if (!HasVertex(vertex))
throw new KeyNotFoundException("Vertex doesn't belong to graph.");
Expand All @@ -104,7 +104,7 @@ public virtual IEnumerable<WeightedEdge<T>> IncomingEdges(T vertex)
{
if (_vertices[adjacent] != null && _doesEdgeExist(adjacent, source))
{
yield return (new WeightedEdge<T>(
yield return (new WeightedEdge<T, W>(
(T)_vertices[adjacent], // from
vertex, // to
_getEdgeWeight(source, adjacent) // weight
Expand All @@ -116,7 +116,7 @@ public virtual IEnumerable<WeightedEdge<T>> IncomingEdges(T vertex)
/// <summary>
/// Get all outgoing unweighted edges from a vertex.
/// </summary>
public virtual IEnumerable<WeightedEdge<T>> OutgoingEdges(T vertex)
public new virtual IEnumerable<WeightedEdge<T, W>> OutgoingEdges(T vertex)
{
if (!HasVertex(vertex))
throw new KeyNotFoundException("Vertex doesn't belong to graph.");
Expand All @@ -127,7 +127,7 @@ public virtual IEnumerable<WeightedEdge<T>> OutgoingEdges(T vertex)
{
if (_vertices[adjacent] != null && _doesEdgeExist(source, adjacent))
{
yield return (new WeightedEdge<T>(
yield return (new WeightedEdge<T, W>(
vertex, // from
(T)_vertices[adjacent], // to
_getEdgeWeight(source, adjacent) // weight
Expand All @@ -149,10 +149,10 @@ public virtual IEnumerable<WeightedEdge<T>> OutgoingEdges(T vertex)
/// <summary>
/// Connects two vertices together with a weight, in the direction: first->second.
/// </summary>
public virtual bool AddEdge(T source, T destination, long weight)
public virtual bool AddEdge(T source, T destination, W weight)
{
// Return if the weight is equals to the empty edge value
if (weight == EMPTY_EDGE_SLOT)
if (EMPTY_EDGE_SLOT.Equals(weight))
return false;

// Get indices of vertices
Expand Down Expand Up @@ -199,10 +199,10 @@ public override bool RemoveEdge(T source, T destination)
/// <summary>
/// Updates the edge weight from source to destination.
/// </summary>
public virtual bool UpdateEdgeWeight(T source, T destination, long weight)
public virtual bool UpdateEdgeWeight(T source, T destination, W weight)
{
// Return if the weight is equals to the empty edge value
if (weight == EMPTY_EDGE_SLOT)
if (EMPTY_EDGE_SLOT.Equals(weight))
return false;

// Get indices of vertices
Expand Down Expand Up @@ -271,7 +271,7 @@ public override bool RemoveVertex(T vertex)
/// <summary>
/// Get edge object from source to destination.
/// </summary>
public virtual WeightedEdge<T> GetEdge(T source, T destination)
public virtual WeightedEdge<T, W> GetEdge(T source, T destination)
{
// Get indices of vertices
int srcIndex = _vertices.IndexOf(source);
Expand All @@ -283,26 +283,26 @@ public virtual WeightedEdge<T> GetEdge(T source, T destination)
if (!_doesEdgeExist(srcIndex, dstIndex))
throw new Exception("Edge doesn't exist.");

return (new WeightedEdge<T>(source, destination, _getEdgeWeight(srcIndex, dstIndex)));
return (new WeightedEdge<T, W>(source, destination, _getEdgeWeight(srcIndex, dstIndex)));
}

/// <summary>
/// Returns the edge weight from source to destination.
/// </summary>
public virtual long GetEdgeWeight(T source, T destination)
public virtual W GetEdgeWeight(T source, T destination)
{
return GetEdge(source, destination).Weight;
}

/// <summary>
/// Returns the neighbours of a vertex as a dictionary of nodes-to-weights.
/// </summary>
public virtual Dictionary<T, long> NeighboursMap(T vertex)
public virtual Dictionary<T, W> NeighboursMap(T vertex)
{
if (!HasVertex(vertex))
return null;

var neighbors = new Dictionary<T, long>();
var neighbors = new Dictionary<T, W>();
int source = _vertices.IndexOf(vertex);

// Check existence of vertex
Expand Down Expand Up @@ -351,11 +351,14 @@ public override void Clear()
_edgesCount = 0;
_verticesCount = 0;
_vertices = new ArrayList<object>(_verticesCapacity);
_adjacencyMatrix = new long[_verticesCapacity, _verticesCapacity];
_adjacencyMatrix = new W[_verticesCapacity, _verticesCapacity];
_adjacencyMatrix.Populate(rows: _verticesCapacity, columns: _verticesCapacity, defaultValue: EMPTY_EDGE_SLOT);
}

}

public class DirectedWeightedDenseGraph<T> : DirectedWeightedDenseGraph<T, Int64>, IWeightedGraph<T> where T : IComparable<T>
{
public new WeightedEdge<T> GetEdge(T source, T destination) => base.GetEdge(source, destination).ToSimpleEdge();
}
}

Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.