Matrix.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Windows.Controls;
  4. namespace DrawGraph
  5. {
  6. public class Matrix
  7. {
  8. /// <summary>
  9. /// Creates an adjacency matrix from given nodes and edges
  10. /// </summary>
  11. /// <param name="nodes">Array of nodes</param>
  12. /// <param name="edges">Array of edges</param>
  13. /// <returns>Adjacency matrix in 2D int array</returns>
  14. public static int[,] AdjacencyCreate(Node[] nodes, Edge[] edges)
  15. {
  16. int length = nodes.Length;
  17. int[,] matrix = new int[length, length];
  18. for (int i = 0; i < nodes.Length; i++)
  19. {
  20. var Node1 = nodes[i];
  21. for (int j = 0; j < nodes.Length; j++)
  22. {
  23. if (i != j)
  24. {
  25. var Node2 = nodes[j];
  26. for (int k = 0; k < edges.Length; k++)
  27. {
  28. var edge = edges[k];
  29. if (edge.IsFocused)
  30. {
  31. if (Node.Compare(edge.TargetNode, Node1) &&
  32. Node.Compare(edge.SourceNode, Node2))
  33. if (edge.Weight > 0)
  34. matrix[i, j] = (int) edge.Weight;
  35. else
  36. matrix[i, j] = 1;
  37. else if (Node.Compare(edge.SourceNode, Node1) &&
  38. Node.Compare(edge.TargetNode, Node2))
  39. if (edge.Weight > 0)
  40. matrix[i, j] = (int) edge.Weight;
  41. }
  42. else
  43. {
  44. if (Node.Compare(edge.TargetNode, Node1) &&
  45. Node.Compare(edge.SourceNode, Node2))
  46. if (edge.Weight > 0)
  47. {
  48. matrix[i, j] = (int) edge.Weight;
  49. InvertElement(matrix, i, j);
  50. }
  51. else
  52. {
  53. matrix[i, j] = 1;
  54. InvertElement(matrix, i, j);
  55. }
  56. else if (Node.Compare(edge.SourceNode, Node1) &&
  57. Node.Compare(edge.TargetNode, Node2))
  58. if (edge.Weight > 0)
  59. {
  60. matrix[i, j] = (int) edge.Weight;
  61. InvertElement(matrix, i, j);
  62. }
  63. else
  64. {
  65. matrix[i, j] = 1;
  66. InvertElement(matrix, i, j);
  67. }
  68. }
  69. }
  70. }
  71. else
  72. {
  73. matrix[i, j] = 0;
  74. }
  75. }
  76. }
  77. return matrix;
  78. }
  79. /// <summary>
  80. /// Creates an adjacency matrix from given graph
  81. /// </summary>
  82. /// <param name="graph">Your graph</param>
  83. /// <returns>Adjacency matrix in 2D int array</returns>
  84. public static int[,] AdjacencyCreate(Graph graph)
  85. {
  86. return AdjacencyCreate(graph.Nodes, graph.Edges);
  87. }
  88. /// <summary>
  89. /// Creates an adjacency matrix from given nodes and edges
  90. /// </summary>
  91. /// <param name="nodes">List of nodes</param>
  92. /// <param name="edges">List of edges</param>
  93. /// <returns>Adjacency matrix in 2D int array</returns>
  94. public static int[,] AdjacencyCreate(List<Node> nodes, List<Edge> edges)
  95. {
  96. Node[] node = nodes.ToArray();
  97. Edge[] edge = edges.ToArray();
  98. return AdjacencyCreate(node, edge);
  99. }
  100. private static int[,] InvertElement(int[,] matrix, int indexX, int indexY)
  101. {
  102. matrix[indexY, indexX] = matrix[indexX, indexY];
  103. return matrix;
  104. }
  105. /// <summary>
  106. /// Creates an incidence matrix from given nodes and edges
  107. /// </summary>
  108. /// <param name="nodes">Array of nodes</param>
  109. /// <param name="edges">Array of edges</param>
  110. /// <returns>Incidence matrix in 2D int array</returns>
  111. public static int[,] IncidenceCreate(Node[] nodes, Edge[] edges)
  112. {
  113. var rows = nodes.Length;
  114. var cols = edges.Length;
  115. var matrix = new int[rows, cols];
  116. for (var i = 0; i < rows; i++)
  117. {
  118. var Node = nodes[i];
  119. for (var j = 0; j < cols; j++)
  120. {
  121. var edge = edges[j];
  122. if (Node.Compare(Node, edge.TargetNode) && edge.IsFocused)
  123. matrix[i, j] = -1;
  124. else
  125. {
  126. if (Node.Compare(Node, edge.TargetNode) || Node.Compare(Node, edge.SourceNode))
  127. if (edge.Weight > 0)
  128. matrix[i, j] = (int)edge.Weight;
  129. else
  130. matrix[i, j] = 1;
  131. else
  132. matrix[i, j] = 0;
  133. }
  134. }
  135. }
  136. return matrix;
  137. }
  138. /// <summary>
  139. /// Creates an incidence matrix from given graph
  140. /// </summary>
  141. /// <param name="graph">Your graph</param>
  142. /// <returns>Incidence matrix in 2D int array</returns>
  143. public static int[,] IncidenceCreate(Graph graph)
  144. {
  145. return IncidenceCreate(graph.Nodes, graph.Edges);
  146. }
  147. /// <summary>
  148. /// Creates an incidence matrix from given nodes and edges
  149. /// </summary>
  150. /// <param name="nodes">List of nodes</param>
  151. /// <param name="edges">List of edges</param>
  152. /// <returns>Incidence matrix in 2D int array</returns>
  153. public static int[,] IncidenceCreate(List<Node> nodes, List<Edge> edges)
  154. {
  155. Node[] node = nodes.ToArray();
  156. Edge[] edge = edges.ToArray();
  157. return IncidenceCreate(node, edge);
  158. }
  159. /// <summary>
  160. /// Creates nodes and edges from adjacency matrix
  161. /// </summary>
  162. /// <param name="matrix">Adjacency matrix</param>
  163. /// <returns>Tuple of node and edge array</returns>
  164. public static Graph FromAdjacency(int[,] matrix)
  165. {
  166. Random random = new Random();
  167. Node[] nodes = new Node[matrix.GetLength(0)];
  168. Edge[] edges = new Edge[0];
  169. int[,] buffer = new int[edges.Length, edges.Length];
  170. for (int i = 0; i < nodes.Length; i++)
  171. {
  172. nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight));
  173. }
  174. for (int i = 0; i < nodes.Length; i++)
  175. for (int j = 0; j < nodes.Length; j++)
  176. {
  177. if (matrix[i, j] > 0 && matrix[i, j] == matrix[j, i])
  178. {
  179. buffer[j, i] = 1;
  180. buffer[i, j] = 1;
  181. }
  182. else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i])
  183. buffer[i, j] = 1;
  184. else
  185. buffer[i, j] = 0;
  186. }
  187. for (int i = 0; i < nodes.Length; i++)
  188. {
  189. var sourceNode = nodes[i];
  190. for (int j = 0; j < nodes.Length; j++)
  191. {
  192. var targetNode = nodes[j];
  193. if (buffer[i, j] != 1)
  194. {
  195. if (matrix[i, j] > 0 && matrix[j, i] == matrix[i, j])
  196. {
  197. Array.Resize(ref edges, edges.Length + 1);
  198. var index = edges.Length - 1;
  199. edges[index] = new Edge(sourceNode, targetNode, false);
  200. }
  201. else if (matrix[i, j] > 0 && matrix[i, j] != matrix[j, i])
  202. {
  203. Array.Resize(ref edges, edges.Length + 1);
  204. var index = edges.Length - 1;
  205. edges[index] = new Edge(sourceNode, targetNode, true);
  206. }
  207. }
  208. }
  209. }
  210. Graph graph = new Graph(nodes, edges);
  211. return graph;
  212. }
  213. /// <summary>
  214. /// Creates nodes and edges from adjacency matrix and add all elements to your canvas
  215. /// </summary>
  216. /// <param name="matrix">Adjacency matrix</param>
  217. /// <param name="canvas">Canvas to draw</param>
  218. /// <returns>Tuple of nodes and edges</returns>
  219. public static Graph FromAdjacencyToCanvas(int[,] matrix, Canvas canvas)
  220. {
  221. var items = FromAdjacency(matrix);
  222. Node[] nodes = items.Nodes;
  223. Edge[] edges = items.Edges;
  224. GraphAction.AddRangeToCanvas(nodes, edges, canvas);
  225. return items;
  226. }
  227. /// <summary>
  228. /// Creates nodes and edges from incidence matrix
  229. /// </summary>
  230. /// <param name="matrix">Incidence matrix</param>
  231. /// <returns>Tuple of nodes and edges array</returns>
  232. public static Graph FromIncidence(int[,] matrix)
  233. {
  234. Random random = new Random();
  235. int rows = matrix.GetLength(0);
  236. int cols = matrix.GetLength(1);
  237. Node[] nodes = new Node[rows];
  238. Edge[] edges = new Edge[cols];
  239. int cost = int.MaxValue;
  240. Node buffer = null;
  241. for(int i = 0; i < rows; i++)
  242. {
  243. nodes[i] = new Node(random.Next(0, Settings.CanvasWidth), random.Next(0, Settings.CanvasHeight));
  244. }
  245. for(int i = 0; i < cols; i++)
  246. {
  247. for(int j = 0; j < rows; j++)
  248. {
  249. if (matrix[i, j] > 0)
  250. {
  251. if (buffer == null)
  252. {
  253. cost = matrix[i, j];
  254. buffer = nodes[j];
  255. }
  256. else
  257. {
  258. if (matrix[i, j] == (cost * (-1)))
  259. edges[i] = new Edge(buffer, nodes[j], matrix[i, j], true);
  260. else
  261. edges[i] = new Edge(buffer, nodes[j], matrix[i, j], false);
  262. }
  263. }
  264. }
  265. }
  266. Graph graph = new Graph(nodes, edges);
  267. return graph;
  268. }
  269. /// <summary>
  270. /// Creates nodes and edges from incidence matrix and add all elements to your canvas
  271. /// </summary>
  272. /// <param name="matrix">Incidence matrix</param>
  273. /// <param name="canvas">Canvas to draw</param>
  274. /// <returns>Tuple of nodes and edges</returns>
  275. public static Graph FromIncidenceToCanvas(int[,] matrix, Canvas canvas)
  276. {
  277. var tuple = FromIncidence(matrix);
  278. Node[] nodes = tuple.Nodes;
  279. Edge[] edges = tuple.Edges;
  280. GraphAction.AddRangeToCanvas(nodes, edges, canvas);
  281. return tuple;
  282. }
  283. //TODO
  284. public static int[,] DistanceCreate(Node[] nodes, Edge[] edges)
  285. {
  286. if (edges is null)
  287. {
  288. throw new ArgumentNullException(nameof(edges));
  289. }
  290. var length = nodes.Length;
  291. int[,] matrix = new int[length, length];
  292. return matrix;
  293. }
  294. public static int[,] DistanceCreate(Graph graph)
  295. {
  296. return DistanceCreate(graph.Nodes, graph.Edges);
  297. }
  298. }
  299. }