Skip to content

Commit

Permalink
A lot of new additions to algs4, these are the last classes that othe…
Browse files Browse the repository at this point in the history
…r classes depends on, from now on all other classes have all their dependencies in algs4.

Adding:
- BreadthFirstPaths
- Complex
- FordFulkerson
- GrahamScan
- NFA
- SequentialSearchST
- SymbolGraph
  • Loading branch information
mina-asham committed May 9, 2015
1 parent 5e0833f commit ec288b1
Show file tree
Hide file tree
Showing 8 changed files with 1,411 additions and 0 deletions.
7 changes: 7 additions & 0 deletions algs4/algs4.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,10 @@
<Compile Include="algs4\Bag.cs" />
<Compile Include="algs4\BellmanFordSP.cs" />
<Compile Include="algs4\BinaryDump.cs" />
<Compile Include="algs4\BreadthFirthPaths.cs" />
<Compile Include="algs4\BST.cs" />
<Compile Include="algs4\Cat.cs" />
<Compile Include="algs4\Complex.cs" />
<Compile Include="algs4\Count.cs" />
<Compile Include="algs4\Counter.cs" />
<Compile Include="algs4\DepthFirstOrder.cs" />
Expand All @@ -62,23 +64,28 @@
<Compile Include="algs4\EdgeWeightedGraph.cs" />
<Compile Include="algs4\FlowEdge.cs" />
<Compile Include="algs4\FlowNetwork.cs" />
<Compile Include="algs4\FordFulkerson.cs" />
<Compile Include="algs4\GrahamScan.cs" />
<Compile Include="algs4\Graph.cs" />
<Compile Include="algs4\GraphGenerator.cs" />
<Compile Include="algs4\IndexMinPQ.cs" />
<Compile Include="algs4\Interval1D.cs" />
<Compile Include="algs4\Interval2D.cs" />
<Compile Include="algs4\MinPQ.cs" />
<Compile Include="algs4\NFA.cs" />
<Compile Include="algs4\Particle.cs" />
<Compile Include="algs4\PictureDump.cs" />
<Compile Include="algs4\Point2D.cs" />
<Compile Include="algs4\Queue.cs" />
<Compile Include="algs4\RedBlackBST.cs" />
<Compile Include="algs4\SequentialSearchST.cs" />
<Compile Include="algs4\Set.cs" />
<Compile Include="algs4\ST.cs" />
<Compile Include="algs4\Stack.cs" />
<Compile Include="algs4\StaticSETofInts.cs" />
<Compile Include="algs4\SuffixArray.cs" />
<Compile Include="algs4\SymbolDigraph.cs" />
<Compile Include="algs4\SymbolGraph.cs" />
<Compile Include="algs4\TopM.cs" />
<Compile Include="algs4\Topological.cs" />
<Compile Include="algs4\Transaction.cs" />
Expand Down
259 changes: 259 additions & 0 deletions algs4/algs4/BreadthFirthPaths.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
using System.Collections.Generic;
using algs4.stdlib;

