Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions Routers/Routers.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.4.33403.182
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Routers", "Routers\Routers.csproj", "{EB4BA75B-C03B-4E71-B21F-37AFE12F12FA}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestsForRouters", "TestsForRouters\TestsForRouters.csproj", "{FB3AE590-F3E6-4FBF-A49E-C733744BAC40}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsForTwoLists", "TestsForTwoLists\TestsForTwoLists.csproj", "{9C296729-ADA4-4900-8155-A9BE6FB52711}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestsForGraph", "TestsForGraph\TestsForGraph.csproj", "{E8F69361-637E-4930-B8F3-30A9506B0843}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{EB4BA75B-C03B-4E71-B21F-37AFE12F12FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EB4BA75B-C03B-4E71-B21F-37AFE12F12FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EB4BA75B-C03B-4E71-B21F-37AFE12F12FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB4BA75B-C03B-4E71-B21F-37AFE12F12FA}.Release|Any CPU.Build.0 = Release|Any CPU
{FB3AE590-F3E6-4FBF-A49E-C733744BAC40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FB3AE590-F3E6-4FBF-A49E-C733744BAC40}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FB3AE590-F3E6-4FBF-A49E-C733744BAC40}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FB3AE590-F3E6-4FBF-A49E-C733744BAC40}.Release|Any CPU.Build.0 = Release|Any CPU
{9C296729-ADA4-4900-8155-A9BE6FB52711}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9C296729-ADA4-4900-8155-A9BE6FB52711}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9C296729-ADA4-4900-8155-A9BE6FB52711}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C296729-ADA4-4900-8155-A9BE6FB52711}.Release|Any CPU.Build.0 = Release|Any CPU
{E8F69361-637E-4930-B8F3-30A9506B0843}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E8F69361-637E-4930-B8F3-30A9506B0843}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E8F69361-637E-4930-B8F3-30A9506B0843}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E8F69361-637E-4930-B8F3-30A9506B0843}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {18B17EA7-5909-4E96-B776-65626F45E146}
EndGlobalSection
EndGlobal
105 changes: 105 additions & 0 deletions Routers/Routers/Graph.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
namespace RoutersByGraph;

/// <summary>
/// A container consisting of two lists List Arcs, ListVertexes and its own size
/// </summary>
public class Graph
{
/// <summary>
/// Returns graph size
/// </summary>
/// <returns>Graph size</returns>
/// <exception cref="NullPointerException">If the graph is empty throw exception</exception>
public int Size() => sizeGraph;

/// <summary>
/// It is used as a wrapper for writing a graph to a file
/// </summary>
/// <param name="filePath">Location of the original file</param>
/// <exception cref="NullPointerException">An empty or unfilled graph throws an exception</exception>
public void WriteToFile(string filePath, string fileAfter)
{
if (edges == null || vertexes == null)
{
throw new NullGraphOrGraphComponentsException();
}
edges.WirteToFile(filePath);
}

/// <summary>
/// Function to return ListArcs
/// </summary>
/// <returns>ListArcs in Graph</returns>
public ListEdges? ReturnListArcs() => edges;


/// <summary>
/// Function to return ListVertexes
/// </summary>
/// <returns>ListVertexes</returns>
public ListVertexes? ReturnListVertexes() => vertexes;

/// <summary>
/// Checks that the graph and its components are filled
/// </summary>
/// <returns>Returns true if the graph or its components are filled otherwise false</returns>
public bool IsEmpty()
{
return edges == null || vertexes == null;
}

/// <summary>
/// Adds paths from one vertex to another to the graph
/// </summary>
/// <param name="fromVertex">The vertex from which the path exits</param>
/// <param name="toVertex">The vertex that the path is included in</param>
/// <param name="sizeWay">Path Size</param>
public void AddArcs(int fromVertex, int toVertex, int sizeWay)
{

if (edges == null)
{
edges = new ListEdges();
}
edges.AddElement(fromVertex, toVertex, sizeWay);
}

/// <summary>
/// Initializes the list of vertices in the graph
/// </summary>
/// <param name="size">The size of the future graph</param>
public void AddVertexes(int size)
{
if (vertexes == null)
{
vertexes = new ListVertexes();
}
sizeGraph = size;
for(int i = 1; i <= sizeGraph; i++)
{
vertexes.AddElement(i);
}
}

/// <summary>
/// The shell of the Kraskala algorithm
/// </summary>
/// <param name="graph">Accepts the graph for which the algorithm will be applied</param>
/// <returns>Returns true if the graph is connected and false otherwise</returns>
/// <exception cref="NullPointerException">Throws an exception if the graph or its components are empty</exception>
public bool KraskalAlgorithm(Graph graph)
{
if (edges == null)
{
throw new NullGraphOrGraphComponentsException();
}
return edges.KraskalAlgorithm(graph);
}

private ListVertexes? vertexes { get; set; }

private ListEdges? edges { get; set; }

private int sizeGraph { get; set; }

}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А зачем этот класс вообще, если всё, что он делает, это передаёт все вызовы в GraphElement?

