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
No related branches found
No related tags found
1 merge request!40Fix: Change backing datastructure of graphs
...@@ -11,7 +11,7 @@ namespace SparseTransform.DataStructures ...@@ -11,7 +11,7 @@ namespace SparseTransform.DataStructures
/// <remarks> /// <remarks>
/// In the matrix representation this is the lower left triangle since <see cref="AdjacencyGraph"/> represents symmetric matrices. /// In the matrix representation this is the lower left triangle since <see cref="AdjacencyGraph"/> represents symmetric matrices.
/// </remarks> /// </remarks>
private List<GraphNode> _nodes; private Dictionary<int, GraphNode> _nodes;
/// <summary> /// <summary>
/// Number of nodes /// Number of nodes
...@@ -58,7 +58,7 @@ namespace SparseTransform.DataStructures ...@@ -58,7 +58,7 @@ namespace SparseTransform.DataStructures
List<int> colors = new List<int>(); List<int> colors = new List<int>();
if (Colored) if (Colored)
{ {
foreach (GraphNode node in _nodes) foreach (GraphNode node in _nodes.Values)
{ {
int color = node.Color; int color = node.Color;
// Do not check for != 0 since we already know everything here is colored // Do not check for != 0 since we already know everything here is colored
...@@ -79,7 +79,7 @@ namespace SparseTransform.DataStructures ...@@ -79,7 +79,7 @@ namespace SparseTransform.DataStructures
/// </summary> /// </summary>
public AdjacencyGraph() public AdjacencyGraph()
{ {
_nodes = new List<GraphNode>(); _nodes = new Dictionary<int, GraphNode>();
} }
public void AddEdge(int i, int j) public void AddEdge(int i, int j)
...@@ -106,14 +106,16 @@ namespace SparseTransform.DataStructures ...@@ -106,14 +106,16 @@ namespace SparseTransform.DataStructures
/// <returns>GraphNode that was just added</returns> /// <returns>GraphNode that was just added</returns>
private GraphNode AddNode(int index) private GraphNode AddNode(int index)
{ {
GraphNode? n = FindNodeByIndex(index); if(!_nodes.ContainsKey(index))
if (n is null)
{ {
n = new GraphNode(index); GraphNode n = new GraphNode(index);
_nodes.Add(n); _nodes[index] = n;
return n; return n;
} }
return n; else
{
return _nodes[index];
}
} }
/// <summary> /// <summary>
...@@ -122,7 +124,7 @@ namespace SparseTransform.DataStructures ...@@ -122,7 +124,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the nodes</returns> /// <returns>IEnumerable for the nodes</returns>
public IEnumerable<GraphNode> GetNodes() public IEnumerable<GraphNode> GetNodes()
{ {
List<GraphNode> nodes = new List<GraphNode>(_nodes); List<GraphNode> nodes = new List<GraphNode>(_nodes.Values);
nodes.Sort((x, y) => nodes.Sort((x, y) =>
{ {
if (x.Index < y.Index) if (x.Index < y.Index)
...@@ -133,23 +135,13 @@ namespace SparseTransform.DataStructures ...@@ -133,23 +135,13 @@ namespace SparseTransform.DataStructures
return nodes as IEnumerable<GraphNode>; 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) public IntegerMatrix? ToSeedMatrix(int rows)
{ {
IntegerMatrix seed = new IntegerMatrix(rows, ColorsUsed); IntegerMatrix seed = new IntegerMatrix(rows, ColorsUsed);
// This only works for row OR column partitions not mixed // This only works for row OR column partitions not mixed
if (Colored) if (Colored)
{ {
foreach (GraphNode node in _nodes) foreach (GraphNode node in _nodes.Values)
{ {
// The row index is the column index of the element // The row index is the column index of the element
// The column index = binary vector index is the color // The column index = binary vector index is the color
......
...@@ -14,7 +14,7 @@ namespace SparseTransform.DataStructures ...@@ -14,7 +14,7 @@ namespace SparseTransform.DataStructures
/// <remarks> /// <remarks>
/// Uses "left" in the name since ColPack does it too and in visualizations this is where the row nodes are often pictured. /// Uses "left" in the name since ColPack does it too and in visualizations this is where the row nodes are often pictured.
/// </remarks> /// </remarks>
private List<GraphNode> _leftNodes; private Dictionary<int, GraphNode> _leftNodes;
/// <summary> /// <summary>
/// Stores nodes representing columns in the matrix representation. /// Stores nodes representing columns in the matrix representation.
...@@ -22,7 +22,7 @@ namespace SparseTransform.DataStructures ...@@ -22,7 +22,7 @@ namespace SparseTransform.DataStructures
/// <remarks> /// <remarks>
/// Uses "right" in the name since ColPack does this too and in visualizations this is where the row nodes are often pictured. /// Uses "right" in the name since ColPack does this too and in visualizations this is where the row nodes are often pictured.
/// </remarks> /// </remarks>
private List<GraphNode> _rightNodes; private Dictionary<int, GraphNode> _rightNodes;
/// <summary> /// <summary>
/// Number of nodes on the left side /// Number of nodes on the left side
...@@ -101,7 +101,7 @@ namespace SparseTransform.DataStructures ...@@ -101,7 +101,7 @@ namespace SparseTransform.DataStructures
List<int> colors = new List<int>(); List<int> colors = new List<int>();
if (LeftColored) if (LeftColored)
{ {
foreach (GraphNode node in _leftNodes) foreach (GraphNode node in _leftNodes.Values)
{ {
int color = node.Color; int color = node.Color;
// Do not check for != 0 since we already know everything here is colored // Do not check for != 0 since we already know everything here is colored
...@@ -113,7 +113,7 @@ namespace SparseTransform.DataStructures ...@@ -113,7 +113,7 @@ namespace SparseTransform.DataStructures
} }
if (RightColored) if (RightColored)
{ {
foreach (GraphNode node in _rightNodes) foreach (GraphNode node in _rightNodes.Values)
{ {
int color = node.Color; int color = node.Color;
// Do not check for != 0 since we already know everything here is colored // Do not check for != 0 since we already know everything here is colored
...@@ -136,8 +136,8 @@ namespace SparseTransform.DataStructures ...@@ -136,8 +136,8 @@ namespace SparseTransform.DataStructures
/// </summary> /// </summary>
public BipartiteGraph() public BipartiteGraph()
{ {
_leftNodes = new List<GraphNode>(); _leftNodes = new Dictionary<int, GraphNode>();
_rightNodes = new List<GraphNode>(); _rightNodes = new Dictionary<int, GraphNode>();
} }
/// <summary> /// <summary>
...@@ -165,14 +165,16 @@ namespace SparseTransform.DataStructures ...@@ -165,14 +165,16 @@ namespace SparseTransform.DataStructures
/// <param name="index">index to create node for</param> /// <param name="index">index to create node for</param>
private GraphNode AddLeftNode(int index) private GraphNode AddLeftNode(int index)
{ {
GraphNode? n = FindLeftNodeByIndex(index); if(!_leftNodes.ContainsKey(index))
if (n is null)
{ {
n = new GraphNode(index); GraphNode n = new GraphNode(index);
_leftNodes.Add(n); _leftNodes[index] = n;
return n; return n;
} }
return n; else
{
return _leftNodes[index];
}
} }
/// <summary> /// <summary>
...@@ -181,54 +183,16 @@ namespace SparseTransform.DataStructures ...@@ -181,54 +183,16 @@ namespace SparseTransform.DataStructures
/// <param name="index">index to create node for</param> /// <param name="index">index to create node for</param>
private GraphNode AddRightNode(int index) private GraphNode AddRightNode(int index)
{ {
GraphNode? n = FindRightNodeByIndex(index); if(!_rightNodes.ContainsKey(index))
if (n is null)
{ {
n = new GraphNode(index); GraphNode n = new GraphNode(index);
_rightNodes.Add(n); _rightNodes[index] = n;
return n;
}
return n; return n;
} }
else
/// <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); return _rightNodes[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);
} }
/// <summary> /// <summary>
...@@ -237,7 +201,7 @@ namespace SparseTransform.DataStructures ...@@ -237,7 +201,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the left nodes</returns> /// <returns>IEnumerable for the left nodes</returns>
public IEnumerable<GraphNode> GetLeftNodes() public IEnumerable<GraphNode> GetLeftNodes()
{ {
List<GraphNode> leftNodes = new List<GraphNode>(_leftNodes); List<GraphNode> leftNodes = new List<GraphNode>(_leftNodes.Values);
leftNodes.Sort((x, y) => leftNodes.Sort((x, y) =>
{ {
if (x.Index < y.Index) if (x.Index < y.Index)
...@@ -254,7 +218,7 @@ namespace SparseTransform.DataStructures ...@@ -254,7 +218,7 @@ namespace SparseTransform.DataStructures
/// <returns>IEnumerable for the right nodes</returns> /// <returns>IEnumerable for the right nodes</returns>
public IEnumerable<GraphNode> GetRightNodes() public IEnumerable<GraphNode> GetRightNodes()
{ {
List<GraphNode> rightNodes = new List<GraphNode>(_rightNodes); List<GraphNode> rightNodes = new List<GraphNode>(_rightNodes.Values);
rightNodes.Sort((x, y) => rightNodes.Sort((x, y) =>
{ {
if (x.Index < y.Index) if (x.Index < y.Index)
...@@ -277,7 +241,7 @@ namespace SparseTransform.DataStructures ...@@ -277,7 +241,7 @@ namespace SparseTransform.DataStructures
// This only works for row OR column partitions not mixed // This only works for row OR column partitions not mixed
if (LeftColored) if (LeftColored)
{ {
foreach (GraphNode node in _leftNodes) foreach (GraphNode node in _leftNodes.Values)
{ {
// The row index is the column index of the element // The row index is the column index of the element
// The column index = binary vector index is the color // The column index = binary vector index is the color
...@@ -288,7 +252,7 @@ namespace SparseTransform.DataStructures ...@@ -288,7 +252,7 @@ namespace SparseTransform.DataStructures
} }
else if (RightColored) else if (RightColored)
{ {
foreach (GraphNode node in _rightNodes) foreach (GraphNode node in _rightNodes.Values)
{ {
// The row index is the row index of the element // The row index is the row index of the element
seed[node.Index - 1, node.Color - 1] = 1; 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