namespace algs4.algs4
{
public class BreadthFirstPaths
{
private const int Infinity = int.MaxValue;

/// <summary>
/// marked[v] = is there an s-v path
/// </summary>
private readonly bool[] _marked;

/// <summary>
/// edgeTo[v] = previous edge on shortest s-v path
/// </summary>
private readonly int[] _edgeTo;

/// <summary>
/// distTo[v] = number of edges shortest s-v path
/// </summary>
private readonly int[] _distTo;

/// <summary>
/// Computes the shortest path between the source vertex s
/// and every other vertex in the graph G.
/// </summary>
/// <param name="g">the graph</param>
/// <param name="s">the source vertex</param>
public BreadthFirstPaths(Graph g, int s)
{
_marked = new bool[g.V()];
_distTo = new int[g.V()];
_edgeTo = new int[g.V()];
BFS(g, s);
}

/// <summary>
/// Computes the shortest path between any one of the source vertices in sources
/// and every other vertex in graph G.
/// </summary>
/// <param name="g">the graph</param>
/// <param name="sources">the source vertices</param>
public BreadthFirstPaths(Graph g, IEnumerable<int> sources)
{
_marked = new bool[g.V()];
_distTo = new int[g.V()];
_edgeTo = new int[g.V()];
for (int v = 0; v < g.V(); v++)
{
_distTo[v] = Infinity;
}
BFS(g, sources);
}

/// <summary>
/// Breadth-first search from a single source
/// </summary>
/// <param name="g"></param>
/// <param name="s"></param>
private void BFS(Graph g, int s)
{
Queue<int> q = new Queue<int>();
for (int v = 0; v < g.V(); v++)
{
_distTo[v] = Infinity;
}
_distTo[s] = 0;
_marked[s] = true;
q.Enqueue(s);

while (!q.IsEmpty())
{
int v = q.Dequeue();
foreach (int w in g.Adj(v))
{
if (!_marked[w])
{
_edgeTo[w] = v;
_distTo[w] = _distTo[v] + 1;
_marked[w] = true;
q.Enqueue(w);
}
}
}
}

/// <summary>
/// Breadth-first search from multiple sources
/// </summary>
/// <param name="g"></param>
/// <param name="sources"></param>
private void BFS(Graph g, IEnumerable<int> sources)
{
Queue<int> q = new Queue<int>();
foreach (int s in sources)
{
_marked[s] = true;
_distTo[s] = 0;
q.Enqueue(s);
}
while (!q.IsEmpty())
{
int v = q.Dequeue();
foreach (int w in g.Adj(v))
{
if (!_marked[w])
{
_edgeTo[w] = v;
_distTo[w] = _distTo[v] + 1;
_marked[w] = true;
q.Enqueue(w);
}
}
}
}

/// <summary>
/// Is there a path between the source vertex s (or sources) and vertex v?
/// </summary>
/// <param name="v">the vertex</param>
/// <returns>true if there is a path, and false otherwise</returns>
public bool HasPathTo(int v)
{
return _marked[v];
}

/// <summary>
/// Returns the number of edges in a shortest path between the source vertex s
/// (or sources) and vertex v?
/// </summary>
/// <param name="v">the vertex</param>
/// <returns>the number of edges in a shortest path</returns>
public int DistTo(int v)
{
return _distTo[v];
}

/// <summary>
/// Returns a shortest path between the source vertex s (or sources)
/// and v, or null if no such path.
/// </summary>
/// <param name="v">the vertex</param>
/// <returns>the sequence of vertices on a shortest path, as an IEnumerable</returns>
public IEnumerable<int> PathTo(int v)
{
if (!HasPathTo(v))
{
return null;
}
Stack<int> path = new Stack<int>();
int x;
for (x = v; _distTo[x] != 0; x = _edgeTo[x])
{
path.Push(x);
}
path.Push(x);
return path;
}

/// <summary>
/// Check optimality conditions for single source
/// </summary>
/// <param name="g"></param>
/// <param name="s"></param>
/// <returns></returns>
public bool Check(Graph g, int s)
{
// check that the distance of s = 0
if (_distTo[s] != 0)
{
StdOut.PrintLn("distance of source " + s + " to itself = " + _distTo[s]);
return false;
}

// check that for each edge v-w dist[w] <= dist[v] + 1
// provided v is reachable from s
for (int v = 0; v < g.V(); v++)
{
foreach (int w in g.Adj(v))
{
if (HasPathTo(v) != HasPathTo(w))
{
StdOut.PrintLn("edge " + v + "-" + w);
StdOut.PrintLn("hasPathTo(" + v + ") = " + HasPathTo(v));
StdOut.PrintLn("hasPathTo(" + w + ") = " + HasPathTo(w));
return false;
}
if (HasPathTo(v) && (_distTo[w] > _distTo[v] + 1))
{
StdOut.PrintLn("edge " + v + "-" + w);
StdOut.PrintLn("distTo[" + v + "] = " + _distTo[v]);
StdOut.PrintLn("distTo[" + w + "] = " + _distTo[w]);
return false;
}
}
}

// check that v = edgeTo[w] satisfies distTo[w] + distTo[v] + 1
// provided v is reachable from s
for (int w = 0; w < g.V(); w++)
{
if (!HasPathTo(w) || w == s)
{
continue;
}
int v = _edgeTo[w];
if (_distTo[w] != _distTo[v] + 1)
{
StdOut.PrintLn("shortest path edge " + v + "-" + w);
StdOut.PrintLn("distTo[" + v + "] = " + _distTo[v]);
StdOut.PrintLn("distTo[" + w + "] = " + _distTo[w]);
return false;
}
}

return true;
}

/// <summary>
/// Unit tests the BreadthFirstPaths data type.
/// </summary>
/// <param name="args"></param>
public static void RunMain(string[] args)
{
In input = new In(args[0]);
Graph g = new Graph(input);

int s = int.Parse(args[1]);
BreadthFirstPaths bfs = new BreadthFirstPaths(g, s);

for (int v = 0; v < g.V(); v++)
{
if (bfs.HasPathTo(v))
{
StdOut.PrintF("{0} to {1} ({2}): ", s, v, bfs.DistTo(v));
foreach (int x in bfs.PathTo(v))
{
if (x == s)
{
StdOut.Print(x);
}
else
{
StdOut.Print("-" + x);
}
}
StdOut.PrintLn();
}

else
{
StdOut.PrintF("{0} to {1} (-): not connected\n", s, v);
}
}
}
}
}
Loading

0 comments on commit ec288b1

Please sign in to comment.