xxeell

DGraph

Oct 12th, 2020
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.79 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. using System.Xml.Linq;
  8.  
  9. namespace GraphTheory.GraphLibrary
  10. {
  11.     public class DGraph
  12.     {
  13.         #region Inner_classes
  14.         protected class Vertex
  15.         {
  16.             public int Id = 0;
  17.             public string Name = "";
  18.             public List<Line> InnerLines = new List<Line>();
  19.             public List<Line> OuterLines = new List<Line>();
  20.         }
  21.  
  22.         protected class Line
  23.         {
  24.             public int Id = 0;
  25.             public Vertex Start = null;
  26.             public Vertex End = null;
  27.             public int Weight = 0;
  28.         }
  29.         #endregion
  30.  
  31.         public bool IsOriented { get; private set; }
  32.         public bool IsWeighted { get; private set; }
  33.         protected List<Vertex> vertexes_main_list;
  34.         protected List<Line> lines_main_list;
  35.  
  36.         #region Constructors
  37.         // Void graph
  38.         public DGraph(bool oriented, bool weighted)
  39.         {
  40.             IsOriented = oriented;
  41.             IsWeighted = weighted;
  42.  
  43.             vertexes_main_list = new List<Vertex>();
  44.             lines_main_list = new List<Line>();
  45.         }
  46.  
  47.         // from XML
  48.         protected DGraph(XElement xml_element)
  49.         {
  50.             XElement config_elem = xml_element.Element("Configuration");
  51.             XElement vertexes_elem = xml_element.Element("Vertexes");
  52.             XElement lines_elem = xml_element.Element("Lines");
  53.  
  54.             IsOriented = true;
  55.  
  56.             vertexes_main_list = new List<Vertex>();
  57.             lines_main_list = new List<Line>();
  58.  
  59.             foreach (XElement vertex_elem in vertexes_elem.Elements("Vertex"))
  60.             {
  61.                 AddVertex(vertex_elem.Value);
  62.             }
  63.  
  64.             foreach (XElement line_elem in lines_elem.Elements("Line"))
  65.             {
  66.                 AddLine(line_elem.Element("Start").Value,
  67.                     line_elem.Element("End").Value,
  68.                     int.Parse(line_elem.Element("Weight").Value));
  69.             }
  70.  
  71.             IsOriented = config_elem.Element("Oriented").Value == "true";
  72.             IsWeighted = config_elem.Element("Weighted").Value == "true";
  73.         }
  74.  
  75.         // from File
  76.         public DGraph(string file_name)
  77.             : this(XElement.Parse(File.ReadAllText(file_name)))
  78.         {
  79.             //
  80.         }
  81.  
  82.         // Copy
  83.         public DGraph(DGraph original)
  84.             : this(DGraph.ToXML(original))
  85.         {
  86.             //
  87.         }
  88.         #endregion
  89.  
  90.         #region Methods
  91.  
  92.         #region Vertex_methods
  93.         protected Vertex FindVertex(string vertex_name)
  94.         {
  95.             return vertexes_main_list.Find(x => x.Name == vertex_name);
  96.         }
  97.  
  98.         protected Vertex FindVertexWithHasCheck(string vertex_name)
  99.         {
  100.             Vertex t = FindVertex(vertex_name);
  101.             if (t == null)
  102.             {
  103.                 throw new Exception($"Graph has no vertex with \"{vertex_name}\" name.");
  104.             }
  105.             return t;
  106.         }
  107.  
  108.         public void AddVertex(string vertex_name)
  109.         {
  110.             if (vertexes_main_list.Any(x => x.Name == vertex_name))
  111.             {
  112.                 throw new Exception("Vertex with this name has already yet.");
  113.             }
  114.  
  115.             vertexes_main_list.Add(new Vertex
  116.             {
  117.                 Id = (vertexes_main_list.Count > 0) ? (vertexes_main_list.Last().Id + 1) : (0),
  118.                 Name = vertex_name
  119.             });
  120.         }
  121.  
  122.         public void RemoveVertex(string vertex_name)
  123.         {
  124.  
  125.             Vertex vertex = FindVertexWithHasCheck(vertex_name);
  126.             vertexes_main_list.Remove(vertex);
  127.  
  128.             foreach (var line in vertex.InnerLines.Concat(vertex.OuterLines).ToArray())
  129.             {
  130.                 line.Start.OuterLines.Remove(line);
  131.                 line.End.InnerLines.Remove(line);
  132.                 lines_main_list.Remove(line);
  133.             }
  134.         }
  135.  
  136.         public string[] GetAllVertexes()
  137.         {
  138.             return vertexes_main_list.Select(x => x.Name).ToArray();
  139.         }
  140.         #endregion
  141.  
  142.         #region Lines_methods
  143.         protected Line FindLine(Vertex start, Vertex end)
  144.         {
  145.             Line line = null;
  146.  
  147.             if (start.OuterLines.Count < end.InnerLines.Count)
  148.             {
  149.                 line = start.OuterLines.Find(x => x.End.Id == end.Id);
  150.             }
  151.             else
  152.             {
  153.                 line = end.InnerLines.Find(x => x.Start.Id == start.Id);
  154.             }
  155.  
  156.             return line;
  157.         }
  158.  
  159.         protected Line FindLineWithHasCheck(Vertex start, Vertex end)
  160.         {
  161.             Line line = FindLine(start, end);
  162.  
  163.             if (line == null)
  164.             {
  165.                 throw new Exception($"Graph has no Line between \"{start.Name}\" and \"{end.Name}\".");
  166.             }
  167.  
  168.             return line;
  169.         }
  170.  
  171.         public void AddLine(string start_vertex, string end_vetrex, int weight = 0)
  172.         {
  173.             Vertex start = FindVertexWithHasCheck(start_vertex);
  174.  
  175.             Vertex end = FindVertexWithHasCheck(end_vetrex);
  176.  
  177.             if (start.OuterLines.Count < end.InnerLines.Count)
  178.             {
  179.                 if (start.OuterLines.Any(x => x.End == end))
  180.                 {
  181.                     throw new Exception($"Line between \"{start_vertex}\" and \"{end_vetrex}\" has already yet.");
  182.                 }
  183.             }
  184.             else
  185.             {
  186.                 if (end.InnerLines.Any(x => x.Start == start))
  187.                 {
  188.                     throw new Exception($"Line between \"{start_vertex}\" and \"{end_vetrex}\" has already yet.");
  189.                 }
  190.             }
  191.  
  192.             void CreateLine(Vertex v1, Vertex v2)
  193.             {
  194.                 Line line = new Line
  195.                 {
  196.                     Id = lines_main_list.Count > 0 ? lines_main_list.Last().Id + 1 : 0,
  197.                     Start = v1,
  198.                     End = v2,
  199.                     Weight = weight
  200.                 };
  201.  
  202.                 lines_main_list.Add(line);
  203.                 v1.OuterLines.Add(line);
  204.                 v2.InnerLines.Add(line);
  205.             }
  206.  
  207.             CreateLine(start, end);
  208.  
  209.             if (!IsOriented)
  210.             {
  211.                 CreateLine(end, start);
  212.             }
  213.         }
  214.  
  215.         public void RemoveLine(string start_vertex, string end_vetrex)
  216.         {
  217.             Vertex start = FindVertexWithHasCheck(start_vertex);
  218.  
  219.             Vertex end = FindVertexWithHasCheck(end_vetrex);
  220.  
  221.             void RemoveLineByVertexes(Vertex v1, Vertex v2)
  222.             {
  223.                 Line line = FindLineWithHasCheck(v1, v2);
  224.  
  225.                 lines_main_list.Remove(line);
  226.                 start.OuterLines.Remove(line);
  227.                 end.InnerLines.Remove(line);
  228.             }
  229.  
  230.             RemoveLineByVertexes(start, end);
  231.  
  232.             if (!IsOriented)
  233.             {
  234.                 RemoveLineByVertexes(end, start);
  235.             }
  236.         }
  237.  
  238.         public string[] GetAllInnerLinesByVertex(string vertex_name, bool with_width = false)
  239.         {
  240.             Vertex v = FindVertexWithHasCheck(vertex_name);
  241.             return v.InnerLines
  242.                 .Select(x => x.End.Name + (with_width ? $"({x.Weight})" : ""))
  243.                 .ToArray();
  244.         }
  245.  
  246.         public string[] GetAllOuterLinesByVertex(string vertex_name, bool with_width = false)
  247.         {
  248.             Vertex v = FindVertexWithHasCheck(vertex_name);
  249.             return v.OuterLines
  250.                 .Select(x => x.End.Name + (with_width ? $"({x.Weight})" : ""))
  251.                 .ToArray();
  252.         }
  253.         #endregion
  254.  
  255.         #region IO_methods
  256.         static public XElement ToXML(DGraph graph)
  257.         {
  258.             XElement config_elem = new XElement("Configuration",
  259.                     new XElement("Oriented", graph.IsOriented),
  260.                     new XElement("Weighted", graph.IsWeighted));
  261.  
  262.             XElement vertex_elem = new XElement("Vertexes");
  263.             foreach (var v in graph.vertexes_main_list)
  264.             {
  265.                 vertex_elem.Add(new XElement("Vertex", v.Name));
  266.             }
  267.  
  268.             XElement line_elem = new XElement("Lines");
  269.             foreach (var l in graph.lines_main_list)
  270.             {
  271.                 line_elem.Add(new XElement("Line",
  272.                     new XElement("Weight", l.Weight),
  273.                     new XElement("Start", l.Start.Name),
  274.                     new XElement("End", l.End.Name)));
  275.             }
  276.  
  277.             return new XElement("Graph",
  278.                 config_elem,
  279.                 vertex_elem,
  280.                 line_elem);
  281.         }
  282.  
  283.         static public DGraph FromXML(XElement xml_element)
  284.         {
  285.             try
  286.             {
  287.                 return new DGraph(xml_element);
  288.             }
  289.             catch (Exception e)
  290.             {
  291.                 throw new Exception("Incorrect XML.", e);
  292.             }
  293.         }
  294.  
  295.         public void WriteToFile(string file_name)
  296.         {
  297.             XElement element = ToXML(this);
  298.             File.WriteAllText(file_name, element.ToString());
  299.         }
  300.  
  301.         public void WriteAdjacencyListToFile(string file_name)
  302.         {
  303.             StringBuilder builder = new StringBuilder();
  304.  
  305.             foreach(var v in vertexes_main_list)
  306.             {
  307.                 builder.Append($"{v.Name} : ");
  308.                 foreach(var l in GetAllOuterLinesByVertex(v.Name, IsWeighted))
  309.                 {
  310.                     builder.Append(l);
  311.                     builder.Append(", ");
  312.                 }
  313.                 builder.Length = builder.Length - 2;
  314.                 builder.Append(Environment.NewLine);
  315.             }
  316.  
  317.             File.WriteAllText(file_name, builder.ToString());
  318.         }
  319.  
  320.         #endregion
  321.  
  322.         #endregion
  323.     }
  324. }
  325.  
Add Comment
Please, Sign In to add comment