Skip to content
Snippets Groups Projects
Commit 516f6c22 authored by Paul Nitzke's avatar Paul Nitzke
Browse files

Fix: Change backing datastructure of graphs

* Replaces List with Dictionary with the node index being the key and
  the GraphNode (also containing the index) the value
* This dramatically speeds up the MatrixMarket string to graph
  transformation in MatrixMarketReader since adding edges and in
  particular nodes to the graph is much faster
* This is because the nodes are added to the graph as needes i.e. the
  graph searches for them in the existing node list and if not present
  adds them. This search is significant the larger the graph gets. This
  is also why the transformation of larger graphs took exponentially
  longer.
parent 11c60e6e
Branches
No related tags found
1 merge request!40Fix: Change backing datastructure of graphs
......@@ -11,7 +11,7 @@ namespace SparseTransform.DataStructures
/// <remarks>
/// In the matrix representation this is the lower left triangle since <see cref="AdjacencyGraph"/> represents symmetric matrices.
/// </remarks>
private List<GraphNode> _nodes;
private Dictionary<int, GraphNode> _nodes;
/// <summary>
/// Number of nodes
......@@ -58,7 +58,7 @@ namespace SparseTransform.DataStructures
List<int> colors = new List<int>();
if (Colored)
{
foreach (GraphNode node in _nodes)
foreach (GraphNode node in _nodes.Values)
{
int color = node.Color;
// Do not check for != 0 since we already know everything here is colored
......@@ -79,7 +79,7 @@ namespace SparseTransform.DataStructures
/// </summary>
public AdjacencyGraph()
{
_nodes = new List<GraphNode>();
_nodes = new Dictionary<int, GraphNode>();
}
public void AddEdge(int i, int j)
......@@ -106,14 +106,16 @@ namespace SparseTransform.DataStructures
/// <returns>GraphNode that was just added</returns>
private GraphNode AddNode(int index)
{
GraphNode? n = FindNodeByIndex(index);
if (n is null)
if(!_nodes.ContainsKey(index))
{
n = new GraphNode(index);
_nodes.Add(n);
GraphNode n = new GraphNode(index);
_nodes[index] = n;
return n;
}
return n;
else
{
return _nodes[index];
}
}
/// <summary>
......@@ -122,7 +124,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the nodes</returns>
public IEnumerable<GraphNode> GetNodes()
{
List<GraphNode> nodes = new List<GraphNode>(_nodes);
List<GraphNode> nodes = new List<GraphNode>(_nodes.Values);
nodes.Sort((x, y) =>
{
if (x.Index < y.Index)
......@@ -133,23 +135,13 @@ namespace SparseTransform.DataStructures
return nodes as IEnumerable<GraphNode>;
}
/// <summary>
/// Finds a node by index. Returns null if not found.
/// </summary>
/// <param name="index">index to search for</param>
/// <returns>node if found otherwise null</returns>
private GraphNode? FindNodeByIndex(int index)
{
return _nodes.Find(n => n.Index == index);
}
public IntegerMatrix? ToSeedMatrix(int rows)
{
IntegerMatrix seed = new IntegerMatrix(rows, ColorsUsed);
// This only works for row OR column partitions not mixed
if (Colored)
{
foreach (GraphNode node in _nodes)
foreach (GraphNode node in _nodes.Values)
{
// The row index is the column index of the element
// The column index = binary vector index is the color
......
......@@ -14,7 +14,7 @@ namespace SparseTransform.DataStructures
/// <remarks>
/// Uses "left" in the name since ColPack does it too and in visualizations this is where the row nodes are often pictured.
/// </remarks>
private List<GraphNode> _leftNodes;
private Dictionary<int, GraphNode> _leftNodes;
/// <summary>
/// Stores nodes representing columns in the matrix representation.
......@@ -22,7 +22,7 @@ namespace SparseTransform.DataStructures
/// <remarks>
/// Uses "right" in the name since ColPack does this too and in visualizations this is where the row nodes are often pictured.
/// </remarks>
private List<GraphNode> _rightNodes;
private Dictionary<int, GraphNode> _rightNodes;
/// <summary>
/// Number of nodes on the left side
......@@ -101,7 +101,7 @@ namespace SparseTransform.DataStructures
List<int> colors = new List<int>();
if (LeftColored)
{
foreach (GraphNode node in _leftNodes)
foreach (GraphNode node in _leftNodes.Values)
{
int color = node.Color;
// Do not check for != 0 since we already know everything here is colored
......@@ -113,7 +113,7 @@ namespace SparseTransform.DataStructures
}
if (RightColored)
{
foreach (GraphNode node in _rightNodes)
foreach (GraphNode node in _rightNodes.Values)
{
int color = node.Color;
// Do not check for != 0 since we already know everything here is colored
......@@ -136,8 +136,8 @@ namespace SparseTransform.DataStructures
/// </summary>
public BipartiteGraph()
{
_leftNodes = new List<GraphNode>();
_rightNodes = new List<GraphNode>();
_leftNodes = new Dictionary<int, GraphNode>();
_rightNodes = new Dictionary<int, GraphNode>();
}
/// <summary>
......@@ -165,14 +165,16 @@ namespace SparseTransform.DataStructures
/// <param name="index">index to create node for</param>
private GraphNode AddLeftNode(int index)
{
GraphNode? n = FindLeftNodeByIndex(index);
if (n is null)
if(!_leftNodes.ContainsKey(index))
{
n = new GraphNode(index);
_leftNodes.Add(n);
GraphNode n = new GraphNode(index);
_leftNodes[index] = n;
return n;
}
return n;
else
{
return _leftNodes[index];
}
}
/// <summary>
......@@ -181,54 +183,16 @@ namespace SparseTransform.DataStructures
/// <param name="index">index to create node for</param>
private GraphNode AddRightNode(int index)
{
GraphNode? n = FindRightNodeByIndex(index);
if (n is null)
if(!_rightNodes.ContainsKey(index))
{
n = new GraphNode(index);
_rightNodes.Add(n);
GraphNode n = new GraphNode(index);
_rightNodes[index] = n;
return n;
}
return n;
}
/// <summary>
/// Checks if node exists on the left side
/// </summary>
/// <param name="index">index to check for</param>
/// <returns>true if node was found</returns>
private bool ContainsLeftNode(int index)
{
return FindLeftNodeByIndex(index) is GraphNode;
}
/// <summary>
/// Checks if node exists on the right side
/// </summary>
/// <param name="index">index to check for</param>
/// <returns>true if node was found</returns>
private bool ContainsRightNode(int index)
{
return FindRightNodeByIndex(index) is GraphNode;
}
/// <summary>
/// Finds a node on the left side by index. Returns null if not found.
/// </summary>
/// <param name="index">index to search for</param>
/// <returns>GraphNode if found, null if not</returns>
private GraphNode? FindLeftNodeByIndex(int index)
{
return _leftNodes.Find(n => n.Index == index);
}
/// <summary>
/// Finds a node on the right side by index. Returns null if not found.
/// </summary>
/// <param name="index">index to search for</param>
/// <returns>GraphNode if found, null if not</returns>
private GraphNode? FindRightNodeByIndex(int index)
{
return _rightNodes.Find(n => n.Index == index);
else
{
return _rightNodes[index];
}
}
/// <summary>
......@@ -237,7 +201,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the left nodes</returns>
public IEnumerable<GraphNode> GetLeftNodes()
{
List<GraphNode> leftNodes = new List<GraphNode>(_leftNodes);
List<GraphNode> leftNodes = new List<GraphNode>(_leftNodes.Values);
leftNodes.Sort((x, y) =>
{
if (x.Index < y.Index)
......@@ -254,7 +218,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the right nodes</returns>
public IEnumerable<GraphNode> GetRightNodes()
{
List<GraphNode> rightNodes = new List<GraphNode>(_rightNodes);
List<GraphNode> rightNodes = new List<GraphNode>(_rightNodes.Values);
rightNodes.Sort((x, y) =>
{
if (x.Index < y.Index)
......@@ -277,7 +241,7 @@ namespace SparseTransform.DataStructures
// This only works for row OR column partitions not mixed
if (LeftColored)
{
foreach (GraphNode node in _leftNodes)
foreach (GraphNode node in _leftNodes.Values)
{
// The row index is the column index of the element
// The column index = binary vector index is the color
......@@ -288,7 +252,7 @@ namespace SparseTransform.DataStructures
}
else if (RightColored)
{
foreach (GraphNode node in _rightNodes)
foreach (GraphNode node in _rightNodes.Values)
{
// The row index is the row index of the element
seed[node.Index - 1, node.Color - 1] = 1;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment