Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Xml.Linq;
- namespace GraphTheory.GraphLibrary
- {
- public class DGraph
- {
- #region Inner_classes
- protected class Vertex
- {
- public int Id = 0;
- public string Name = "";
- public List<Line> InnerLines = new List<Line>();
- public List<Line> OuterLines = new List<Line>();
- }
- protected class Line
- {
- public int Id = 0;
- public Vertex Start = null;
- public Vertex End = null;
- public int Weight = 0;
- }
- #endregion
- public bool IsOriented { get; private set; }
- public bool IsWeighted { get; private set; }
- protected List<Vertex> vertexes_main_list;
- protected List<Line> lines_main_list;
- #region Constructors
- // Void graph
- public DGraph(bool oriented, bool weighted)
- {
- IsOriented = oriented;
- IsWeighted = weighted;
- vertexes_main_list = new List<Vertex>();
- lines_main_list = new List<Line>();
- }
- // from XML
- protected DGraph(XElement xml_element)
- {
- XElement config_elem = xml_element.Element("Configuration");
- XElement vertexes_elem = xml_element.Element("Vertexes");
- XElement lines_elem = xml_element.Element("Lines");
- IsOriented = true;
- vertexes_main_list = new List<Vertex>();
- lines_main_list = new List<Line>();
- foreach (XElement vertex_elem in vertexes_elem.Elements("Vertex"))
- {
- AddVertex(vertex_elem.Value);
- }
- foreach (XElement line_elem in lines_elem.Elements("Line"))
- {
- AddLine(line_elem.Element("Start").Value,
- line_elem.Element("End").Value,
- int.Parse(line_elem.Element("Weight").Value));
- }
- IsOriented = config_elem.Element("Oriented").Value == "true";
- IsWeighted = config_elem.Element("Weighted").Value == "true";
- }
- // from File
- public DGraph(string file_name)
- : this(XElement.Parse(File.ReadAllText(file_name)))
- {
- //
- }
- // Copy
- public DGraph(DGraph original)
- : this(DGraph.ToXML(original))
- {
- //
- }
- #endregion
- #region Methods
- #region Vertex_methods
- protected Vertex FindVertex(string vertex_name)
- {
- return vertexes_main_list.Find(x => x.Name == vertex_name);
- }
- protected Vertex FindVertexWithHasCheck(string vertex_name)
- {
- Vertex t = FindVertex(vertex_name);
- if (t == null)
- {
- throw new Exception($"Graph has no vertex with \"{vertex_name}\" name.");
- }
- return t;
- }
- public void AddVertex(string vertex_name)
- {
- if (vertexes_main_list.Any(x => x.Name == vertex_name))
- {
- throw new Exception("Vertex with this name has already yet.");
- }
- vertexes_main_list.Add(new Vertex
- {
- Id = (vertexes_main_list.Count > 0) ? (vertexes_main_list.Last().Id + 1) : (0),
- Name = vertex_name
- });
- }
- public void RemoveVertex(string vertex_name)
- {
- Vertex vertex = FindVertexWithHasCheck(vertex_name);
- vertexes_main_list.Remove(vertex);
- foreach (var line in vertex.InnerLines.Concat(vertex.OuterLines).ToArray())
- {
- line.Start.OuterLines.Remove(line);
- line.End.InnerLines.Remove(line);
- lines_main_list.Remove(line);
- }
- }
- public string[] GetAllVertexes()
- {
- return vertexes_main_list.Select(x => x.Name).ToArray();
- }
- #endregion
- #region Lines_methods
- protected Line FindLine(Vertex start, Vertex end)
- {
- Line line = null;
- if (start.OuterLines.Count < end.InnerLines.Count)
- {
- line = start.OuterLines.Find(x => x.End.Id == end.Id);
- }
- else
- {
- line = end.InnerLines.Find(x => x.Start.Id == start.Id);
- }
- return line;
- }
- protected Line FindLineWithHasCheck(Vertex start, Vertex end)
- {
- Line line = FindLine(start, end);
- if (line == null)
- {
- throw new Exception($"Graph has no Line between \"{start.Name}\" and \"{end.Name}\".");
- }
- return line;
- }
- public void AddLine(string start_vertex, string end_vetrex, int weight = 0)
- {
- Vertex start = FindVertexWithHasCheck(start_vertex);
- Vertex end = FindVertexWithHasCheck(end_vetrex);
- if (start.OuterLines.Count < end.InnerLines.Count)
- {
- if (start.OuterLines.Any(x => x.End == end))
- {
- throw new Exception($"Line between \"{start_vertex}\" and \"{end_vetrex}\" has already yet.");
- }
- }
- else
- {
- if (end.InnerLines.Any(x => x.Start == start))
- {
- throw new Exception($"Line between \"{start_vertex}\" and \"{end_vetrex}\" has already yet.");
- }
- }
- void CreateLine(Vertex v1, Vertex v2)
- {
- Line line = new Line
- {
- Id = lines_main_list.Count > 0 ? lines_main_list.Last().Id + 1 : 0,
- Start = v1,
- End = v2,
- Weight = weight
- };
- lines_main_list.Add(line);
- v1.OuterLines.Add(line);
- v2.InnerLines.Add(line);
- }
- CreateLine(start, end);
- if (!IsOriented)
- {
- CreateLine(end, start);
- }
- }
- public void RemoveLine(string start_vertex, string end_vetrex)
- {
- Vertex start = FindVertexWithHasCheck(start_vertex);
- Vertex end = FindVertexWithHasCheck(end_vetrex);
- void RemoveLineByVertexes(Vertex v1, Vertex v2)
- {
- Line line = FindLineWithHasCheck(v1, v2);
- lines_main_list.Remove(line);
- start.OuterLines.Remove(line);
- end.InnerLines.Remove(line);
- }
- RemoveLineByVertexes(start, end);
- if (!IsOriented)
- {
- RemoveLineByVertexes(end, start);
- }
- }
- public string[] GetAllInnerLinesByVertex(string vertex_name, bool with_width = false)
- {
- Vertex v = FindVertexWithHasCheck(vertex_name);
- return v.InnerLines
- .Select(x => x.End.Name + (with_width ? $"({x.Weight})" : ""))
- .ToArray();
- }
- public string[] GetAllOuterLinesByVertex(string vertex_name, bool with_width = false)
- {
- Vertex v = FindVertexWithHasCheck(vertex_name);
- return v.OuterLines
- .Select(x => x.End.Name + (with_width ? $"({x.Weight})" : ""))
- .ToArray();
- }
- #endregion
- #region IO_methods
- static public XElement ToXML(DGraph graph)
- {
- XElement config_elem = new XElement("Configuration",
- new XElement("Oriented", graph.IsOriented),
- new XElement("Weighted", graph.IsWeighted));
- XElement vertex_elem = new XElement("Vertexes");
- foreach (var v in graph.vertexes_main_list)
- {
- vertex_elem.Add(new XElement("Vertex", v.Name));
- }
- XElement line_elem = new XElement("Lines");
- foreach (var l in graph.lines_main_list)
- {
- line_elem.Add(new XElement("Line",
- new XElement("Weight", l.Weight),
- new XElement("Start", l.Start.Name),
- new XElement("End", l.End.Name)));
- }
- return new XElement("Graph",
- config_elem,
- vertex_elem,
- line_elem);
- }
- static public DGraph FromXML(XElement xml_element)
- {
- try
- {
- return new DGraph(xml_element);
- }
- catch (Exception e)
- {
- throw new Exception("Incorrect XML.", e);
- }
- }
- public void WriteToFile(string file_name)
- {
- XElement element = ToXML(this);
- File.WriteAllText(file_name, element.ToString());
- }
- public void WriteAdjacencyListToFile(string file_name)
- {
- StringBuilder builder = new StringBuilder();
- foreach(var v in vertexes_main_list)
- {
- builder.Append($"{v.Name} : ");
- foreach(var l in GetAllOuterLinesByVertex(v.Name, IsWeighted))
- {
- builder.Append(l);
- builder.Append(", ");
- }
- builder.Length = builder.Length - 2;
- builder.Append(Environment.NewLine);
- }
- File.WriteAllText(file_name, builder.ToString());
- }
- #endregion
- #endregion
- }
- }
Add Comment
Please, Sign In to add comment