/// <summary> /// Constructs line graph to the source graph. /// </summary> /// <param name="graph">Source graph.</param> /// <param name="associations">Out list of vertices and new edged associations.</param> /// <returns>Line graph.</returns> public static Graph LineGraph(this Graph graph, out List <Edge> associations) { associations = new List <Edge>(); Graph lineGraph = new AdjacencyMatrixGraph(false, graph.EdgesCount); // generates associations between old graph edges and new graph vertices for (int v = 0; v < graph.VerticesCount; v++) { foreach (Edge e in graph.OutEdges(v)) { bool canAdd = true; for (int i = 0; i < associations.Count; i++) { if (associations[i].From == e.To && associations[i].To == e.From) { canAdd = false; } } if (canAdd) { associations.Add(new Edge(e.From, e.To)); } } } // adds appropriate edges to new graph for (int v = 0; v < graph.VerticesCount; v++) { foreach (Edge e in graph.OutEdges(v)) { foreach (Edge eNext in graph.OutEdges(e.To)) { int v1 = 0, v2 = 0; for (int i = 0; i < associations.Count; i++) { if (associations[i].From == e.From && associations[i].To == e.To || associations[i].From == e.To && associations[i].To == e.From) { v1 = i; } if (associations[i].From == eNext.From && associations[i].To == eNext.To || associations[i].From == eNext.To && associations[i].To == eNext.From) { v2 = i; } } if (v1 != v2) { lineGraph.AddEdge(v1, v2); } } } } return(lineGraph); }
public void ConvertToAllocationRestul_StandardCaseOneOfEachSkill() { //arrange var g = new AdjacencyMatrixGraph(true, 11); g.AddEdge(0, 1, 2); g.AddEdge(0, 2); g.AddEdge(2, 6); g.AddEdge(1, 4); g.AddEdge(1, 3); g.AddEdge(6, 9); g.AddEdge(4, 8); g.AddEdge(3, 7); g.AddEdge(9, 10); g.AddEdge(8, 10); g.AddEdge(7, 10); //act var sut = g.GraphToAllocationResult(2, 4, 3); //assert sut.ExpertToProjects.Should().HaveCount(3); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 0 && x.ProjectId == 0 && x.SkillId == 0).Should().NotBeNull(); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 1 && x.ProjectId == 0 && x.SkillId == 1).Should().NotBeNull(); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 2 && x.ProjectId == 1 && x.SkillId == 3).Should().NotBeNull(); }
static void Test1(out Graph roads, out int[] cityCosts, out List <int> result0, out List <int> result1, out List <int> result2, out Graph paths0, out Graph paths1, out Graph paths2) { int n = 5; roads = new AdjacencyMatrixGraph(false, n); cityCosts = new int[n]; cityCosts[0] = 5; cityCosts[1] = 10; cityCosts[2] = 1; cityCosts[3] = 3; cityCosts[4] = 4; result1 = new List <int>(); result1.Add(40000); result1.Add(40000); result1.Add(40000); result1.Add(40000); result1.Add(40000); result2 = result1; result0 = result1; paths0 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths0.AddEdge(1, 0, 10000); paths0.AddEdge(2, 0, 10000); paths0.AddEdge(3, 0, 10000); paths0.AddEdge(4, 0, 10000); paths1 = paths0; paths2 = paths0; }
public static Graph ReadCSV(string path) { using (var reader = new StreamReader(path)) { var line = reader.ReadLine(); var values = line.Split(','); var graph = new AdjacencyMatrixGraph(false, values.Length); int i = 0; int j = 0; foreach (var x in values) { if (int.Parse(x) == 1) { graph.AddEdge(i, j); } i++; } while (!reader.EndOfStream) { i = 0; j++; line = reader.ReadLine(); values = line.Split(','); foreach (var x in values) { if (int.Parse(x) == 1) { graph.AddEdge(i, j); } i++; } } return(graph); } }
public void loadGraph(out IGraph graph) { try { string[] lines = System.IO.File.ReadAllLines(filePath); int size = Int32.Parse(lines[0].Trim()); graph = new AdjacencyMatrixGraph(true, size); for (int i = 1; i < lines.Length; i++) { string[] parts = lines[i].Split(':'); int v1 = Int32.Parse(parts[0].Trim()); string[] rest = parts[1].Trim().Split(','); foreach (string v2_string in rest) { int v2 = Int32.Parse(v2_string.Trim()); if (graph.GetEdgeWeight(v1, v2) == null) { graph.AddEdge(v1, v2); } if (graph.GetEdgeWeight(v2, v1) == null) { graph.AddEdge(v2, v1); } } } } catch (Exception ex) { graph = null; return; } }
static void Main(string[] args) { IGraph g; Parser parser = new Parser(); parser.LoadFile(); parser.loadGraph(out g); if (g == null) { Console.WriteLine("Wystąpił błąd podczas generowania grafu"); return; } int minFlow = int.MaxValue; int source = 0; for (int i = 0; i < g.VerticesCount; i++) { if (i == source) { continue; } IGraph g2 = new AdjacencyMatrixGraph(true, g.VerticesCount); int flow = g.FordFulkersonMaxFlow(source, i, out g2); if (flow <= minFlow) { minFlow = flow; } } Console.WriteLine(minFlow); Console.ReadLine(); }
public void MWAMGraphAddVertex_DuplicateAdd_Ignored() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); IEnumerable<Vertex> vertices; Assert.AreEqual(0, graph.Vertices().Count()); graph.AddVertex(u); vertices = graph.Vertices(); Assert.AreEqual(1, vertices.Count()); Assert.IsTrue(vertices.Contains(u)); graph.AddVertex(v); vertices = graph.Vertices(); Assert.AreEqual(2, vertices.Count()); Assert.IsTrue(vertices.Contains(u)); Assert.IsTrue(vertices.Contains(v)); graph.AddVertex(v); vertices = graph.Vertices(); Assert.AreEqual(2, vertices.Count()); Assert.IsTrue(vertices.Contains(u)); Assert.IsTrue(vertices.Contains(v)); graph.AddVertex(u); vertices = graph.Vertices(); Assert.AreEqual(2, vertices.Count()); Assert.IsTrue(vertices.Contains(u)); Assert.IsTrue(vertices.Contains(v)); }
public void BFSSearchTest_GraphInExpertSystem_Simple() { //arrange var g = new AdjacencyMatrixGraph(true, 11); g.AddEdge(0, 1); g.AddEdge(0, 2); g.AddEdge(0, 3); g.AddEdge(1, 6); g.AddEdge(2, 5); g.AddEdge(3, 4); g.AddEdge(4, 8); g.AddEdge(4, 9); g.AddEdge(5, 8); g.AddEdge(5, 9); g.AddEdge(6, 8); g.AddEdge(6, 9); g.AddEdge(7, 8); g.AddEdge(7, 9); g.AddEdge(8, 10); g.AddEdge(9, 10); var test = new BestAllocationFinder(g); ////act var prev = test.BFS(0, 3, g); //assert prev.ShouldAllBeEquivalentTo(new int[] { -1, 0, 0, 0, 3, 2, 1, -2, 6, 6, 8 }); }
public void AdjacencyMatrixTest() { var graph = new AdjacencyMatrixGraph<String>(100); Assert.IsNotNull(graph); Assert.AreEqual(100, graph.MaxNumberOfVertices); graph.AddEdge(1, "likes", 2); Assert.AreEqual(1, graph.Count()); Assert.AreEqual(1, graph.First().OutVertex); Assert.AreEqual("likes", graph.First().EdgeData); Assert.AreEqual(2, graph.First().InVertex); Assert.AreEqual("2", graph.Out(1).Select(v => v.ToString()).AggString()); Assert.AreEqual("likes", graph.OutEdges(1).AggString()); Assert.AreEqual("", graph.In(1).Select(v => v.ToString()).AggString()); Assert.AreEqual("", graph.InEdges(1).AggString()); graph.AddEdge(2, "loves", 1); Assert.AreEqual(2, graph.Count()); Assert.AreEqual(2, graph.Skip(1).First().OutVertex); Assert.AreEqual("loves", graph.Skip(1).First().EdgeData); Assert.AreEqual(1, graph.Skip(1).First().InVertex); Assert.AreEqual("1", graph.Out(2).Select(v => v.ToString()).AggString()); Assert.AreEqual("loves", graph.OutEdges(2).AggString()); Assert.AreEqual("1", graph.In(2).Select(v => v.ToString()).AggString()); Assert.AreEqual("loves", graph.InEdges(2).AggString()); graph.RemoveEdge(2, 1); Assert.AreEqual(1, graph.Count()); Assert.AreEqual(1, graph.First().OutVertex); Assert.AreEqual("likes", graph.First().EdgeData); Assert.AreEqual(2, graph.First().InVertex); }
public void ConvertToAllocationRestul_OneProjectMultipleExpertyWithOneSkill() { //arrange var g = new AdjacencyMatrixGraph(true, 9); g.AddEdge(0, 1, 4); g.AddEdge(1, 2, 2); g.AddEdge(1, 3, 2); g.AddEdge(2, 4); g.AddEdge(2, 5); g.AddEdge(3, 6); g.AddEdge(3, 7); g.AddEdge(7, 8); g.AddEdge(6, 8); g.AddEdge(5, 8); g.AddEdge(4, 8); //act var sut = g.GraphToAllocationResult(1, 2, 4); //assert sut.ExpertToProjects.Should().HaveCount(4); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 0 && x.ProjectId == 0 && x.SkillId == 0).Should().NotBeNull(); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 1 && x.ProjectId == 0 && x.SkillId == 0).Should().NotBeNull(); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 3 && x.ProjectId == 0 && x.SkillId == 1).Should().NotBeNull(); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 4 && x.ProjectId == 0 && x.SkillId == 1).Should().NotBeNull(); }
public void CanInstantiateAdjacencyMatrixGraph() { int[] vertices = { 1, 2, 3 }; AdjacencyMatrixGraph <int> graph = new AdjacencyMatrixGraph <int>(vertices); Assert.NotNull(graph); }
public void BreadthFirstTraversalIsCorrect() { // Use example graph in the book int[] vertices = { 1, 2, 3, 4, 5, 6 }; // Manually setup adjacency matrix byte[][] adjacencyMatrix = { // 1 2 3 4 5 6 new byte[] { 0, 1, 1, 0, 0, 0 }, new byte[] { 1, 0, 1, 1, 0, 0 }, new byte[] { 1, 1, 0, 0, 1, 0 }, new byte[] { 0, 1, 0, 0, 1, 1 }, new byte[] { 0, 0, 1, 1, 0, 1 }, new byte[] { 0, 0, 0, 1, 1, 0 } }; AdjacencyMatrixGraph <int> graph = new AdjacencyMatrixGraph <int>(vertices) { AdjacencyMatrix = adjacencyMatrix }; int[] resultOfBFSTraversal = graph.PerformBreadthFirstTraversal(); Assert.Equal(new int[] { 1, 2, 3, 4, 5, 6 }, resultOfBFSTraversal); }
public void CalculateMaxFlow_BasicTest() { //arrange var g = new AdjacencyMatrixGraph(true, 11); g.AddEdge(0, 1, 2); g.AddEdge(0, 2); g.AddEdge(2, 6); g.AddEdge(1, 4); g.AddEdge(1, 3); g.AddEdge(6, 9); g.AddEdge(4, 8); g.AddEdge(3, 7); g.AddEdge(2, 5); g.AddEdge(5, 8); g.AddEdge(8, 10); g.AddEdge(9, 10); g.AddEdge(8, 10); g.AddEdge(7, 10); //act var test = new BestAllocationFinder(g); //act var res = test.CalculateMaxFlow(); //assert //prev.ShouldAllBeEquivalentTo(new int[] { -1, 0, 1, 0 }); var ge = new GraphExport(); ge.Export(res); }
public AdjacencyMatrixGraph CreateGraph() { // 1 4 5 7 // u --> v --> w x <---> y --> z // | ^ 5 ^ // \---------/-----------------/ // 2 3 HashSet<Vertex> V = new HashSet<Vertex>(); AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); graph.AddVertex(u); graph.AddVertex(v); graph.AddVertex(w); graph.AddVertex(x); graph.AddVertex(y); graph.AddVertex(z); graph.SetEdge(u, v, 1); graph.SetEdge(u, w, 2); graph.SetEdge(u, z, 3); graph.SetEdge(v, w, 4); graph.SetEdge(x, y, 5); graph.SetEdge(y, x, 5); graph.SetEdge(y, z, 7); return graph; }
/// <summary> /// Funkcja zwracająca przepływ z ograniczeniami, czyli przepływ, który dla każdej z krawędzi /// ma wartość pomiędzy dolnym ograniczeniem a górnym ograniczeniem. /// Zwróć uwagę, że interesuje nas *jakikolwiek* przepływ spełniający te ograniczenia. /// </summary> /// <param name="source">źródło</param> /// <param name="sink">ujście</param> /// <param name="G">graf wejściowy, wagi krawędzi oznaczają przepustowości (górne ograniczenia)</param> /// <param name="lowerBounds">kopia grafu G, wagi krawędzi oznaczają dolne ograniczenia przepływu</param> /// <returns>Graf reprezentujący wynikowy przepływ (analogicznie do poprzedniej funkcji i do reprezentacji /// przepływu w funkcjach z biblioteki. /// Jeśli żądany przepływ nie istnieje, zwróć null. /// </returns> /// <remarks> /// Nie można modyfikować danych wejściowych! /// Złożoność metody powinna być asymptotycznie równa złożoności metody znajdującej największy przeływ (z biblioteki). /// </remarks> /// <hint>Wykorzystaj poprzednią część zadania. /// </hint> public Graph FindConstrainedFlow(int source, int sink, Graph G, Graph lowerBounds) { Graph Network = new AdjacencyMatrixGraph(true, G.VerticesCount); int n = G.VerticesCount; double[] demands = new double[n]; bool was = false; for (int i = 0; i < n; i++) { demands[i] = 0; } for (int i = 0; i < n; i++) { foreach (Edge e in lowerBounds.OutEdges(i)) { demands[i] += e.Weight; demands[e.To] -= e.Weight; Network.AddEdge(new Edge(i, e.To, G.GetEdgeWeight(i, e.To) - e.Weight)); if (i == sink && e.To == source) { was = true; } } } if (!was) { Network.AddEdge(new Edge(sink, source, double.PositiveInfinity)); } else { Network.ModifyEdgeWeight(sink, source, double.PositiveInfinity); } Graph Circulation = FindCirculation(Network, demands); if (Circulation == null) { return(null); } Circulation.DelEdge(sink, source); for (int i = 0; i < n; i++) { foreach (Edge e in lowerBounds.OutEdges(i)) { Circulation.ModifyEdgeWeight(e.From, e.To, e.Weight); } } if (was) { Circulation.AddEdge(new Edge(sink, source, G.GetEdgeWeight(sink, source))); } return(Circulation); }
/// <summary> /// Reads input file. /// </summary> /// <param name="path">Path of file.</param> /// <returns>Graph of people pairs.</returns> public static Graph LoadFile(string path) { Graph graph; using (StreamReader file = new StreamReader(path)) { string line; int verticesCount = int.Parse(file.ReadLine()); graph = new AdjacencyMatrixGraph(false, verticesCount); while ((line = file.ReadLine()) != null) { var persons = line.Split(','); int edgeFrom = int.Parse(persons[0]); int edgeTo = int.Parse(persons[1]); if (edgeFrom > verticesCount - 1 || edgeTo > verticesCount - 1) { throw new ArgumentException(); } if (edgeFrom < 0 || edgeTo < 0) { throw new ArgumentException(); } graph.AddEdge(edgeFrom, edgeTo); } } return(graph); }
public static void PrepareTests2() { int n; var rgg = new RandomGraphGenerator(); cliq_test2 = new Graph[3]; izo_test2 = new Graph[2, 2]; cliq_res2 = new int[] { 3, 3, 5 }; izo_res2 = new bool[] { false, true }; if (cliq_test2.Length != cliq_res2.Length || izo_test2.GetLongLength(0) != izo_res2.Length) { throw new ApplicationException("Zle zddefiniowane testy"); } rgg.SetSeed(123); cliq_test2[0] = rgg.UndirectedGraph(typeof(AdjacencyListsGraph <HashTableAdjacencyList>), 4000, 0.001); rgg.SetSeed(125); cliq_test2[1] = rgg.DirectedGraph(typeof(AdjacencyListsGraph <HashTableAdjacencyList>), 3000, 0.05); n = 1500; cliq_test2[2] = new AdjacencyListsGraph <HashTableAdjacencyList>(false, n); for (int i = 0; i < n; ++i) { for (int j = 1; j <= 4; ++j) { cliq_test2[2].AddEdge(i, (i + j) % n); } } n = 50; izo_test2[0, 0] = new AdjacencyMatrixGraph(true, n); for (int i = 0; i < n; ++i) { for (int j = 0; j < n; ++j) { if (i != j) { izo_test2[0, 0].AddEdge(i, j); } } } izo_test2[0, 1] = izo_test2[0, 0].Clone(); for (int i = 0; i < n; ++i) { izo_test2[0, 0].DelEdge(i, (i + 1) % n); } for (int i = 0; i < n; ++i) { izo_test2[0, 1].DelEdge(i, (i + 2) % n); } rgg.SetSeed(1234); izo_test2[1, 0] = rgg.DirectedGraph(typeof(AdjacencyMatrixGraph), 2500, 0.95, 1, 999); izo_test2[1, 1] = new AdjacencyListsGraph <HashTableAdjacencyList>(izo_test2[1, 0]); izo_test2[1, 1] = rgg.Permute(izo_test2[1, 1]); }
static void Test3(out Graph roads, out int[] cityCosts, out List <int> result0, out List <int> result1, out List <int> result2, out Graph paths0, out Graph paths1, out Graph paths2) { int n = 5; roads = new AdjacencyMatrixGraph(false, n); cityCosts = new int[n]; cityCosts[0] = 5; cityCosts[1] = 10; cityCosts[2] = 1; cityCosts[3] = 7; cityCosts[4] = 7; roads.AddEdge(0, 1, 100); roads.AddEdge(1, 2, 5); roads.AddEdge(2, 0, 5); roads.AddEdge(3, 4, 5); roads.AddEdge(4, 3, 5); result0 = new List <int>(); result0.Add(20015); result0.Add(20015); result0.Add(20010); result0.Add(30005); result0.Add(30005); result1 = new List <int>(); result1.Add(20027); result1.Add(20022); result1.Add(20025); result1.Add(30012); result1.Add(30012); result2 = new List <int>(); result2.Add(20022); result2.Add(20012); result2.Add(20025); result2.Add(30012); result2.Add(30012); paths0 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths0.AddEdge(0, 2, 5); paths0.AddEdge(1, 2, 5); paths0.AddEdge(3, 2, 10000); paths0.AddEdge(4, 2, 10000); paths1 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths1.AddEdge(0, 2, 5); paths1.AddEdge(2, 1, 5); paths1.AddEdge(3, 1, 10000); paths1.AddEdge(4, 1, 10000); paths2 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths2.AddEdge(0, 1, 100); paths2.AddEdge(2, 1, 5); paths2.AddEdge(3, 1, 10000); paths2.AddEdge(4, 1, 10000); }
public static Graph Construct(int n, Edge[] ep) { Graph g = new AdjacencyMatrixGraph(true, n); for (int i = 0; i < ep.Length; ++i) { g.AddEdge(ep[i].From, ep[i].To, i + 1); } return(g); }
public void AdjacencyMatrix_addEdge_hasCorrectValue() { AdjacencyMatrixGraph am = new AdjacencyMatrixGraph(3, GraphType.Directed); am.addEdge(1, 2); am.addEdge(0, 1); Assert.Equal(am.AdjacencyMatrix[1, 2], 1); Assert.Equal(am.AdjacencyMatrix[0, 2], 0); }
public void AdjacencyMatrix_getInDegree_ShouldMatch() { AdjacencyMatrixGraph am = new AdjacencyMatrixGraph(5, GraphType.Directed); am.addEdge(2, 1); am.addEdge(4, 1); var expected = am.GetInDegree(1); Assert.Equal(expected, 2); }
/// <summary> /// Implementacja zadania 2 /// </summary> /// <param name="childrenCount">Liczba dzieci</param> /// <param name="sweetsCount">Liczba batoników</param> /// <param name="childrenLikes"> /// Tablica tablic upodobań dzieci. Tablica childrenLikes[i] zawiera indeksy batoników /// które lubi i-te dziecko. Dzieci i batoniki są indeksowane od 0. /// </param> /// <param name="childrenLimits">Tablica ograniczeń dla dzieci. childtrenLimits[i] to maksymalna liczba batoników jakie może zjeść i-te dziecko.</param> /// <param name="sweetsLimits">Tablica ograniczeń batoników. sweetsLimits[i] to dostępna liczba i-tego batonika.</param> /// <param name="happyChildren">Wynikowy parametr zadania 2a. happyChildren[i] powinien zawierać true jeśli dziecko jest zadowolone i false wpp.</param> /// <param name="shoppingList">Wynikowy parametr zadania 2b. shoppingList[i] poiwnno zawierać liczbę batoników i-tego rodzaju, które trzeba dokupić.</param> /// <returns>Maksymalna liczba rozdanych batoników.</returns> public static int Task2(int childrenCount, int sweetsCount, int[][] childrenLikes, int[] childrenLimits, int[] sweetsLimits, out bool[] happyChildren, out int[] shoppingList) { Graph sweetsDispenser = new AdjacencyMatrixGraph(true, childrenCount + sweetsCount + 2); // Vertices in the graph // 0 - source, 1 - destination, // 2, ..., (2 + childrenCount - 1) - children // (2 + childrenCount), ..., (2 + childrenCount + sweetsCount - 1) - sweets // Each child has a limit on the amount of sweets it can it for (int i = 0; i < childrenCount; i++) { sweetsDispenser.AddEdge(0, 2 + i, childrenLimits[i]); } // Limited number of each sweet for (int i = 0; i < sweetsCount; i++) { sweetsDispenser.AddEdge(2 + childrenCount + i, 1, sweetsLimits[i]); } // Children' likes for (int i = 0; i < childrenCount; i++) { foreach (int sweet in childrenLikes[i]) { sweetsDispenser.AddEdge(2 + i, 2 + childrenCount + sweet, double.PositiveInfinity); } } int totalSweetsTaken = (int)sweetsDispenser.FordFulkersonDinicMaxFlow(0, 1, out Graph sweetsAssignment, MaxFlowGraphExtender.BFPath); happyChildren = new bool[childrenCount]; shoppingList = new int[sweetsCount]; for (int i = 0; i < childrenCount; i++) { double childSum = 0; foreach (Edge e in sweetsAssignment.OutEdges(2 + i)) { childSum += e.Weight; } happyChildren[i] = (int)childSum == childrenLimits[i]; if (!happyChildren[i]) { foreach (Edge e in sweetsDispenser.OutEdges(2 + i)) { shoppingList[e.To - (2 + childrenCount)] += childrenLimits[i] - (int)childSum; break; } } } return(totalSweetsTaken); }
public void IUAMGraphConstructor_MissingVertex_Fails() { HashSet<Vertex> V = new HashSet<Vertex>(); V.Add(u); V.Add(v); HashSet<Edge> E = new HashSet<Edge>(); E.Add(new Edge(u, v)); E.Add(new Edge(u, w)); AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(V, E); }
/// <summary> /// Implementacja zadania 1 /// </summary> /// <param name="childrenCount">Liczba dzieci</param> /// <param name="sweetsCount">Liczba batoników</param> /// <param name="childrenLikes"> /// Tablica tablic upodobań dzieci. Tablica childrenLikes[i] zawiera indeksy batoników /// które lubi i-te dziecko. Dzieci i batoniki są indeksowane od 0. /// </param> /// <param name="assignment"> /// Wynikowy parametr. assigment[i] zawiera indeks batonika które dostało i-te dziecko. /// Jeśli dziecko nie dostało żadnego batonika to -1. /// </param> /// <returns>Liczba dzieci, które dostały batonik.</returns> public static int Task1(int childrenCount, int sweetsCount, int[][] childrenLikes, out int[] assignment) { assignment = null; Graph network = new AdjacencyMatrixGraph(true, sweetsCount + childrenCount + 2); int s = sweetsCount + childrenCount; int t = sweetsCount + childrenCount + 1; // Krawędzie dzieci-ujście for (int i = 0; i < childrenCount; i++) { network.AddEdge(i, t); } // Krawędzie źródło-batoniki for (int i = childrenCount; i < sweetsCount + childrenCount; i++) { network.AddEdge(s, i); } // Krawędzie dziecko-batonik który dziecko lubi for (int i = 0; i < childrenLikes.Length; i++) { for (int j = 0; j < childrenLikes[i].Length; j++) { network.AddEdge(childrenCount + childrenLikes[i][j], i); } } Graph flow; int size = network.FordFulkersonMaxFlow(s, t, out flow); assignment = Enumerable.Repeat(-1, childrenCount).ToArray(); for (int i = 0; i < flow.VerticesCount; i++) { foreach (Edge e in flow.OutEdges(i)) { if (e.Weight == 0 || e.From == s || e.To == t) { continue; } assignment[e.To] = i - childrenCount; } } return(size); }
/// <summary> /// Konstruowanie grafu krawedziowego /// </summary> /// <param name="graph">Zadany graf</param> /// <param name="desc">Tablica opisow wierzcholkow grafu krawedziowego</param> /// <returns>Skonsturowany graf krawedziowy</returns> /// <remarks> /// Wierzcholek grafu krawedziowego odpowiadajacy krawedzi <u,v> grafu pierwotnego ma opis "u-v" /// Czyli np. dla krawedzi <1,2> powinno byc "1-2". /// </remarks> public static Graph LineGraph(Graph graph, out string[] desc) { Graph t = new AdjacencyMatrixGraph(false, graph.EdgesCount); int[,] vert = new int[graph.VerticesCount, graph.VerticesCount]; for (int i = 0; i < graph.VerticesCount; i++) { for (int j = 0; j < graph.VerticesCount; j++) { vert[i, j] = -1; } } int k = 0; string[] description = new string[graph.EdgesCount]; for (int v = 0; v < graph.VerticesCount; ++v) { foreach (Edge e1 in graph.OutEdges(v)) { if (vert[e1.From, e1.To] == -1) { description[k] = e1.From.ToString() + "-" + e1.To.ToString(); vert[e1.From, e1.To] = vert[e1.To, e1.From] = k++; } } } for (int v = 0; v < graph.VerticesCount; ++v) { foreach (Edge e1 in graph.OutEdges(v)) { foreach (Edge e2 in graph.OutEdges(e1.To)) { if (vert[e1.From, e1.To] != vert[e2.From, e2.To]) { t.AddEdge(vert[e1.From, e1.To], vert[e2.From, e2.To]); } } } } desc = description; // zmienic return(t); // zmienic (wynikiem ma byc calkiem inny graf !!!) }
/// <summary> /// Konstruowanie grafu krawedziowego /// </summary> /// <param name="graph">Zadany graf</param> /// <param name="desc">Tablica opisow wierzcholkow grafu krawedziowego</param> /// <returns>Skonsturowany graf krawedziowy</returns> /// <remarks> /// Wierzcholek grafu krawedziowego odpowiadajacy krawedzi <u,v> grafu pierwotnego ma opis "u-v" /// Czyli np. dla krawedzi <1,2> powinno byc "1-2". /// </remarks> public static Graph LineGraph(Graph graph, out string[] desc) { Graph t = new AdjacencyMatrixGraph(false, graph.EdgesCount); int[,] vert = new int[graph.VerticesCount, graph.VerticesCount]; for (int i = 0; i < graph.VerticesCount; i++) { for (int j = 0; j < graph.VerticesCount; j++) { vert[i, j] = -1; } } desc = new string[graph.EdgesCount]; // Tworzymy wierzchołki grafu krawędziowego int k = 0; for (int v = 0; v < graph.VerticesCount; ++v) { foreach (Edge e1 in graph.OutEdges(v)) { if (vert[e1.From, e1.To] == -1) { desc[k] = e1.From.ToString() + "-" + e1.To.ToString(); vert[e1.From, e1.To] = vert[e1.To, e1.From] = k++; } } } // Dodajemy krawędzie grafu krawędziowego for (int v = 0; v < graph.VerticesCount; ++v) { foreach (Edge e1 in graph.OutEdges(v)) { foreach (Edge e2 in graph.OutEdges(e1.To)) { if (e1.From != e2.To) // Sprawdzamy, czy to nie jest ta sama krawędź { t.AddEdge(vert[e1.From, e1.To], vert[e2.From, e2.To]); } } } } return(t); }
static void Test0(out Graph roads, out int[] cityCosts, out List <int> result0, out List <int> result1, out List <int> result2, out Graph paths0, out Graph paths1, out Graph paths2) { int n = 4; roads = new AdjacencyMatrixGraph(false, n); cityCosts = new int[n]; cityCosts[0] = 2; cityCosts[1] = 1; cityCosts[2] = 100; cityCosts[3] = 2; roads.AddEdge(0, 1, 4); roads.AddEdge(1, 3, 4); roads.AddEdge(0, 2, 1); roads.AddEdge(2, 3, 1); result0 = new List <int>(); result0.Add(7); result0.Add(13); result0.Add(7); result0.Add(7); result1 = new List <int>(); result1.Add(117); result1.Add(119); result1.Add(14); result1.Add(117); result2 = new List <int>(); result2.Add(109); result2.Add(115); result2.Add(10); result2.Add(109); paths0 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths0.AddEdge(1, 0, 4); paths0.AddEdge(2, 0, 1); paths0.AddEdge(3, 2, 1); paths1 = roads.IsolatedVerticesGraph(true, roads.VerticesCount); paths1.AddEdge(0, 2, 1); paths1.AddEdge(1, 0, 4); paths1.AddEdge(3, 2, 1); paths2 = paths1; }
public void ConvertToAllocationRestul_BasicTest() { //arrange var g = new AdjacencyMatrixGraph(true, 5); for (int i = 1; i < g.VerticesCount; i++) { g.AddEdge(i - 1, i); } //act var sut = g.GraphToAllocationResult(1, 1, 1); //assert sut.ExpertToProjects.Should().HaveCount(1); sut.ExpertToProjects.FirstOrDefault(x => x.ExpertId == 0 && x.ProjectId == 0 && x.SkillId == 0).Should().NotBeNull(); }
public static Graph ExpertProjectInformationToGraph(ExpertProjectInformation expertProjectInformation) { var g = new AdjacencyMatrixGraph(true, expertProjectInformation.GetVerticesCount()); //indeksowanie wierzcholkow //0 wejscie //expertProjectInformation.GetVerticesCount() - 1 ujscie //od 1 do ProjectCount wierzcholki projektow //od ProjectCount + 1 do ProjectCount + SkillCount wierzcholki skillsow //od ProjectCount + SkillCount + 1 do ProjectCount + SkillCount + ExpertCount wierzcholki eksperow for (int i = 0; i < expertProjectInformation.ProjectCount; i++) { g.AddEdge(0, i + 1, expertProjectInformation.ProjectRequirements[i].Sum()); //waga to suma wszystkich skillow potrzebnych w projekcie } for (int i = 0; i < expertProjectInformation.ProjectCount; i++) { for (int j = 0; j < expertProjectInformation.SkillCount; j++) { if (expertProjectInformation.ProjectRequirements[i][j] != 0) { g.AddEdge(i + 1, expertProjectInformation.ProjectCount + 1 + j, expertProjectInformation.ProjectRequirements[i][j]); } } } for (int i = 0; i < expertProjectInformation.ExpertCount; i++) { for (int j = 0; j < expertProjectInformation.SkillCount; j++) { if (expertProjectInformation.ExpertSkills[i][j] != 0) { g.AddEdge(expertProjectInformation.ProjectCount + 1 + j, expertProjectInformation.ProjectCount + expertProjectInformation.SkillCount + 1 + i, expertProjectInformation.ExpertSkills[i][j]); } } } for (int i = 0; i < expertProjectInformation.ExpertCount; i++) { g.AddEdge(expertProjectInformation.ProjectCount + expertProjectInformation.SkillCount + 1 + i, expertProjectInformation.GetVerticesCount() - 1); } return(g); }
/// <summary> /// Implementacja zadania 1 /// </summary> /// <param name="childrenCount">Liczba dzieci</param> /// <param name="sweetsCount">Liczba batoników</param> /// <param name="childrenLikes"> /// Tablica tablic upodobań dzieci. Tablica childrenLikes[i] zawiera indeksy batoników /// które lubi i-te dziecko. Dzieci i batoniki są indeksowane od 0. /// </param> /// <param name="assignment"> /// Wynikowy parametr. assigment[i] zawiera indeks batonika które dostało i-te dziecko. /// Jeśli dziecko nie dostało żadnego batonika to -1. /// </param> /// <returns>Liczba dzieci, które dostały batonik.</returns> public static int Task1(int childrenCount, int sweetsCount, int[][] childrenLikes, out int[] assignment) { Graph sweetsDispenser = new AdjacencyMatrixGraph(true, childrenCount + sweetsCount + 2); // Vertices in the graph // 0 - source, 1 - destination, // 2, ..., (2 + childrenCount - 1) - children // (2 + childrenCount), ..., (2 + childrenCount + sweetsCount - 1) - sweets // Each child can have only one sweet for (int i = 0; i < childrenCount; i++) { sweetsDispenser.AddEdge(0, 2 + i, 1); } // There is only one piece of each sweet for (int i = 0; i < sweetsCount; i++) { sweetsDispenser.AddEdge(2 + childrenCount + i, 1, 1); } // Children' likes for (int i = 0; i < childrenCount; i++) { foreach (int sweet in childrenLikes[i]) { sweetsDispenser.AddEdge(2 + i, 2 + childrenCount + sweet, 1); } } int childrenSatisfied = (int)sweetsDispenser.FordFulkersonDinicMaxFlow(0, 1, out Graph sweetsAssignment, MaxFlowGraphExtender.BFPath); assignment = new int[childrenCount]; for (int i = 0; i < childrenCount; i++) { assignment[i] = -1; foreach (Edge e in sweetsAssignment.OutEdges(2 + i)) { if (e.Weight > 0) { assignment[i] = e.To - (2 + childrenCount); } } } return(childrenSatisfied); }
/// <summary> /// Znajduje przepływ w sieci N z ograniczonymi przepustowościami wierzchołków (c(v)). /// Do ograniczeń wynikających ze klasycznego problemu maksymalnego przepływu /// w sieci dokładamy dodatkowe: /// dla każdego wierzchołka v, niebędącego źródłem lub ujściem przepływ przez /// dany wierzchołek nie może przekraczać jego przepustowości. /// Przepływ taki możemy znaleźć konstruując pomocniczą sieć N': /// V(N') = { v_in, v_out dla każdego v należącego do V(N) \ {s,t} } u {s,t} /// Dla każdego v należącego do V(N) \ {s,t} wierzchołki v_in i v_out łączymy krawędzią /// o przepustowości c(v). Każda krawędź (u,v) w E(N) jest reprezentowana przez krawędź /// (u_out, v_in) w N'. (przyjmujemy, że w N' s=s_in=s_out i t=t_in=t_out) - przepustowości pozostają bez zmian. /// Maksymalny przepływ w sieci N' odpowiada maksymalnemu przepływowi z ograniczeniami w sieci N. /// /// </summary> /// <param name="network">sieć wejściowa</param> /// <param name="s">źródło sieci</param> /// <param name="t">ujście sieci</param> /// <param name="capacity">przepustowości wierzchołków, przepustowości źródła i ujścia to int.MaxValue</param> /// <param name="flowGraph">Znaleziony graf przepływu w sieci wejściowej</param> /// <returns>Wartość maksymalnego przepływu</returns> /// <remarks> /// Wskazówka: Można przyjąć, że przepustowości źródła i ujścia są nieskończone /// i traktować je jak wszystkie inne wierzchołki. /// </remarks> public static int ConstrainedMaxFlow(this Graph network, int s, int t, int[] capacity, out Graph flowGraph) { // // TODO (1 pkt.) // Graph net = new AdjacencyMatrixGraph(true, network.VerticesCount * 2); for (int v = 0; v < network.VerticesCount; ++v) { if (v != s && v != t) { net.AddEdge(v + network.VerticesCount, v, capacity[v]); } foreach (Edge e in network.OutEdges(v)) { if (e.To != t) { net.AddEdge(v, e.To + network.VerticesCount, e.Weight); } else { net.AddEdge(e); } } } int flow = (int)MaxFlowGraphExtender.PushRelabelMaxFlow(net, s, t, out flowGraph); Graph fll = new AdjacencyMatrixGraph(true, network.VerticesCount); for (int v = 0; v < fll.VerticesCount; ++v) { foreach (Edge e in flowGraph.OutEdges(v)) { if (e.To != t) { fll.AddEdge(v, e.To - network.VerticesCount, e.Weight); } else { fll.AddEdge(e); } } } flowGraph = fll; return(flow); }
/// <summary> /// 2 pkt. /// Funkcja znajduje zaokrąglenie macierzy. Zaokrąglenie Z macierzy M ma następujące właściwości: /// 1. dla każedgo i,j Z[i,j] >= Podłoga(M[i,j]) i Sufit(M[i,j]) >= Z[i,j] /// 2. dla każdego wiersza suma wiersza zachowuje właściwość 1. /// Formalnie dla każdego wiersza i SumaWiersza(Z, i) >= Podłoga(SumaWiersza(M, i)) /// i Sufit(SumaWiersza(M, i)) >= SumaWiersza(Z, i) /// 3. dla każdej kolumny suma kolumny zachowuje właściwość 1. /// Formalnie dla każdej kolumny i SumaKolumny(Z, i) >= Podłoga(SumaKolumny(M, i)) /// i Sufit(SumaKolumny(M, i)) >= SumaKolumny(Z, i) /// </summary> /// <param name="matrix">Macierz do zaokrąglenia</param> /// <returns>Zaokrąglona macierz</returns> /// <remarks> /// Zaokrąglenie można obliczyć znajdując cyrkulację z dolnymi ograniczeniami w pewnej specyficznej sieci. /// Sieć składa się z wierzchołków s i t oraz po jednym wierzchołku dla każdego wiersza i jednym dla każdej kolumny. /// Wierzchołek s jest połączony ze wszystkimi wierzchołkami odpowiadającymi wierszom a t z wierzcholkami odpowiadającymi kolumnom. /// Dodatkowo każdy wiersz jest połączony z każdą kolumną oraz t z s krawędzią o bardzo dużej przepustowości. /// Należy tylko odpowiednio dobrać ograniczenia górne i dolne oraz zinterpretować wynik. /// Wskażówka: Dolne i górne ograniczenia powinny być odpowiedni zaokrąglenim w dół i w górę wartości macierz i sum tyc wartości. /// </remarks> public static int[,] RoundMatrix(double[,] matrix) { int rows = matrix.GetLength(0), columns = matrix.GetLength(1); Graph g = new AdjacencyMatrixGraph(true, rows + columns + 2); int s = 0; int t = 1; // 2, ..., 2 + rows - 1 - rows vertices // 2 + rows, ..., 2 + rows + columns - 1 - column vertices double[] rowSums = new double[rows]; double[] columnSums = new double[columns]; for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { rowSums[i] += matrix[i, j]; } g.AddEdge(s, 2 + i, Math.Ceiling(rowSums[i]) - rowSums[i]); } for (int j = 0; j < columns; j++) { for (int i = 0; i < rows; i++) { columnSums[j] += matrix[i, j]; } g.AddEdge(2 + rows + j, t, Math.Ceiling(columnSums[j]) - columnSums[j]); } for (int i = 0; i < rows; i++) { for (int j = 0; j < columns; j++) { g.AddEdge(2 + i, 2 + rows + j, int.MaxValue); } } g.AddEdge(t, s, int.MaxValue); return(new int[rows, columns]); }
public void Graph_TopologicalSort_ShouldOutputCorrectly() { AdjacencyMatrixGraph amg = new AdjacencyMatrixGraph(5, GraphType.Directed); amg.addEdge(0, 1); amg.addEdge(0, 2); amg.addEdge(1, 3); amg.addEdge(3, 2); amg.addEdge(3, 4); amg.addEdge(2, 4); var expected = new int[] { 0, 1, 3, 2, 4 }; AlgorithmsLib a = new AlgorithmsLib(); var results = a.Graph_TopologicalSort(amg); Assert.True(results.SequenceEqual(expected)); }
public void BFSSearchTest_CycleInGraph() { //arange var g = new AdjacencyMatrixGraph(true, 4); g.AddEdge(3, 0); g.AddEdge(0, 1); g.AddEdge(1, 2); g.AddEdge(2, 3); var test = new BestAllocationFinder(g); //act var prev = test.BFS(0, 3, g); //assert prev.ShouldAllBeEquivalentTo(new int[] { -1, 0, 1, 2 }); }
public AdjacencyMatrixGraph CreateGraph() { // u --> v --> w x <---> y --> z // | ^ ^ // \---------/-----------------/ HashSet<Vertex> V = new HashSet<Vertex>(); AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(10); graph.AddVertex(u); graph.AddVertex(v); graph.AddVertex(w); graph.AddVertex(x); graph.AddVertex(y); graph.AddVertex(z); graph.SetEdge(u, v); graph.SetEdge(u, w); graph.SetEdge(u, z); graph.SetEdge(v, w); graph.SetEdge(x, y); graph.SetEdge(y, x); graph.SetEdge(y, z); return graph; }
public void MWAMGraphAddVertex_Growth_VerticesAndEdgesIntact() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(3); IEnumerable<Vertex> vertices; Assert.AreEqual(0, graph.Vertices().Count()); graph.AddVertex(s); graph.AddVertex(t); graph.AddVertex(u); graph.SetEdge(s, t, 1); graph.SetEdge(t, u, 3); graph.SetEdge(u, s, 4); graph.SetEdge(t, t, 2); // S T U // S 0 1 0 // T 0 2 3 // U 4 0 0 graph.AddVertex(v); vertices = graph.Vertices(); Assert.AreEqual(4, graph.Vertices().Count()); Assert.IsTrue(vertices.Contains(s)); Assert.IsTrue(vertices.Contains(t)); Assert.IsTrue(vertices.Contains(u)); Assert.IsTrue(vertices.Contains(v)); Assert.IsTrue(graph.HasEdge(s, t)); Assert.IsTrue(graph.HasEdge(t, u)); Assert.IsTrue(graph.HasEdge(u, s)); Assert.IsTrue(graph.HasEdge(t, t)); Assert.AreEqual(1, graph.GetEdge(s, t)); Assert.AreEqual(3, graph.GetEdge(t, u)); Assert.AreEqual(4, graph.GetEdge(u, s)); Assert.AreEqual(2, graph.GetEdge(t, t)); Assert.IsFalse(graph.HasEdge(s, s)); Assert.IsFalse(graph.HasEdge(s, u)); Assert.IsFalse(graph.HasEdge(t, s)); Assert.IsFalse(graph.HasEdge(u, t)); Assert.IsFalse(graph.HasEdge(u, u)); }
/// <summary> /// Wyszukiwanie "wąskich gardeł" w sieci przesyłowej /// </summary> /// <param name="g">Graf przepustowości krawędzi</param> /// <param name="c">Graf kosztów rozbudowy sieci (kosztów zwiększenia przepustowości)</param> /// <param name="p">Tablica mocy produkcyjnych/zapotrzebowania w poszczególnych węzłach</param> /// <param name="flowValue">Maksymalna osiągalna produkcja (parametr wyjściowy)</param> /// <param name="cost">Koszt rozbudowy sieci, aby możliwe było osiągnięcie produkcji flowValue (parametr wyjściowy)</param> /// <param name="flow">Graf przepływu dla produkcji flowValue (parametr wyjściowy)</param> /// <param name="ext">Tablica rozbudowywanych krawędzi (parametr wyjściowy)</param> /// <returns> /// 0 - zapotrzebowanie można zaspokoić bez konieczności zwiększania przepustowości krawędzi<br/> /// 1 - zapotrzebowanie można zaspokoić, ale trzeba zwiększyć przepustowość (niektórych) krawędzi<br/> /// 2 - zapotrzebowania nie można zaspokoić (zbyt małe moce produkcyjne lub nieodpowiednia struktura sieci /// - można jedynie zwiększać przepustowości istniejących krawędzi, nie wolno dodawać nowych) /// </returns> /// <remarks> /// Każdy element tablicy p opisuje odpowiadający mu wierzchołek<br/> /// wartość dodatnia oznacza moce produkcyjne (wierzchołek jest źródłem)<br/> /// wartość ujemna oznacza zapotrzebowanie (wierzchołek jest ujściem), /// oczywiście "możliwości pochłaniające" ujścia to moduł wartości elementu<br/> /// "zwykłym" wierzchołkom odpowiada wartość 0 w tablicy p<br/> /// <br/> /// Jeśli funkcja zwraca 0, to<br/> /// parametr flowValue jest równy modułowi sumy zapotrzebowań<br/> /// parametr cost jest równy 0<br/> /// parametr ext jest pustą (zeroelementową) tablicą<br/> /// Jeśli funkcja zwraca 1, to<br/> /// parametr flowValue jest równy modułowi sumy zapotrzebowań<br/> /// parametr cost jest równy sumarycznemu kosztowi rozbudowy sieci (zwiększenia przepustowości krawędzi)<br/> /// parametr ext jest tablicą zawierającą informację o tym o ile należy zwiększyć przepustowości krawędzi<br/> /// Jeśli funkcja zwraca 2, to<br/> /// parametr flowValue jest równy maksymalnej możliwej do osiągnięcia produkcji /// (z uwzględnieniem zwiększenia przepustowości)<br/> /// parametr cost jest równy sumarycznemu kosztowi rozbudowy sieci (zwiększenia przepustowości krawędzi)<br/> /// parametr ext jest tablicą zawierającą informację o tym o ile należy zwiększyć przepustowości krawędzi<br/> /// Uwaga: parametr ext zawiera informacje jedynie o krawędziach, których przepustowości trzeba zwiększyć // (każdy element tablicy to opis jednej takiej krawędzi) /// </remarks> public static int BottleNeckM(this IGraph g, IGraph c, int[] p, out int flowValue, out int cost, out IGraph flow, out Edge[] ext) { flowValue = 0; cost = 0; flow = g.IsolatedVerticesGraph(); ext = new Edge[0]; //return 2; IGraph mincostFlow; int balans = 0; int minv = 0; int maxv = 0; int n = g.VerticesCount; IGraph gnew = new AdjacencyMatrixGraph(true, 2 * n + 2); IGraph cnew = new AdjacencyMatrixGraph(true, 2 * n + 2); // <0;n-1> wierzcholki // n, n+1 to zrodlo i ujscie // <n+2;2n+1> to zdublowane wierzcholki //Krawedzie for (int i = 0; i < n; i++) { foreach (Edge e in g.OutEdges(i)) { gnew.AddEdge(e.From, e.To, e.Weight); gnew.AddEdge(n + 2 + e.From, e.To, int.MaxValue); gnew.AddEdge(e.From, n + 2 + e.From, int.MaxValue); } foreach (Edge e in c.OutEdges(i)) { cnew.AddEdge(e.From, e.To, 0); cnew.AddEdge(e.From + n + 2, e.To, e.Weight); cnew.AddEdge(e.From, e.From + n + 2, 0); } } //Jedno zrodlo i ujscie for (int i = 0; i < n; i++) { if (p[i] > 0) { gnew.AddEdge(n, i, p[i]); cnew.AddEdge(n, i, 0); } else if (p[i] < 0) { gnew.AddEdge(i, n + 1, -p[i]); cnew.AddEdge(i, n + 1, 0); } } cost = gnew.MinCostFlow(cnew, n, n + 1, out mincostFlow); flow = new AdjacencyMatrixGraph(true, n); for (int i = 0; i < n; i++) foreach (Edge e in mincostFlow.OutEdges(i)) { if (e.From == n || e.To == n + 1 || e.To == e.From + n + 2 ) continue; flow.AddEdge(e.From, e.To, e.Weight + (int)mincostFlow.GetEdgeWeight(e.From + n + 2, e.To)); } List<Edge> doPoprawy = new List<Edge>(); for (int i = n + 2; i <= 2 * n + 1; i++) foreach (Edge e in mincostFlow.OutEdges(i)) { if (e.Weight == 0 || e.To == e.From + n + 2 || e.From == n || e.To == n + 1) continue; doPoprawy.Add(new Edge(e.From - n - 2, e.To, e.Weight)); flow.ModifyEdgeWeight(e.From - n - 2, e.To, e.Weight); } ext = doPoprawy.ToArray(); foreach (Edge e in mincostFlow.OutEdges(n)) flowValue += e.Weight; for (int i = 0; i < p.Length; i++) { balans += p[i]; if (p[i] > 0) maxv += p[i]; if (p[i] < 0) minv += p[i]; } if (balans < 0) //wiecej wypl niz wplyw return 2; if (cost == 0 && flowValue == maxv) //nie poprawilismy, jest maxflow return 0; if (flowValue == maxv && cost != 0) //poprawilismy, udalo sie return 1; return 2; }
public void MWAMGraphSetEdge_UnconnectedGraph_Succeeds() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(); graph.AddVertex(u); graph.AddVertex(v); graph.SetEdge(u, v, 3); Assert.IsTrue(graph.HasEdge(u, v)); Assert.AreEqual(3, graph.GetEdge(u, v)); Assert.IsFalse(graph.HasEdge(v, u)); }
public void MWAMGraphSetEdge_MissingVertex_Fails() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(); graph.AddVertex(u); graph.AddVertex(v); graph.SetEdge(u, t, 3); }
public void MWAMGraphRemoveEdge_SetAndRemove_Succeeds() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(); graph.AddVertex(u); graph.AddVertex(v); graph.SetEdge(u, v, 3); graph.RemoveEdge(u, v); Assert.IsFalse(graph.HasEdge(u, v)); Assert.IsFalse(graph.HasEdge(v, u)); }
public void MWAMGraphConstructor_InvalidCapacity_ThrowsException() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(0); }
public void MWAMGraphConstructor_Empty_Succeeds() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(); Assert.IsNotNull(graph, "Empty graph was created"); Assert.IsTrue(Enumerable.Empty<Vertex>().SequenceEqual(graph.Vertices()), "Empty vertices list"); }
/// <summary> /// Wyszukiwanie "wąskich gardeł" w sieci przesyłowej /// </summary> /// <param name="g">Graf przepustowości krawędzi</param> /// <param name="c">Graf kosztów rozbudowy sieci (kosztów zwiększenia przepustowości)</param> /// <param name="p">Tablica mocy produkcyjnych/zapotrzebowania w poszczególnych węzłach</param> /// <param name="flowValue">Maksymalna osiągalna produkcja (parametr wyjściowy)</param> /// <param name="cost">Koszt rozbudowy sieci, aby możliwe było osiągnięcie produkcji flowValue (parametr wyjściowy)</param> /// <param name="flow">Graf przepływu dla produkcji flowValue (parametr wyjściowy)</param> /// <param name="ext">Tablica rozbudowywanych krawędzi (parametr wyjściowy)</param> /// <returns> /// 0 - zapotrzebowanie można zaspokoić bez konieczności zwiększania przepustowości krawędzi<br/> /// 1 - zapotrzebowanie można zaspokoić, ale trzeba zwiększyć przepustowość (niektórych) krawędzi<br/> /// 2 - zapotrzebowania nie można zaspokoić (zbyt małe moce produkcyjne lub nieodpowiednia struktura sieci /// - można jedynie zwiększać przepustowości istniejących krawędzi, nie wolno dodawać nowych) /// </returns> /// <remarks> /// Każdy element tablicy p opisuje odpowiadający mu wierzchołek<br/> /// wartość dodatnia oznacza moce produkcyjne (wierzchołek jest źródłem)<br/> /// wartość ujemna oznacza zapotrzebowanie (wierzchołek jest ujściem), /// oczywiście "możliwości pochłaniające" ujścia to moduł wartości elementu<br/> /// "zwykłym" wierzchołkom odpowiada wartość 0 w tablicy p<br/> /// <br/> /// Jeśli funkcja zwraca 0, to<br/> /// parametr flowValue jest równy modułowi sumy zapotrzebowań<br/> /// parametr cost jest równy 0<br/> /// parametr ext jest pustą (zeroelementową) tablicą<br/> /// Jeśli funkcja zwraca 1, to<br/> /// parametr flowValue jest równy modułowi sumy zapotrzebowań<br/> /// parametr cost jest równy sumarycznemu kosztowi rozbudowy sieci (zwiększenia przepustowości krawędzi)<br/> /// parametr ext jest tablicą zawierającą informację o tym o ile należy zwiększyć przepustowości krawędzi<br/> /// Jeśli funkcja zwraca 2, to<br/> /// parametr flowValue jest równy maksymalnej możliwej do osiągnięcia produkcji /// (z uwzględnieniem zwiększenia przepustowości)<br/> /// parametr cost jest równy sumarycznemu kosztowi rozbudowy sieci (zwiększenia przepustowości krawędzi)<br/> /// parametr ext jest tablicą zawierającą informację o tym o ile należy zwiększyć przepustowości krawędzi<br/> /// Uwaga: parametr ext zawiera informacje jedynie o krawędziach, których przepustowości trzeba zwiększyć /// (każdy element tablicy to opis jednej takiej krawędzi) /// </remarks> public static int BottleNeck(this IGraph g, IGraph c, int[] p, out int flowValue, out int cost, out IGraph flow, out Edge[] ext) { flowValue = 0; // ZMIENIĆ cost = 0; // ZMIENIĆ flow = new AdjacencyMatrixGraph(true, g.VerticesCount); ext = new Edge[0]; // ZMIENIĆ IGraph g1 = new AdjacencyMatrixGraph(true, g.VerticesCount * 2 + 2); IGraph c1 = new AdjacencyMatrixGraph(true, g.VerticesCount * 2 + 2); IGraph flow2; List<Edge> ext1 = new List<Edge>(); int wplywy = 0, minw = 0, maxw= 0; for (int i = 0; i < g.VerticesCount; i++) { foreach (var e in g.OutEdges(i)) { g1.AddEdge(i, e.To, e.Weight); g1.AddEdge(i + g.VerticesCount + 2, e.To, int.MaxValue); g1.AddEdge(i, i + g.VerticesCount + 2, int.MaxValue); } foreach (var e in c.OutEdges(i)) { c1.AddEdge(i, e.To, 0); c1.AddEdge(i + g.VerticesCount + 2, e.To, e.Weight); c1.AddEdge(i, i + g.VerticesCount + 2, 0); } } for (int i = 0; i < g.VerticesCount; i++) if (p[i] > 0) { g1.AddEdge(g.VerticesCount, i, Math.Abs(p[i])); c1.AddEdge(g.VerticesCount, i, 0); } else if (p[i] < 0) { g1.AddEdge(i, g.VerticesCount+ 1, Math.Abs(p[i])); c1.AddEdge(i, g.VerticesCount + 1, 0); } cost = g1.MinCostFlow(c1, g.VerticesCount, g.VerticesCount + 1, out flow2); for (int i = 0; i < g.VerticesCount; i++) foreach (var e in flow2.OutEdges(i)) if (i != g.VerticesCount && e.To != g.VerticesCount + 1 && e.To != i + g.VerticesCount + 2) flow.AddEdge(i, e.To, e.Weight +(int)flow2.GetEdgeWeight(i + g.VerticesCount + 2, e.To)); for (int i = g.VerticesCount + 2; i<= 2 * g.VerticesCount +1; i++) foreach (var e in flow2.OutEdges(i)) if (e.Weight != 0 && e.To != i+ g.VerticesCount + 2 && i != g.VerticesCount && e.To != g.VerticesCount + 1) { ext1.Add(new Edge(i - g.VerticesCount - 2, e.To, e.Weight)); flow.ModifyEdgeWeight(i -g.VerticesCount - 2, e.To, e.Weight); } ext = ext1.ToArray(); foreach (var e in flow2.OutEdges(g.VerticesCount)) flowValue+=e.Weight; for (int i = 0; i < p.Length; i++) { wplywy += p[i]; if (p[i] > 0) maxw += Math.Abs(p[i]); if (p[i] < 0) minw -= Math.Abs(p[i]); } return (wplywy < 0) ? 2 : ((flowValue == maxw) ? ((cost == 0) ? 0 : 1) : 2); }
public static IGraph CreateAdvancedGraph(this GameMap gameMap, List<Fighter> fighters, List<Enemy> enemies, Vector2 start, Vector2 end, out Vector2 startGraph, out int beginning, out int destination) { // Punkt startowy i końcowy na siatce o gęstości wyznaczonej przez VerticesDensity Vector2 startPoint = new Vector2((float)Math.Round(start.X / VerticesDensity)*VerticesDensity, (float)Math.Round(start.Y / VerticesDensity)*VerticesDensity); Vector2 endPoint = new Vector2((float)Math.Round(end.X / VerticesDensity) * VerticesDensity, (float)Math.Round(end.Y / VerticesDensity) * VerticesDensity); // Jak dużo punktów mieści się na jednym Tile'u Vector2 tileDensity = new Vector2((float)Math.Ceiling(GameMap.TileShift.X / VerticesDensity), (float)Math.Ceiling(GameMap.TileShift.Y / VerticesDensity)); // W którym miejscu na ekranie zaczyna się i kończy graf startGraph = new Vector2(Math.Min(startPoint.X, endPoint.X) - VerticesDensity * tileDensity.X, Math.Min(startPoint.Y, endPoint.Y) - VerticesDensity * tileDensity.Y); Vector2 endGraph = new Vector2(Math.Max(startPoint.X, endPoint.X) + VerticesDensity * tileDensity.X, Math.Max(startPoint.Y, endPoint.Y) + VerticesDensity * tileDensity.Y); // Rozmiar grafu Point size = new Point((int)((endGraph.X - startGraph.X) / VerticesDensity + 1), (int)((endGraph.Y - startGraph.Y) / VerticesDensity + 1)); // ustalenie punktow poczatkowego i docelowego, na potrzeby wyszukiwania sciezek beginning = (int)((startPoint.X - startGraph.X) / VerticesDensity) + (int)((startPoint.Y - startGraph.Y) / VerticesDensity) * (size.X - 1); destination = (int)((endGraph.X - endPoint.X) / VerticesDensity) + (int)((endGraph.Y - endPoint.Y) / VerticesDensity) * (size.X - 1); // Tworzenie grafu o rozmiarze prostokata IGraph g = new AdjacencyMatrixGraph(false, (int)(size.X*size.Y)); #region Boundaries // Utworzenie granic do sprawdzania czy da się przejść Boundaries[] b = new Boundaries[8]; List<Vector2> points = new List<Vector2>(); // Lewy górny points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0,Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(Unit.BoundariesSize - VerticesDensity, -VerticesDensity)); points.Add(new Vector2(-VerticesDensity, -Unit.BoundariesSize - VerticesDensity)); points.Add(new Vector2(-Unit.BoundariesSize - VerticesDensity, -VerticesDensity)); b[0] = Boundaries.CreateFromPoints(points); // Górny points.Clear(); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(Unit.BoundariesSize, -VerticesDensity)); points.Add(new Vector2(0, -Unit.BoundariesSize - VerticesDensity)); points.Add(new Vector2(-Unit.BoundariesSize, -VerticesDensity)); b[1] = Boundaries.CreateFromPoints(points); // Prawy górny points.Clear(); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(VerticesDensity + Unit.BoundariesSize, -VerticesDensity)); points.Add(new Vector2(VerticesDensity, -Unit.BoundariesSize - VerticesDensity)); points.Add(new Vector2(VerticesDensity - Unit.BoundariesSize, -VerticesDensity)); b[2] = Boundaries.CreateFromPoints(points); // Prawy points.Clear(); points.Add(new Vector2(0, Unit.BoundariesSize)); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, -Unit.BoundariesSize)); points.Add(new Vector2(VerticesDensity, -Unit.BoundariesSize)); points.Add(new Vector2(VerticesDensity + Unit.BoundariesSize, 0)); points.Add(new Vector2(VerticesDensity, Unit.BoundariesSize)); b[3] = Boundaries.CreateFromPoints(points); // Prawy dolny points.Clear(); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, -Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(VerticesDensity + Unit.BoundariesSize, VerticesDensity)); points.Add(new Vector2(VerticesDensity, VerticesDensity + Unit.BoundariesSize)); points.Add(new Vector2(VerticesDensity - Unit.BoundariesSize, VerticesDensity)); b[4] = Boundaries.CreateFromPoints(points); // Dolny points.Clear(); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, -Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(Unit.BoundariesSize, VerticesDensity)); points.Add(new Vector2(0, VerticesDensity + Unit.BoundariesSize)); points.Add(new Vector2(-Unit.BoundariesSize, VerticesDensity)); b[5] = Boundaries.CreateFromPoints(points); // Lewy dolny points.Clear(); points.Add(new Vector2(-Unit.BoundariesSize, 0)); points.Add(new Vector2(0, -Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(-VerticesDensity + Unit.BoundariesSize, VerticesDensity)); points.Add(new Vector2(-VerticesDensity, VerticesDensity + Unit.BoundariesSize)); points.Add(new Vector2(-VerticesDensity - Unit.BoundariesSize, VerticesDensity)); b[6] = Boundaries.CreateFromPoints(points); // Lewy points.Clear(); points.Add(new Vector2(0, Unit.BoundariesSize)); points.Add(new Vector2(Unit.BoundariesSize, 0)); points.Add(new Vector2(0, -Unit.BoundariesSize)); points.Add(new Vector2(-VerticesDensity, -Unit.BoundariesSize)); points.Add(new Vector2(-VerticesDensity - Unit.BoundariesSize, 0)); points.Add(new Vector2(-VerticesDensity, Unit.BoundariesSize)); b[7] = Boundaries.CreateFromPoints(points); #endregion // Tworzenie grafu, TODO: do poprawki ta pętla for (int i = 1; i < size.X - 1; i+=2) { for (int j = 1; j < size.Y - 1; j+=2) { g.UpdateGraph(i, j, i - 1, j - 1, startGraph, size, VerticesDensity, gameMap, b[0]); g.UpdateGraph(i, j, i, j - 1, startGraph, size, VerticesDensity, gameMap, b[1]); g.UpdateGraph(i, j, i + 1, j - 1, startGraph, size, VerticesDensity, gameMap, b[2]); g.UpdateGraph(i, j, i + 1, j, startGraph, size, VerticesDensity, gameMap, b[3]); g.UpdateGraph(i, j, i + 1, j + 1, startGraph, size, VerticesDensity, gameMap, b[4]); g.UpdateGraph(i, j, i, j + 1, startGraph, size, VerticesDensity, gameMap, b[5]); g.UpdateGraph(i, j, i - 1, j + 1, startGraph, size, VerticesDensity, gameMap, b[6]); g.UpdateGraph(i, j, i - 1, j, startGraph, size, VerticesDensity, gameMap, b[7]); #region komentarz /* Vector2 mapPosition = new Vector2(startGraph.X + i * VerticesDensity, startGraph.Y + j * VerticesDensity); bool intersects = false; int x = startGraph.GetMapPosition(gameMap).X; int y = startGraph.GetMapPosition(gameMap).Y; foreach (var mo in gameMap[x + i - 1, y + j - 1].mapObjects) if ((b[0] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i , y + j].mapObjects) if ((b[0] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i - 1 + (j - 1) * (size.X - 1), i + j * (size.X - 1)); else g.DelEdge(i - 1 + (j - 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i, y + j - 1].mapObjects) if ((b[1] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[1] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i + (j - 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i + 1, y + j - 1].mapObjects) if ((b[2] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[2] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i + 1 + (j - 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i + 1, y + j].mapObjects) if ((b[3] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[3] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i + 1 + j * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i + 1, y + j + 1].mapObjects) if ((b[4] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[4] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i + 1 + (j + 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i, y + j + 1].mapObjects) if ((b[5] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[5] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i + (j + 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i - 1, y + j + 1].mapObjects) if ((b[6] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[6] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i - 1 + (j + 1) * (size.X - 1), i + j * (size.X - 1)); intersects = false; foreach (var mo in gameMap[x + i - 1, y + j].mapObjects) if ((b[7] + mapPosition).Intersects(mo.boundaries)) intersects = true; foreach (var mo in gameMap[x + i, y + j].mapObjects) if ((b[7] + mapPosition).Intersects(mo.boundaries)) intersects = true; if (!intersects) g.AddEdge(i - 1 + j * (size.X - 1), i + j * (size.X - 1)); */ #endregion } } return g; }
public static void Main() { int[] backtrackingColors; int[] greedyColors; int n,i,j,mb,mg; long counter0, counter1, counter2; string[] message1 = { "Zwykly maly graf:", "Maly dwudzielny:", "Mala klika:" }; int[] bestColorsNumbers1 = { 4, 2, 9 }; string[] message2 = { "Zwykly graf:", "Graf dwudzielny:", "Cykl parzysty:", "Klika:" }; int[] bestColorsNumbers2 = { 6, 2, 2, 200 }; string[] message3 = { "Zwykly duzy graf:", "Duzy dwudzielny:", "Duza klika:" }; int[] bestColorsNumbers3 = { 59, 2, 4000 }; IGraph[] g1 = new IGraph[message1.Length]; IGraph[] g2 = new IGraph[message2.Length]; IGraph[] g3 = new IGraph[message3.Length]; var rgg = new RandomGraphGenerator(); //GraphExport ge = new GraphExport(true, "C:\\Users\\polgrabiat\\Desktop\\Graphviz2.26.3\\Graphviz2.26.3\\bin\\dot.exe"); Console.WriteLine(); Console.WriteLine("Generowanie grafow"); Console.WriteLine(); rgg.SetSeed(101); g1[0] = rgg.UndirectedGraph(typeof(AdjacencyMatrixGraph),8,0.5); rgg.SetSeed(102); g1[1] = rgg.BipariteGraph(typeof(AdjacencyMatrixGraph),5,3,0.75); n=9; g1[2] = new AdjacencyMatrixGraph(false,n); for ( i=0 ; i<n ; ++i ) for ( j=i+1 ; j<n ; ++ j ) g1[2].AddEdge(i,j); rgg.SetSeed(103); g2[0] = rgg.UndirectedGraph(typeof(AdjacencyMatrixGraph), 20, 0.5); rgg.SetSeed(104); g2[1] = rgg.BipariteGraph(typeof(AdjacencyMatrixGraph), 30, 20, 0.25); n = 50; g2[2] = new AdjacencyListsGraph(false, n); for (i = 1; i < n; ++i) g2[2].AddEdge(i - 1, i); g2[2].AddEdge(n - 1, 0); rgg.SetSeed(105); g2[2] = rgg.Permute(g2[2]); n = 200; g2[3] = new AdjacencyMatrixGraph(false, n); for (i = 0; i < n; ++i) { for (j = i + 1; j < n; ++j) g2[3].AddEdge(i, j); } rgg.SetSeed(106); g3[0] = rgg.UndirectedGraph(typeof(AdjacencyMatrixGraph), 75, 0.99); rgg.SetSeed(107); g3[1] = rgg.BipariteGraph(typeof(AdjacencyMatrixGraph), 2000, 2000, 0.55); n = 5000; g3[2] = new AdjacencyMatrixGraph(false, n); for (i = 0; i < n; ++i) { for (j = i + 1; j < n; ++j) g3[2].AddEdge(i, j); } //Console.WriteLine("{0}", g3[2].EdgesCount); Console.WriteLine("Grafy za 1 pkt"); Console.WriteLine(); for ( i=0 ; i<g1.Length ; ++i ) { // ge.Export(g1[i], "ala"); counter0=Graph.Counter; mb=g1[i].BacktrackingColor(out backtrackingColors); counter1=Graph.Counter; mg=g1[i].GreedyColor(out greedyColors); counter2=Graph.Counter; Console.WriteLine("{0,-17} liczba wierzcholkow {1,4}, optymalna liczba kolorow {2,4}", message1[i], g1[i].VerticesCount, bestColorsNumbers1[i]); Console.WriteLine(" Backtracking: liczba kolorow {0,4}, zlozonosc {1,8}", mb, counter1-counter0); Console.WriteLine(" Greedy: liczba kolorow {0,4}, zlozonosc {1,8}", mg, counter2-counter1); Console.WriteLine(); } Console.WriteLine("Grafy za 2 pkt"); Console.WriteLine(); for (i = 0; i < g2.Length; ++i) { counter0 = Graph.Counter; mb = g2[i].BacktrackingColor(out backtrackingColors); counter1 = Graph.Counter; mg = g2[i].GreedyColor(out greedyColors); counter2 = Graph.Counter; Console.WriteLine("{0,-17} liczba wierzcholkow {1,4}, optymalna liczba kolorow {2,4}", message2[i], g2[i].VerticesCount, bestColorsNumbers2[i]); Console.WriteLine(" Backtracking: liczba kolorow {0,4}, zlozonosc {1,8}", mb, counter1 - counter0); Console.WriteLine(" Greedy: liczba kolorow {0,4}, zlozonosc {1,8}", mg, counter2 - counter1); Console.WriteLine(); } Console.WriteLine("Grafy za 3 pkt"); Console.WriteLine(); for (i = 0; i < g3.Length; ++i) { counter0 = Graph.Counter; mb = g3[i].BacktrackingColor(out backtrackingColors); counter1 = Graph.Counter; mg = g3[i].GreedyColor(out greedyColors); counter2 = Graph.Counter; Console.WriteLine("{0,-17} liczba wierzcholkow {1,4}, optymalna liczba kolorow {2,4}", message3[i], g3[i].VerticesCount, bestColorsNumbers3[i]); Console.WriteLine(" Backtracking: liczba kolorow {0,4}, zlozonosc {1,8}", mb, counter1 - counter0); Console.WriteLine(" Greedy: liczba kolorow {0,4}, zlozonosc {1,8}", mg, counter2 - counter1); Console.WriteLine(); } Console.WriteLine("Koniec"); Console.WriteLine(); }
public void IUAMGraphConstructor_Empty_Succeeds() { AdjacencyMatrixGraph graph = new AdjacencyMatrixGraph(new HashSet<Vertex>(), new HashSet<Edge>()); Assert.IsNotNull(graph, "Empty graph was not created"); }
public static void Main() { IGraph g1 = new AdjacencyMatrixGraph(true, 8); IGraph c1 = new AdjacencyMatrixGraph(true, 8); g1.AddEdge(0, 2, 20); g1.AddEdge(0, 3, 30); g1.AddEdge(1, 2, 10); g1.AddEdge(1, 2, 20); g1.AddEdge(1, 3, 40); g1.AddEdge(2, 4, 20); g1.AddEdge(2, 5, 10); g1.AddEdge(3, 6, 50); g1.AddEdge(3, 7, 30); g1.AddEdge(4, 5, 10); g1.AddEdge(6, 5, 10); g1.AddEdge(6, 7, 10); c1.AddEdge(0, 2); c1.AddEdge(0, 3); c1.AddEdge(1, 2); c1.AddEdge(1, 3); c1.AddEdge(2, 4); c1.AddEdge(2, 5); c1.AddEdge(3, 6); c1.AddEdge(3, 7); c1.AddEdge(4, 5); c1.AddEdge(6, 5); c1.AddEdge(6, 7); int[] p1 = new int[8] { 50, 50, 0, 0, -10, -20, -30, -40 }; int fv, cost, res; IGraph f,f2; Edge[] ext; Console.WriteLine(); res = g1.BottleNeck(c1, p1, out fv, out cost, out f, out ext); g1.BottleNeckM(c1, p1, out fv, out cost, out f2, out ext); if (f.Compare(f2)) Console.WriteLine("Jest ok ;)"); Console.Write("Test 1 - nie ma potrzeby rozbudowy sieci: "); if (res == 0 && fv == 100 && cost == 0 && ext.Length == 0) Console.WriteLine("OK"); else Console.WriteLine("FAILED"); Console.WriteLine(); g1.DelEdge(0, 3); g1.DelEdge(2, 4); g1.AddEdge(0, 3, 20); g1.AddEdge(2, 4, 10); res = g1.BottleNeck(c1, p1, out fv, out cost, out f, out ext); g1.BottleNeckM(c1, p1, out fv, out cost, out f2, out ext); if (f.Compare(f2)) Console.WriteLine("Jest ok ;)"); Console.Write("Test 2 - trzeba rozbudowac siec i mozna to zrobic: "); if (res == 1 && fv == 100 && cost == 20 && ext.Length > 0) { Console.WriteLine("OK"); Console.WriteLine(" rozbudowano krawedzie:"); foreach (Edge ee in ext) Console.WriteLine(" {0}", ee); } else Console.WriteLine("FAILED"); Console.WriteLine(); p1[0] = 40; res = g1.BottleNeck(c1, p1, out fv, out cost, out f, out ext); g1.BottleNeckM(c1, p1, out fv, out cost, out f2, out ext); if (f.Compare(f2)) Console.WriteLine("Jest ok ;)"); Console.Write("Test 3 - nie da sie rozbudowac sieci: "); if (res == 2 && fv == 90 && cost == 10 && ext.Length > 0) { Console.WriteLine("OK"); Console.WriteLine(" rozbudowano krawedzie:"); foreach (Edge ee in ext) Console.WriteLine(" {0}", ee); } else Console.WriteLine("FAILED"); Console.WriteLine(); p1[0] = 50; g1.DelEdge(3, 6); c1.DelEdge(3, 6); res = g1.BottleNeck(c1, p1, out fv, out cost, out f, out ext); g1.BottleNeckM(c1, p1, out fv, out cost, out f2, out ext); if (f.Compare(f2)) Console.WriteLine("Jest ok ;)"); Console.Write("Test 4 - nie da sie rozbudowac sieci: "); if (res == 2 && fv == 70 && cost == 20 && ext.Length > 0) { Console.WriteLine("OK"); Console.WriteLine(" rozbudowano krawedzie:"); foreach (Edge ee in ext) Console.WriteLine(" {0}", ee); } else Console.WriteLine("FAILED"); Console.WriteLine(); }