6 changes: 6 additions & 0 deletions Routers/Routers/InvalidFileException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace RoutersByGraph;

/// <summary>
/// Exception if there is a problem with the path to the file or there is an incorrect sequence inside the file
/// </summary>
public class InvalidFileException : Exception {}
223 changes: 223 additions & 0 deletions Routers/Routers/ListEdges.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
namespace RoutersByGraph;

/// <summary>
/// A list of arcs consisting of a pair of vertices and arcs between them
/// </summary>
public class ListEdges
{
private ListElement? head;
private ListElement? tail;

private bool SortByVertexOrArcs(bool sortByVertex, ListElement firstListElement, ListElement secondListElement)
{
return sortByVertex ? firstListElement.FromVertex > secondListElement.FromVertex : firstListElement.SizeWay < secondListElement.SizeWay;
}

/// <summary>
/// Sorting by the list bubble method
/// </summary>
/// <param name="sortByVertex">The parameter for selecting a comparison in the subsequent sorting is true if by vertices and false if by arcs</param>
/// <exception cref="NullPointerException">Throws an exception if the list is empty</exception>
public void SortListArcs(bool sortByVertex)
{
if (head == null)
{
throw new NullGraphOrGraphComponentsException();
}
int size = head.SizeListArcs;
for(int i = 0; i < size; ++i)
{
var walker = head;
for(int j = 0; j < size; ++j)
{
if (walker.Next != null && SortByVertexOrArcs(sortByVertex, walker, walker.Next))
{
var item = new ListElement(walker.FromVertex, walker.ToVertex, walker.SizeWay);
walker.SizeWay = walker.Next.SizeWay;
walker.FromVertex = walker.Next.FromVertex;
walker.ToVertex = walker.Next.ToVertex;
walker.Next.SizeWay = item.SizeWay;
walker.Next.ToVertex = item.ToVertex;
walker.Next.FromVertex = item.FromVertex;
}
walker = walker.Next;
}
}
}

/// <summary>
/// Removes arcs from the list
/// </summary>
/// <param name="fromVertex">The vertex from which the arc goes</param>
/// <param name="toVertex">The vertex to which the arc goes</param>
/// <exception cref="NullPointerException">Throws an exception if the list is empty</exception>
private void DeleteArc(int fromVertex, int toVertex)
{
if (head == null)
{
throw new NullGraphOrGraphComponentsException();
}
var walker = head;
if (walker.FromVertex == fromVertex && walker.ToVertex == toVertex)
{
head = head.Next;
return;
}
while (walker.Next != null)
{
if (walker.Next.FromVertex == fromVertex && walker.Next.ToVertex == toVertex)
{
walker.Next = walker.Next.Next;
return;
}
walker = walker.Next;
}
}

/// <summary>
/// Kraskal's algorithm for a minimal spanning tree
/// </summary>
/// <param name="graph">The graph in which everything is stored</param>
/// <returns>Returns false if the tree is not connected</returns>
/// <exception cref="NullPointerException">Throws an exception if the graph and its components are empty</exception>
public bool KraskalAlgorithm(Graph graph)
{
if (graph == null || graph.IsEmpty())
{
throw new NullGraphOrGraphComponentsException();
}
var listArcs = graph.ReturnListArcs();
var listVertexes = graph.ReturnListVertexes();
if (listArcs == null || listVertexes == null || head == null)
{
throw new NullReferenceException();
}
listArcs.SortListArcs(false);
var walker = listArcs.head;
int set = 1;
int anotherSet = 0;
while (walker != null)
{
if (walker.ToVertex != walker.FromVertex)
{
int returnedNumberPlentyFirstVertex = listVertexes.SearchForASuitableSet(walker.FromVertex);
int returnedNumberPlentySecondVertex = listVertexes.SearchForASuitableSet(walker.ToVertex);

if (returnedNumberPlentyFirstVertex != returnedNumberPlentySecondVertex)
{
if (returnedNumberPlentyFirstVertex == 0 && returnedNumberPlentySecondVertex != 0)
{
listVertexes.ChangeOneVertexSet(walker.FromVertex, returnedNumberPlentySecondVertex);
--anotherSet;
}
else if (returnedNumberPlentyFirstVertex != 0 && returnedNumberPlentySecondVertex == 0)
{
listVertexes.ChangeOneVertexSet(walker.ToVertex, returnedNumberPlentyFirstVertex);
--anotherSet;
}
else
{
listVertexes.ChangeNumbersSet(returnedNumberPlentyFirstVertex, returnedNumberPlentySecondVertex);
--anotherSet;
}
}
else if (returnedNumberPlentyFirstVertex == 0)
{
listVertexes.ChangeOneVertexSet(walker.FromVertex, set);
listVertexes.ChangeOneVertexSet(walker.ToVertex, set);
++set;
++anotherSet;
}
else
{
DeleteArc(walker.FromVertex, walker.ToVertex);
--head.SizeListArcs;
}
}
else
{
DeleteArc(walker.FromVertex, walker.ToVertex);
--head.SizeListArcs;
}
walker = walker.Next;
}
SortListArcs(true);
return !(walker == null && anotherSet != 1 && anotherSet != 0);
}

/// <summary>
/// Adds a new item to the list
/// </summary>
/// <param name="fromVertex">The vertex from which the arc originates</param>
/// <param name="toVertex">The vertex that the arc enters</param>
/// <param name="sizeWay">Arc Size</param>
public void AddElement(int fromVertex, int toVertex, int sizeWay)
{
var item = new ListElement(fromVertex, toVertex, sizeWay);
if (head == null)
{
head = item;
}
else
{
tail.Next = item;
}
tail = item;
++head.SizeListArcs;
}

/// <summary>
/// Writing to the arc list file
/// </summary>
/// <param name="filePath">The path to the file</param>
public void WirteToFile(string fileAfter)
{
var file = new StreamWriter(fileAfter);
var walker = head;
int previousMainVertex = 0;
bool isFirst = true;
while (walker != null)
{
if (walker.FromVertex != previousMainVertex)
{
if (!isFirst)
{
file.WriteLine();
}
file.Write(walker.FromVertex);
file.Write(": ");
previousMainVertex = walker.FromVertex;
isFirst = false;
}
else
{
file.Write(", ");
}
file.Write(walker.ToVertex);
file.Write(" (");
file.Write(walker.SizeWay);
file.Write(")");
walker = walker.Next;
}
file.Close();
}

private class ListElement
{
public ListElement(int fromVertex, int toVertex, int sizeWay)
{
FromVertex = fromVertex;
ToVertex = toVertex;
SizeWay = sizeWay;
}

public int FromVertex { get; set; }

public int ToVertex { get; set; }
public ListElement? Next { get; set; }

public int SizeWay { get; set; }

public int SizeListArcs { get; set; }
}
}
Loading