Пример #1
0
        /// <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();
        }
Пример #3
0
        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;
        }
Пример #4
0
 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);
     }
 }
Пример #5
0
        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;
            }
        }
Пример #6
0
        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));
        }
Пример #8
0
        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 });
        }
Пример #9
0
        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();
        }
Пример #11
0
        public void CanInstantiateAdjacencyMatrixGraph()
        {
            int[] vertices = { 1, 2, 3 };
            AdjacencyMatrixGraph <int> graph = new AdjacencyMatrixGraph <int>(vertices);

            Assert.NotNull(graph);
        }
Пример #12
0
        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);
        }
Пример #13
0
        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;
        }
Пример #15
0
        /// <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);
        }
Пример #16
0
        /// <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);
        }
Пример #17
0
    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]);
    }
Пример #18
0
        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);
        }
Пример #19
0
    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);
    }
Пример #20
0
        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);
        }
Пример #21
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);
        }
Пример #22
0
        /// <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);
        }
Пример #24
0
        /// <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);
        }
Пример #25
0
    /// <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 !!!)
    }
Пример #26
0
    /// <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);
    }
Пример #27
0
        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);
        }
Пример #30
0
        /// <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);
        }
Пример #31
0
        /// <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);
        }
Пример #32
0
        /// <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]);
        }
Пример #33
0
        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));
        }
Пример #34
0
        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));
        }
Пример #37
0
        /// <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");
 }
Пример #43
0
        /// <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;
        }
Пример #45
0
    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");
 }
Пример #47
0
    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();
    }