using System; using System.Collections.Generic; using System.Windows.Controls; namespace DrawGraph { public class Matrix { /// /// Creates an adjacency matrix from given nodes and edges /// /// Array of nodes /// Array of edges /// Adjacency matrix in 2D int array public static int[,] AdjacencyCreate(Node[] nodes, Edge[] edges) { int length = nodes.Length; int[,] matrix = new int[length, length]; for (int i = 0; i < nodes.Length; i++) { var Node1 = nodes[i]; for (int j = 0; j < nodes.Length; j++) { if (i != j) { var Node2 = nodes[j]; for (int k = 0; k < edges.Length; k++) { var edge = edges[k]; if (edge.IsFocused) { if (Node.Compare(edge.TargetNode, Node1) && Node.Compare(edge.SourceNode, Node2)) if (edge.Weight > 0) matrix[i, j] = (int) edge.Weight; else matrix[i, j] = 1; else if (Node.Compare(edge.SourceNode, Node1) && Node.Compare(edge.TargetNode, Node2)) if (edge.Weight > 0) matrix[i, j] = (int) edge.Weight; } else { if (Node.Compare(edge.TargetNode, Node1) && Node.Compare(edge.SourceNode, Node2)) if (edge.Weight > 0) { matrix[i, j] = (int) edge.Weight; InvertElement(matrix, i, j); } else { matrix[i, j] = 1; InvertElement(matrix, i, j); } else if (Node.Compare(edge.SourceNode, Node1) && Node.Compare(edge.TargetNode, Node2)) if (edge.Weight > 0) { matrix[i, j] = (int) edge.Weight; InvertElement(matrix, i, j); } else { matrix[i, j] = 1; InvertElement(matrix, i, j); } } } } else { matrix[i, j] = 0; } } } return matrix; } /// /// Creates an adjacency matrix from given nodes and edges /// /// List of nodes /// List of edges /// Adjacency matrix in 2D int array public static int[,] AdjacencyCreate(List nodes, List edges) { Node[] node = nodes.ToArray(); Edge[] edge = edges.ToArray(); return AdjacencyCreate(node, edge); } private static int[,] InvertElement(int[,] matrix, int indexX, int indexY) { matrix[indexY, indexX] = matrix[indexX, indexY]; return matrix; } /// /// Creates an incidence matrix from given nodes and edges /// /// Array of nodes /// Array of edges /// Incidence matrix in 2D int array public static int[,] IncidenceCreate(Node[] nodes, Edge[] edges) { var rows = nodes.Length; var cols = edges.Length; var matrix = new int[rows, cols]; for (var i = 0; i < rows; i++) { var Node = nodes[i]; for (var j = 0; j < cols; j++) { var edge = edges[j]; if (Node.Compare(Node, edge.TargetNode) && edge.IsFocused) matrix[i, j] = -1; else { if (Node.Compare(Node, edge.TargetNode) || Node.Compare(Node, edge.SourceNode)) if (edge.Weight > 0) matrix[i, j] = (int)edge.Weight; else matrix[i, j] = 1; else matrix[i, j] = 0; } } } return matrix; } /// /// Creates an incidence matrix from given nodes and edges /// /// List of nodes /// List of edges /// Incidence matrix in 2D int array public static int[,] IncidenceCreate(List nodes, List edges) { Node[] node = nodes.ToArray(); Edge[] edge = edges.ToArray(); return IncidenceCreate(node, edge); } /// /// Creates nodes and edges from adjacency matrix /// /// Adjacency matrix /// Tuple of node and edge array public static Tuple FromAdjacency(int[,] matrix) { Random random = new Random(); Node[] nodes = new Node[matrix.GetLength(0)]; Edge[] edges = new Edge[0]; int[,] buffer = new int[edges.Length, edges.Length]; for (int i = 0; i < nodes.Length; i++) { nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight)); } for (int i = 0; i < nodes.Length; i++) for (int j = 0; j < nodes.Length; j++) { if (matrix[i, j] > 0 && matrix[i, j] == matrix[j, i]) { buffer[j, i] = 1; buffer[i, j] = 1; } else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i]) buffer[i, j] = 1; else buffer[i, j] = 0; } for (int i = 0; i < nodes.Length; i++) { var sourceNode = nodes[i]; for (int j = 0; j < nodes.Length; j++) { var targetNode = nodes[j]; if (buffer[i, j] != 1) { if (matrix[i, j] > 0 && matrix[j, i] == matrix[i, j]) { Array.Resize(ref edges, edges.Length + 1); var index = edges.Length - 1; edges[index] = new Edge(sourceNode, targetNode, false); } else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i]) { Array.Resize(ref edges, edges.Length + 1); var index = edges.Length - 1; edges[index] = new Edge(sourceNode, targetNode, true); } } } } return Tuple.Create(nodes, edges); } /// /// Creates nodes and edges from adjacency matrix and add all elements to your canvas /// /// Adjacency matrix /// Canvas to draw /// Tuple of nodes and edges public static Tuple FromAdjacencyToCanvas(int[,] matrix, Canvas canvas) { var items = FromAdjacency(matrix); Node[] nodes = items.Item1; Edge[] edges = items.Item2; GraphAction.AddRangeToCanvas(nodes, edges, canvas); return Tuple.Create(nodes, edges); } /// /// Creates nodes and edges from incidence matrix /// /// Incidence matrix /// Tuple of nodes and edges array public static Tuple FromIncidence(int[,] matrix) { Random random = new Random(); int rows = matrix.GetLength(0); int cols = matrix.GetLength(1); Node[] nodes = new Node[rows]; Edge[] edges = new Edge[cols]; int cost = int.MaxValue; Node buffer = null; for(int i = 0; i < rows; i++) { nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight)); } for(int i = 0; i < cols; i++) { for(int j = 0; j < rows; j++) { if (matrix[i, j] > 0) { if (buffer == null) { cost = matrix[i, j]; buffer = nodes[j]; } else { if (matrix[i, j] == (cost * (-1))) edges[i] = new Edge(buffer, nodes[j], matrix[i, j], true); else edges[i] = new Edge(buffer, nodes[j], matrix[i, j], false); } } } } return Tuple.Create(nodes, edges); } /// /// Creates nodes and edges from incidence matrix and add all elements to your canvas /// /// Incidence matrix /// Canvas to draw /// Tuple of nodes and edges public static Tuple FromIncidenceToCanvas(int[,] matrix, Canvas canvas) { var tuple = FromIncidence(matrix); Node[] nodes = tuple.Item1; Edge[] edges = tuple.Item2; GraphAction.AddRangeToCanvas(nodes, edges, canvas); return Tuple.Create(nodes, edges); } } }