Ejemplo n.º 1
0
        /// <summary>
        /// Część 1. zadania - zaplanowanie produkcji telewizorów dla pojedynczego kontrahenta.
        /// </summary>
        /// <remarks>
        /// Do przeprowadzenia testów wyznaczających maksymalną produkcję i zysk wymagane jest jedynie zwrócenie obiektu <see cref="PlanData"/>.
        /// Testy weryfikujące plan wymagają przypisania tablicy z planem do parametru wyjściowego <see cref="weeklyPlan"/>.
        /// </remarks>
        /// <param name="production">
        /// Tablica obiektów zawierających informacje o produkcji fabryki w kolejnych tygodniach.
        /// Wartości pola <see cref="PlanData.Quantity"/> oznaczają limit produkcji w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - koszt produkcji jednej sztuki.
        /// </param>
        /// <param name="sales">
        /// Tablica obiektów zawierających informacje o sprzedaży w kolejnych tygodniach.
        /// Wartości pola <see cref="PlanData.Quantity"/> oznaczają maksymalną sprzedaż w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - cenę sprzedaży jednej sztuki.
        /// </param>
        /// <param name="storageInfo">
        /// Obiekt zawierający informacje o magazynie.
        /// Wartość pola <see cref="PlanData.Quantity"/> oznacza pojemność magazynu,
        /// a pola <see cref="PlanData.Value"/> - koszt przechowania jednego telewizora w magazynie przez jeden tydzień.
        /// </param>
        /// <param name="weeklyPlan">
        /// Parametr wyjściowy, przez który powinien zostać zwrócony szczegółowy plan sprzedaży.
        /// </param>
        /// <returns>
        /// Obiekt <see cref="PlanData"/> opisujący wyznaczony plan.
        /// W polu <see cref="PlanData.Quantity"/> powinna znaleźć się maksymalna liczba wyprodukowanych telewizorów,
        /// a w polu <see cref="PlanData.Value"/> - wyznaczony maksymalny zysk fabryki.
        /// </returns>
        public PlanData CreateSimplePlan(PlanData[] production, PlanData[] sales, PlanData storageInfo,
                                         out SimpleWeeklyPlan[] weeklyPlan)
        {
            weeklyPlan = null;
            if (!isOK(production, sales, storageInfo))
            {
                throw new ArgumentException();
            }
            int n = production.Length;

            weeklyPlan = new SimpleWeeklyPlan[n];
            for (int i = 0; i < n; ++i)
            {
                weeklyPlan[i].UnitsProduced = 0;
                weeklyPlan[i].UnitsSold     = 0;
                weeklyPlan[i].UnitsStored   = 0;
            }
            int   k = n + 2;
            int   source = 0; int sink = n + 1;
            Graph g = new AdjacencyListsGraph <SimpleAdjacencyList>(true, k);
            Graph r = new AdjacencyListsGraph <SimpleAdjacencyList>(true, k);


            for (int j = 0; j < n - 1; ++j)
            {
                g.AddEdge(new Edge(source, j + 1, production[j].Quantity)); // dodawanie produkcji      //produkcja+,   sales-,  magazynowanie-
                r.AddEdge(new Edge(source, j + 1, production[j].Value));

                g.AddEdge(new Edge(j + 1, sink, sales[j].Quantity)); // dodawanie sprzedazy
                r.AddEdge(new Edge(j + 1, sink, -sales[j].Value));

                g.AddEdge(new Edge(j + 1, j + 2, storageInfo.Quantity)); // dodawanie magazynu
                r.AddEdge(new Edge(j + 1, j + 2, storageInfo.Value));
            }

            g.AddEdge(source, n, production[n - 1].Quantity); // ostatni tydzien produkcji
            r.AddEdge(source, n, production[n - 1].Value);
            g.AddEdge(n, sink, sales[n - 1].Quantity);        // ostatni tydzien sprzedazy
            r.AddEdge(n, sink, -sales[n - 1].Value);
            (double value, double cost, Graph flow)ret = MinCostFlowGraphExtender.MinCostFlow(g, r, source, sink, false, MaxFlowGraphExtender.PushRelabelMaxFlow, null, false);
            int produced = 0;

            for (int i = 0; i < n; ++i)
            {
                produced += (int)ret.flow.GetEdgeWeight(source, i + 1);
                weeklyPlan[i].UnitsProduced = (int)ret.flow.GetEdgeWeight(source, i + 1);
                weeklyPlan[i].UnitsSold     = (int)ret.flow.GetEdgeWeight(i + 1, sink);
                if (i != n - 1)
                {
                    weeklyPlan[i].UnitsStored = (int)ret.flow.GetEdgeWeight(i + 1, i + 2);
                }
                else
                {
                    weeklyPlan[i].UnitsStored = 0;
                }
            }
            return(new PlanData {
                Quantity = produced, Value = -ret.cost
            });
        }
Ejemplo n.º 2
0
        public static Graph webGraph()
        {
            int   nOfCycles = rnd.Next(2, 15);
            int   ringSize = rnd.Next(3, 1000 / nOfCycles);
            int   verticesCount = nOfCycles * ringSize;
            Graph web = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            int   i, j;

            for (j = 0; j < nOfCycles; j++)
            {
                for (i = 1; i < ringSize; i++)   // 0:ringsize-1 denotes first cycle; ringsize:2*ringsize-1 is second cycle
                {
                    web.AddEdge(new Edge(j * ringSize + i - 1, j * ringSize + i));
                }
            }
            for (j = 0; j < nOfCycles; j++)     // closing cycles
            {
                web.AddEdge(new Edge(j * ringSize, (j + 1) * ringSize - 1));
            }
            for (j = 0; j < nOfCycles - 1; j++) // connecting cycles
            {
                for (i = 0; i < ringSize; i++)
                {
                    web.AddEdge(new Edge(j * ringSize + i, (j + 1) * ringSize + i));
                }
            }
            for (j = 0; j < nOfCycles - 1; j++) // connecting last vertices of cycles
            {
                web.AddEdge(new Edge((j + 1) * ringSize - 1, (j + 2) * ringSize - 1));
            }
            return(changeVerticesNumeration(web));
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Część 1. zadania - zaplanowanie produkcji telewizorów dla pojedynczego kontrahenta.
        /// </summary>
        /// <remarks>
        /// Do przeprowadzenia testów wyznaczających maksymalną produkcję i zysk wymagane jest jedynie zwrócenie obiektu <see cref="PlanData"/>.
        /// Testy weryfikujące plan wymagają przypisania tablicy z planem do parametru wyjściowego <see cref="weeklyPlan"/>.
        /// </remarks>
        /// <param name="production">
        /// Tablica obiektów zawierających informacje o produkcji fabryki w kolejnych tygodniach.
        /// Wartości pola <see cref="PlanData.Quantity"/> oznaczają limit produkcji w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - koszt produkcji jednej sztuki.
        /// </param>
        /// <param name="sales">
        /// Tablica obiektów zawierających informacje o sprzedaży w kolejnych tygodniach.
        /// Wartości pola <see cref="PlanData.Quantity"/> oznaczają maksymalną sprzedaż w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - cenę sprzedaży jednej sztuki.
        /// </param>
        /// <param name="storageInfo">
        /// Obiekt zawierający informacje o magazynie.
        /// Wartość pola <see cref="PlanData.Quantity"/> oznacza pojemność magazynu,
        /// a pola <see cref="PlanData.Value"/> - koszt przechowania jednego telewizora w magazynie przez jeden tydzień.
        /// </param>
        /// <param name="weeklyPlan">
        /// Parametr wyjściowy, przez który powinien zostać zwrócony szczegółowy plan sprzedaży.
        /// </param>
        /// <returns>
        /// Obiekt <see cref="PlanData"/> opisujący wyznaczony plan.
        /// W polu <see cref="PlanData.Quantity"/> powinna znaleźć się maksymalna liczba wyprodukowanych telewizorów,
        /// a w polu <see cref="PlanData.Value"/> - wyznaczony maksymalny zysk fabryki.
        /// </returns>
        public PlanData CreateSimplePlan(PlanData[] production, PlanData[] sales, PlanData storageInfo,
                                         out SimpleWeeklyPlan[] weeklyPlan)
        {
            int weeks = production.Length;

            if (weeks == 0 || storageInfo.Quantity < 0 || storageInfo.Value < 0 || weeks != sales.Length)
            {
                throw new ArgumentException();
            }
            for (int i = 0; i < weeks; i++)
            {
                if (production[i].Quantity < 0 || production[i].Value < 0 ||
                    sales[i].Quantity < 0 || sales[i].Value < 0)
                {
                    throw new ArgumentException();
                }
            }

            Graph g = new AdjacencyListsGraph <HashTableAdjacencyList>(true, weeks + 2);
            Graph c = g.IsolatedVerticesGraph();

            //n - source
            //n+1 - target

            for (int i = 0; i < weeks; i++)
            {
                g.AddEdge(weeks, i, production[i].Quantity);
                c.AddEdge(weeks, i, production[i].Value);

                g.AddEdge(i, weeks + 1, sales[i].Quantity);
                c.AddEdge(i, weeks + 1, -sales[i].Value);

                if (i < weeks - 1)
                {
                    g.AddEdge(i, i + 1, storageInfo.Quantity);
                    c.AddEdge(i, i + 1, storageInfo.Value);
                }
            }
            (double value, double cost, Graph flow) = g.MinCostFlow(c, weeks, weeks + 1, true, MaxFlowGraphExtender.FordFulkersonDinicMaxFlow, MaxFlowGraphExtender.MKMBlockingFlow);

            weeklyPlan = new SimpleWeeklyPlan[weeks];

            for (int i = 0; i < weeks; i++)
            {
                weeklyPlan[i].UnitsProduced = (int)flow.GetEdgeWeight(weeks, i);
                weeklyPlan[i].UnitsSold     = (int)flow.GetEdgeWeight(i, weeks + 1);
                if (i < weeks - 1)
                {
                    weeklyPlan[i].UnitsStored = (int)flow.GetEdgeWeight(i, i + 1);
                }
                else
                {
                    weeklyPlan[i].UnitsStored = 0;
                }
            }

            return(new PlanData {
                Quantity = (int)value, Value = -cost
            });
        }
Ejemplo n.º 4
0
        public static Graph cactus()
        {
            int   verticesCount = rnd.Next(3, 1000);
            Graph cactus = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            int   i = 0; int connectingNode = 0;

            while (i < verticesCount - 1)
            {
                int polygonsize = 1;
                if (rnd.Next(2) > 0)
                {
                    cactus.AddEdge(connectingNode, ++i);
                }
                else
                {
                    polygonsize = rnd.Next(1, 10);
                    polygonsize = Math.Min(polygonsize, verticesCount - i - 1);
                    cactus.AddEdge(connectingNode, ++i);
                    for (int j = 1; j < polygonsize; j++)
                    {
                        cactus.AddEdge(i, ++i);
                    }
                    cactus.AddEdge(i, connectingNode);
                }
                if (rnd.Next(2) > 0)   // chance for changing connecting node == 0.5
                {
                    connectingNode = i - rnd.Next(polygonsize);
                }
            }
            return(changeVerticesNumeration(cactus));
        }
Ejemplo n.º 5
0
        private void button1_Click(object sender, EventArgs e)
        {
            Random rand = new Random();
            int x = 100;
            int y = 100;
            IGraph g = new AdjacencyListsGraph(false, x*y);
            for (int i = 0; i < x; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    if (rand.Next(0, 3) != 3)
                        g.AddEdge(i, j, rand.Next(1,3));
                }
            }
            textBox1.Text = "";

            Edge[] path;

            int s = 3, t = 24;

            g.DelEdge(s, t);

            Stopwatch sw = new Stopwatch();
            sw.Start();

            if (g.AStar(s, t, out path))
            {
                foreach (var p in path)
                    textBox1.Text += p.From + ",";
                textBox1.Text += t;
            }

            textBox2.Text = sw.Elapsed.Milliseconds.ToString();
        }
Ejemplo n.º 6
0
        public static Graph treeOfPolygons()
        {
            int         verticesCount = rnd.Next(3, 1000);
            Graph       poligonTree   = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            List <Edge> freeEdges     = new List <Edge>();
            Edge        e             = new Edge(0, 1);

            poligonTree.Add(e);
            freeEdges.Add(e);
            int i = 1;

            while (i < verticesCount - 1)
            {
                int polygonsize = rnd.Next(3, 7);
                polygonsize = Math.Min(polygonsize, verticesCount - i - 1);
                if (polygonsize > 2)
                {
                    poligonTree.AddEdge(e.To, ++i); freeEdges.Add(new Edge(e.To, i));
                    for (int j = 0; j < polygonsize - 1; j++)
                    {
                        poligonTree.AddEdge(i, ++i);
                        freeEdges.Add(new Edge(i - 1, i));
                    }
                    poligonTree.AddEdge(i, e.From);
                    freeEdges.Add(new Edge(i, e.From));
                }
                else
                {
                    break;
                }
                e = freeEdges[rnd.Next(freeEdges.Count)];
                freeEdges.Remove(e);
            }
            return(changeVerticesNumeration(poligonTree));
        }
Ejemplo n.º 7
0
        public static Graph twotree()
        {
            int   verticesCount = rnd.Next(3, 1000);
            Graph twotree       = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);

            twotree.AddEdge(new Edge(0, 1)); twotree.AddEdge(new Edge(1, 0));
            twotree.AddEdge(new Edge(1, 2)); twotree.AddEdge(new Edge(2, 1));
            twotree.AddEdge(new Edge(2, 0)); twotree.AddEdge(new Edge(0, 2));
            for (int i = 3; i < verticesCount; i++)
            {
                int         a          = rnd.Next(i);
                List <Edge> neighbours = twotree.OutEdges(a).ToList();
                int         b          = rnd.Next(neighbours.Count);
                if (neighbours[b].To == a)
                {
                    b = neighbours[b].From;
                }
                else
                {
                    b = neighbours[b].To;
                }
                twotree.AddEdge(i, a);
                twotree.AddEdge(i, b);
            }
            return(changeVerticesNumeration(twotree));
        }
Ejemplo n.º 8
0
        public static Graph necklace()
        {
            int k, l, r; // k - size of a bead; l - length of path; r - nb of beads

            k = rnd.Next(3, 7);
            l = rnd.Next(2, 7);
            r = rnd.Next(3, 15);
            int   verticesCount = (k + l) * r;
            Graph necklace = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            int   i = 0; int toPathStart = k / 2 - 1;

            for (int bead = 0; bead < r; bead++)
            {
                for (int j = 0; j < k; j++)
                {
                    necklace.AddEdge(i, ++i);
                }
                necklace.AddEdge(i, i - k);   // bead done
                necklace.AddEdge(i - toPathStart, ++i);
                if (bead == r - 1)
                {
                    l--;
                }
                for (int j = 0; j < l - 1; j++)
                {
                    necklace.AddEdge(i, ++i);       // path done
                }
            }
            necklace.AddEdge(verticesCount - 1, 0);  // for the last bead the last vertice connected with vertice 0
            return(changeVerticesNumeration(necklace));
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sprawdza możliwość przejazdu między dzielnicami-wielokątami district1 i district2,
        /// tzn. istnieją para ulic, pomiędzy którymi jest przejazd
        /// oraz fragment jednej ulicy należy do obszaru jednej z dzielnic i fragment drugiej należy do obszaru drugiej dzielnicy
        /// </summary>
        /// <returns>Informacja czy istnieje przejazd między dzielnicami</returns>
        public bool CheckDistricts(Street[] streets, Point[] district1, Point[] district2, out List <int> path, out List <Point> intersections)
        {
            AdjacencyListsGraph <SimpleAdjacencyList> g = new AdjacencyListsGraph <SimpleAdjacencyList>(false, streets.Length + 2);

            path          = new List <int>();
            intersections = new List <Point>();

            int s  = streets.Length;
            int d1 = streets.Length + 1;
            int d2 = streets.Length;

            //Construct graph
            for (int i = 0; i < s; i++)
            {
                for (int j = 0; j < district1.Length; j++)
                {
                    Street temp = new Street(district1[j], district1[(j + 1) % district1.Length]);
                    if (CheckIntersection(temp, streets[i]) == 1)
                    {
                        g.AddEdge(i, d1);
                    }
                }

                for (int j = 0; j < district2.Length; j++)
                {
                    Street temp = new Street(district2[j], district2[(j + 1) % district2.Length]);
                    if (CheckIntersection(temp, streets[i]) == 1)
                    {
                        g.AddEdge(i, d2);
                    }
                }

                for (int j = i + 1; j < s; j++)
                {
                    if (CheckIntersection(streets[i], streets[j]) == 1)
                    {
                        g.AddEdge(i, j);
                    }
                }
            }

            PathsInfo[] d = new PathsInfo[s + 2];
            g.DijkstraShortestPaths(d1, out d);
            if (double.IsNaN(d[d2].Dist))
            {
                return(false);
            }

            Edge[] edges = PathsInfo.ConstructPath(d1, d2, d);
            for (int i = 0; i < edges.Length - 1; i++)
            {
                path.Add(edges[i].To);
                if (i > 0)
                {
                    intersections.Add(GetIntersectionPoint(streets[edges[i].From], streets[edges[i].To]));
                }
            }
            return(true);
        }
Ejemplo n.º 10
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]);
    }
Ejemplo n.º 11
0
        /// <summary>
        /// Metoda zwraca największą możliwą do wyprodukowania liczbę smerfonów
        /// </summary>
        /// <param name="providers">Dostawcy</param>
        /// <param name="factories">Fabryki</param>
        /// <param name="distanceCostMultiplier">współczynnik kosztu przewozu</param>
        /// <param name="productionCost">Łączny koszt produkcji wszystkich smerfonów</param>
        /// <param name="transport">Tablica opisująca ilości transportowanych surowców miedzy poszczególnymi dostawcami i fabrykami</param>
        /// <param name="maximumProduction">Maksymalny rozmiar produkcji</param>
        public static double CalculateFlow(Provider[] providers, Factory[] factories, double distanceCostMultiplier, out double productionCost, out int[,] transport, int maximumProduction = int.MaxValue)
        {
            Graph gFlow = new AdjacencyListsGraph <SimpleAdjacencyList>(true, providers.Length + factories.Length * 2 + 3);
            Graph gCost = new AdjacencyListsGraph <SimpleAdjacencyList>(true, providers.Length + factories.Length * 2 + 3);

            int i = 1;

            for (int z = 1; z < providers.Length + 1; z++)
            {
                gFlow.AddEdge(0, z, providers[z - 1].Capacity);
                gCost.AddEdge(0, z, providers[z - 1].Cost);
            }


            foreach (var provider in providers)
            {
                int k = providers.Length + 1;
                foreach (var factory in factories)
                {
                    double distance = Math.Ceiling(Math.Sqrt((factory.Position.X - provider.Position.X) * (factory.Position.X - provider.Position.X) + (factory.Position.Y - provider.Position.Y) * (factory.Position.Y - provider.Position.Y)) * distanceCostMultiplier);
                    gFlow.AddEdge(new Edge(i, k, double.MaxValue));
                    gCost.AddEdge(new Edge(i, k, distance));
                    gFlow.AddEdge(new Edge(i, k + factories.Length, double.MaxValue));
                    gCost.AddEdge(new Edge(i, k + factories.Length, distance));
                    k++;
                }
                i++;
            }
            for (int z = providers.Length + 1; z < factories.Length + providers.Length + 1; z++)
            {
                gFlow.AddEdge(z, providers.Length + factories.Length * 2 + 1, factories[z - providers.Length - 1].Limit);
                gCost.AddEdge(z, providers.Length + factories.Length * 2 + 1, factories[z - providers.Length - 1].LowerCost);
                gFlow.AddEdge(z + factories.Length, providers.Length + factories.Length * 2 + 1, int.MaxValue);
                gCost.AddEdge(z + factories.Length, providers.Length + factories.Length * 2 + 1, factories[z - providers.Length - 1].HigherCost);
            }
            Graph fl;

            gCost.Add(new Edge(providers.Length + factories.Length * 2 + 1, providers.Length + factories.Length * 2 + 2, 0));
            gFlow.Add(new Edge(providers.Length + factories.Length * 2 + 1, providers.Length + factories.Length * 2 + 2, maximumProduction));
            double max = gFlow.MinCostFlow(gCost, 0, providers.Length + factories.Length * 2 + 2, out productionCost, out fl);

            transport = new int[providers.Length, factories.Length];
            for (int z = 1; z < providers.Length + 1; z++)
            {
                foreach (Edge e in fl.OutEdges(z))
                {
                    int to = e.To;
                    if (to > providers.Length + factories.Length)
                    {
                        to -= factories.Length;
                    }
                    transport[e.From - 1, to - providers.Length - 1] += (int)e.Weight;
                }
            }

            return(max);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Część 2. zadania - zaplanowanie produkcji telewizorów dla wielu kontrahentów.
        /// </summary>
        /// <remarks>
        /// Do przeprowadzenia testów wyznaczających produkcję dającą maksymalny zysk wymagane jest jedynie zwrócenie obiektu <see cref="PlanData"/>.
        /// Testy weryfikujące plan wymagają przypisania tablicy z planem do parametru wyjściowego <see cref="weeklyPlan"/>.
        /// </remarks>
        /// <param name="production">
        /// Tablica obiektów zawierających informacje o produkcji fabryki w kolejnych tygodniach.
        /// Wartość pola <see cref="PlanData.Quantity"/> oznacza limit produkcji w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - koszt produkcji jednej sztuki.
        /// </param>
        /// <param name="sales">
        /// Dwuwymiarowa tablica obiektów zawierających informacje o sprzedaży w kolejnych tygodniach.
        /// Pierwszy wymiar tablicy jest równy liczbie kontrahentów, zaś drugi - liczbie tygodni w planie.
        /// Wartości pola <see cref="PlanData.Quantity"/> oznaczają maksymalną sprzedaż w danym tygodniu,
        /// a pola <see cref="PlanData.Value"/> - cenę sprzedaży jednej sztuki.
        /// Każdy wiersz tablicy odpowiada jednemu kontrachentowi.
        /// </param>
        /// <param name="storageInfo">
        /// Obiekt zawierający informacje o magazynie.
        /// Wartość pola <see cref="PlanData.Quantity"/> oznacza pojemność magazynu,
        /// a pola <see cref="PlanData.Value"/> - koszt przechowania jednego telewizora w magazynie przez jeden tydzień.
        /// </param>
        /// <param name="weeklyPlan">
        /// Parametr wyjściowy, przez który powinien zostać zwrócony szczegółowy plan sprzedaży.
        /// </param>
        /// <returns>
        /// Obiekt <see cref="PlanData"/> opisujący wyznaczony plan.
        /// W polu <see cref="PlanData.Quantity"/> powinna znaleźć się optymalna liczba wyprodukowanych telewizorów,
        /// a w polu <see cref="PlanData.Value"/> - wyznaczony maksymalny zysk fabryki.
        /// </returns>
        public PlanData CreateComplexPlan(PlanData[] production, PlanData[,] sales, PlanData storageInfo,
                                          out WeeklyPlan[] weeklyPlan)
        {
            int   verticesPerWeek = 2 + sales.GetLength(0);
            int   verticesCount   = verticesPerWeek * production.Length + 2;
            Graph initialGraph    = new AdjacencyListsGraph <HashTableAdjacencyList>(true, verticesCount);
            Graph flowsGraph      = initialGraph.IsolatedVerticesGraph();
            Graph costGraph       = initialGraph.IsolatedVerticesGraph();

            for (int week = 0; week < production.Length; week++)
            {
                flowsGraph.AddEdge(0, week * verticesPerWeek + 1, double.PositiveInfinity);
                costGraph.AddEdge(0, week * verticesPerWeek + 1, 0);

                flowsGraph.AddEdge(week * verticesPerWeek + 1, week * verticesPerWeek + 2, production[week].Quantity);
                costGraph.AddEdge(week * verticesPerWeek + 1, week * verticesPerWeek + 2, production[week].Value);


                if (production.Length - week >= 2)
                {
                    flowsGraph.AddEdge(week * verticesPerWeek + 2, week * verticesPerWeek + verticesPerWeek + 2, storageInfo.Quantity);
                    costGraph.AddEdge(week * verticesPerWeek + 2, (week + 1) * verticesPerWeek + 2, storageInfo.Value);
                }
                //for (int i = 0; i < length; i++)
                //{

                //}
                //flowsGraph.AddEdge(week * verticesPerWeek + 2, week * verticesPerWeek + 3, sales[week].Quantity);
                //costGraph.AddEdge(week * verticesPerWeek + 2, week * verticesPerWeek + 3, -sales[week].Value);

                flowsGraph.AddEdge(week * verticesPerWeek + 3, verticesCount - 1, double.PositiveInfinity);
                costGraph.AddEdge(week * verticesPerWeek + 3, verticesCount - 1, 0);
            }


            (double tvQuantity, double cost, Graph resultFlow) = flowsGraph.MinCostFlow(costGraph, 0, verticesCount - 1, true);


            weeklyPlan = new WeeklyPlan[production.Length];
            for (int week = 0; week < production.Length; week++)
            {
                weeklyPlan[week].UnitsProduced = (int)resultFlow.GetEdgeWeight(week * verticesPerWeek + 1, week * verticesPerWeek + 2);
                //weeklyPlan[week].UnitsSold = (int)resultFlow.GetEdgeWeight(week * verticesPerWeek + 2, week * verticesPerWeek + 3);
                if (production.Length - week >= 2)
                {
                    weeklyPlan[week].UnitsStored = (int)resultFlow.GetEdgeWeight(week * verticesPerWeek + 2, (week + 1) * verticesPerWeek + 2);
                }
                else
                {
                    weeklyPlan[week].UnitsStored = 0;
                }
            }
            return(new PlanData {
                Quantity = (int)tvQuantity, Value = -cost
            });
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Wersja III i IV zadania
        /// Zwraca najkrótszy możliwy czas przejścia przez labirynt z użyciem co najwyżej k lasek dynamitu
        /// </summary>
        /// <param name="maze">labirynt</param>
        /// <param name="k">liczba dostępnych lasek dynamitu, dla wersji III k=1</param>
        /// <param name="path">zwracana ścieżka</param>
        /// <param name="t">czas zburzenia ściany</param>
        /// // pomysl: k+1 takich samych grafow(warstw) bez krawedzi X , a krawedzie X to takie "mosty" miedzy warstwami
        // ETAP 3 i 4
        public int FindShortestPathWithKDynamites(char[,] maze, int k, out string path, int t)
        {
            path = "";

            int X     = maze.GetLength(1);
            int Y     = maze.GetLength(0);
            int n     = X * Y; // liczba punktow w tablicy, dla ulatwienia w szukaniu numeru wierzcholka w innej warstwie grafu
            int start = -1;
            int end   = -1;
            AdjacencyListsGraph <AVLAdjacencyList> g = new AdjacencyListsGraph <AVLAdjacencyList>(true, (k + 1) * n);

            PathsInfo[] p = null;
            createGraph(maze, g, t, out start, out end, k, n);
            ShortestPathsGraphExtender.DijkstraShortestPaths(g, start, out p);
            int[] dist = new int[k + 1]; // tablica najlepszych drog dla uzycia dynamitow od 0 do k
            for (int i = 0; i <= k; ++i)
            {
                dist[i] = -1;
            }
            int min   = int.MaxValue;
            int index = 0;               // ilosc dynamitow zuzytych dla najlepszej drogi

            for (int i = 0; i <= k; ++i) // sprawdzenie dla kazdej ilosci uzytego dynamitu najlepszej drogi
            {
                int tmp = (int)p[end + i * n].Dist;
                if (!Double.IsNaN(p[end + i * n].Dist)) // jesli nie NaN to porownac z wartoscia najmniejsza
                {
                    dist[i] = tmp;
                    if (tmp < min) // jesli nowa wartosc lepsza to zapisac jako min
                    {
                        min   = tmp;
                        index = i;
                    }
                }
            }
            if (min == int.MaxValue)
            {
                return(-1); // jesli nie znaleziono sciezki to -1
            }
            else
            {
                if (X > 1)
                {
                    path = constructStringE34(PathsInfo.ConstructPath(start, end + index * n, p), X, n);
                }
                else // jesli kolejne wierzcholki grafu nie sa na tablicy po prawo/lewo, tylko gora/dol (bo wymiar 1xN czy Nx1 nie wiem)
                {
                    path = constructStringE341xN(PathsInfo.ConstructPath(start, end + index * n, p), X, n);
                }
                return(min);
            }
        }
Ejemplo n.º 14
0
        public static Graph wheel()
        {
            int   veticesCount = rnd.Next(4, 101);
            Graph wheel        = new AdjacencyListsGraph <SimpleAdjacencyList>(false, veticesCount);

            for (int i = 1; i < veticesCount; i++)
            {
                wheel.AddEdge(0, i);
                wheel.AddEdge(i - 1, i);
            }
            wheel.AddEdge(1, veticesCount - 1);
            return(changeVerticesNumeration(wheel));
        }
Ejemplo n.º 15
0
        //Część 2
        // Konstruowanie grafu na podstawie podanego ciągu grafowego


        public Graph ConstructGraph(int[] sequence)
        {
            Graph g = new AdjacencyListsGraph <HashTableAdjacencyList>(false, sequence.Length);

            if (sequence.Length == 1)
            {
                if (sequence[0] == 0)
                {
                    return(g);
                }
                else
                {
                    return(null);
                }
            }
            List <(int, int)> t = new List <(int, int)>();
            int sum             = 0;

            for (int i = 0; i < sequence.Length; i++)
            {
                t.Add((sequence[i], i));
                sum += sequence[i];
            }
            if (sum % 2 == 1)
            {
                return(null);
            }
            t.Sort();
            int count = t.Count;

            while (count > 1 && t[count - 1].Item1 > 0)
            {
                for (int i = 0; i < t[count - 1].Item1; i++)
                {
                    if (t[count - 2 - i].Item1 == 0)
                    {
                        return(null);
                    }
                    g.AddEdge(t[count - 1].Item2, t[count - 2 - i].Item2);
                    t[count - 2 - i] = (t[count - 2 - i].Item1 - 1, t[count - 2 - i].Item2);
                }

                t.RemoveAt(count - 1);
                count--;

                t.Sort();
            }


            return(g);
        }
Ejemplo n.º 16
0
        public static Graph changeVerticesNumeration(Graph g)
        {
            int[] perm = permutation(g.VerticesCount);
            Graph gnew = new AdjacencyListsGraph <SimpleAdjacencyList>(false, g.VerticesCount);

            for (int i = 0; i < g.VerticesCount; i++)
            {
                foreach (Edge e in g.OutEdges(i))
                {
                    gnew.AddEdge(perm[e.From], perm[e.To]);
                }
            }
            return(gnew);
        }
        //Część 2
        // Konstruowanie grafu na podstawie podanego ciągu grafowego
        // 1.5 pkt
        public Graph ConstructGraph(int[] sequence)
        {
            if (sequence == null)
            {
                return(null);
            }
            if (!IsGraphic(sequence))
            {
                return(null);
            }
            AdjacencyListsGraph <SimpleAdjacencyList> g = new AdjacencyListsGraph <SimpleAdjacencyList>(false, sequence.Length);
            List <(int, int)> lista = new List <(int, int)>();

            sequence = sequence.OrderByDescending(x => x).ToArray();
            for (int i = 0; i < sequence.Length; i++)
            {
                lista.Add((i, sequence[i]));
Ejemplo n.º 18
0
        //Część 3
        // Wyznaczanie minimalnego drzewa (bądź lasu) rozpinającego algorytmem Kruskala
        // 2 pkt
        public Graph MinimumSpanningTree(Graph graph, out double min_weight)
        {
            if (graph.Directed == true)
            {
                throw new ArgumentException();
            }

            EdgesMinPriorityQueue edges   = new EdgesMinPriorityQueue();
            Predicate <Edge>      wyjscie = delegate(Edge a)
            {
                if (a.From < a.To)
                {
                    edges.Put(a);
                }
                return(true);
            };

            graph.GeneralSearchAll <EdgesStack>(null, null, wyjscie, out int cc);

            UnionFind union = new UnionFind(graph.VerticesCount);
            Graph     graf  = new AdjacencyListsGraph <SimpleAdjacencyList>(false, graph.VerticesCount);

            min_weight = 0;
            int ile_wstawione_krawedzi = 0;
            int ile_wierzcholkow       = graph.VerticesCount;

            while (edges.Empty == false)
            {
                Edge e = edges.Get();
                if (union.Find(e.From) != union.Find(e.To))
                {
                    union.Union(e.From, e.To);
                    graf.AddEdge(e);
                    min_weight += e.Weight;
                    ile_wstawione_krawedzi++;
                }

                if (ile_wstawione_krawedzi == ile_wierzcholkow - 1)
                {
                    break;
                }
            }
            return(graf);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Procedura określająca czy drużyna jest wyeliminowana z rozgrywek
        /// </summary>
        /// <param name="teamId">indeks drużyny do sprawdzenia</param>
        /// <param name="teams">lista zespołów</param>
        /// <param name="predictedResults">wyniki gwarantujące zwycięstwo sprawdzanej drużyny</param>
        /// <returns></returns>
        public static bool IsTeamEliminated(int teamId, Team[] teams, out int[,] predictedResults)
        {
            predictedResults = null;
            int n = teams.Length;

            Graph g = new AdjacencyListsGraph <SimplyAdjacencyList>(true, (n * (n - 1)) / 2 + n + 2);
            int   s = g.VerticesCount - 2;
            int   t = g.VerticesCount - 1;

            // krawędzie drużyna -> ujście
            for (int i = 0; i < n; i++)
            {
                g.AddEdge(i, t, teams[teamId].NumberOfWins + teams[teamId].NumberOfGamesToPlay - teams[i].NumberOfWins);
            }

            int v = n;

            for (int i = 0; i < n; i++)
            {
                for (int j = i; j < n; j++)
                {
                    g.AddEdge(s, v, teams[i].NumberOfGamesToPlayByTeam[j]);
                    g.AddEdge(v, i, int.MaxValue);
                    g.AddEdge(v, j, int.MaxValue);
                    v++;
                }
            }
            Graph flow;

            g.FordFulkersonMaxFlow(s, t, out flow);

            foreach (Edge e in flow.OutEdges(s))
            {
                if (e.Weight < g.GetEdgeWeight(s, e.To).Value)
                {
                    return(false);
                }
            }

            return(true);
        }
Ejemplo n.º 20
0
        public static Graph rawHelm()
        {
            int verticesCount = rnd.Next(4, 1000);

            if (verticesCount % 2 == 0)
            {
                verticesCount++;
            }
            Graph helm = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            int   i;
            int   ringSize = verticesCount / 2;

            for (i = 1; i <= ringSize; i++)   // 1:ringSize is first cycle; ringsize+1:2*ringSize is second cycle
            {
                helm.AddEdge(new Edge(i - 1, i));
                helm.AddEdge(new Edge(0, i));
                helm.AddEdge(new Edge(i, ringSize + i));     // connecting outer vertices
            }
            helm.AddEdge(new Edge(ringSize, 1));
            return(helm);
        }
Ejemplo n.º 21
0
        // ETAP 1 i 2
        public int FindShortestPath(char[,] maze, bool withDynamite, out string path, int t = 0)
        {
            path = "";
            int X = maze.GetLength(1);
            int Y = maze.GetLength(0);

            int start = -1;
            int end   = -1;
            AdjacencyListsGraph <AVLAdjacencyList> g = new AdjacencyListsGraph <AVLAdjacencyList>(true, X * Y);

            PathsInfo[] p = null;

            if (t == 0)
            {
                createGraph(maze, g, out start, out end);
            }
            else
            {
                createGraph(maze, g, t, out start, out end);
            }
            ShortestPathsGraphExtender.DijkstraShortestPaths(g, start, out p);
            int dist = (int)p[end].Dist;

            if (!Double.IsNaN(p[end].Dist))
            {
                if (X > 1)
                {
                    path = constructString(PathsInfo.ConstructPath(start, end, p));
                }
                else
                {
                    path = constructString1xN(PathsInfo.ConstructPath(start, end, p));
                }
                return(dist);
            }
            else
            {
                return(-1);
            }
        }
Ejemplo n.º 22
0
        private void button1_Click(object sender, EventArgs e)
        {
            Random rand = new Random();
            int    x    = 100;
            int    y    = 100;
            IGraph g    = new AdjacencyListsGraph(false, x * y);

            for (int i = 0; i < x; i++)
            {
                for (int j = 0; j < y; j++)
                {
                    if (rand.Next(0, 3) != 3)
                    {
                        g.AddEdge(i, j, rand.Next(1, 3));
                    }
                }
            }
            textBox1.Text = "";

            Edge[] path;

            int s = 3, t = 24;

            g.DelEdge(s, t);

            Stopwatch sw = new Stopwatch();

            sw.Start();

            if (g.AStar(s, t, out path))
            {
                foreach (var p in path)
                {
                    textBox1.Text += p.From + ",";
                }
                textBox1.Text += t;
            }

            textBox2.Text = sw.Elapsed.Milliseconds.ToString();
        }
Ejemplo n.º 23
0
        public static void WeightedTest()
        {
            Console.Out.WriteLine("Grafy ważone");

            Graph grid3 = new AdjacencyListsGraph <SimpleAdjacencyList>(false, 9);

            for (int i = 0; i < 9; i += 3)
            {
                grid3.AddEdge(i, i + 1, 3);
                grid3.AddEdge(i + 1, i + 2, 2);
            }

            for (int i = 0; i < 3; i++)
            {
                grid3.AddEdge(i + 0, i + 3, 2);
                grid3.AddEdge(i + 3, i + 6, 1);
            }

            RandomGraphGenerator rgg = new RandomGraphGenerator(240044);
            Graph eCycle24           = rgg.UndirectedCycle(typeof(AdjacencyListsGraph <SimpleAdjacencyList>), 24, 1, 5, true);
            Graph oCycle23           = rgg.UndirectedCycle(typeof(AdjacencyListsGraph <SimpleAdjacencyList>), 23, 1, 5, true);
            Graph g3 = rgg.UndirectedGraph(typeof(AdjacencyListsGraph <SimpleAdjacencyList>), 20, 0.2, 1, 11, true);


            TestSet set2 = new TestSet();

            set2.TestCases.Add(new MatchingTestCase(10, grid3, 0, 4, 5));
            set2.TestCases.Add(new MatchingTestCase(10, grid3, 1, 5, 7));
            set2.TestCases.Add(new MatchingTestCase(10, grid3, 2 * grid3.EdgesCount - grid3.VerticesCount, grid3.EdgesCount, 3 + 6 + 6 + 9));
            set2.TestCases.Add(new MatchingTestCase(10, grid3, 2 * grid3.EdgesCount - grid3.VerticesCount - 1, grid3.EdgesCount - 1, 3 + 6 + 6 + 6));
            set2.TestCases.Add(new MatchingTestCase(10, eCycle24, 0, 12, 33));
            set2.TestCases.Add(new MatchingTestCase(10, oCycle23, 0, 11, 30));
            set2.TestCases.Add(new MatchingTestCase(10, eCycle24, 1, 12, 24));
            set2.TestCases.Add(new MatchingTestCase(10, oCycle23, 1, 12, 32));
            set2.TestCases.Add(new MatchingTestCase(10, g3, 0, 10, 45));
            set2.TestCases.Add(new MatchingTestCase(10, g3, 2, 11, 43));
            set2.TestCases.Add(new MatchingTestCase(10, g3, 3, 11, 35));

            set2.PreformTests(true, false);
        }
Ejemplo n.º 24
0
        public static Graph cycle()
        {
            int   verticesCount = rnd.Next(3, 100);
            Graph cycle         = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);

            for (int i = 1; i < verticesCount; i++)
            {
                cycle.AddEdge(i - 1, i);
            }
            cycle.AddEdge(0, verticesCount - 1);
            cycle = changeVerticesNumeration(cycle);
            //FOR USER - checking changeVerticesNumeration

            /*
             * if (cycle.VerticesCount < 11)
             * {
             *  int vert = 0;
             *  int vold = -1;
             *  int v = 0;
             *  Console.Write("vert count = " + verticesCount);
             *  Console.WriteLine();
             *  Edge e; ;
             *  do
             *  {
             *      Console.Write(v + " ");
             *      e = cycle.OutEdges(v).ToArray()[0];
             *      if (e.To == vold || e.From == vold)
             *          e = cycle.OutEdges(v).ToArray()[1];
             *      vold = v;
             *      if (vold == e.To)
             *          v = e.From;
             *      else
             *          v = e.To;
             *  }
             *  while (v != vert);
             *  Console.WriteLine();
             * }
             */
            return(cycle);
        }
Ejemplo n.º 25
0
        static Graph randomRegularBipartite(int vertices, int degree, int seed)
        {
            Random rand = new Random(seed);
            Graph  ret  = new AdjacencyListsGraph <HashTableAdjacencyList>(false, 2 * vertices);

            for (int j = 0; j < degree; j++)
            {
                for (int i = 0; i < vertices; i++)
                {
                    int curi = i;
                    int v2   = -1;
                    while (true)
                    {
                        v2 = 2 * rand.Next(vertices) + 1;
                        //while (ret.OutDegree(v2) != j)
                        //    v2 = 2 * rand.Next(vertices) + 1;
                        while (!ret.GetEdgeWeight(2 * curi, v2).IsNaN())
                        {
                            v2 = 2 * rand.Next(vertices) + 1;
                        }
                        if (ret.OutDegree(v2) != j)
                        {
                            int tmpi = ret.OutEdges(v2).ToArray()[rand.Next(ret.OutDegree(v2))].To / 2;
                            while (ret.OutDegree(2 * tmpi) != j + 1)
                            {
                                tmpi = ret.OutEdges(v2).ToArray()[rand.Next(ret.OutDegree(v2))].To / 2;
                            }
                            ret.DelEdge(2 * tmpi, v2);
                            ret.AddEdge(2 * curi, v2);
                            curi = tmpi;
                            continue;
                        }
                        break;
                    }
                    ret.AddEdge(2 * curi, v2);
                }
            }
            return(ret);
        }
        internal static Graph BuildSeekFlowGraph(int teamId, Team[] teams)
        {
            int teamsCount     = teams.Length;
            int pairLayerCount = (int)GetBinCoeff(teamsCount - 1, 2);
            int teamLayerCount = teamsCount - 1;
            int verticesCount  = 2 + pairLayerCount + teamLayerCount;

            Graph h = new AdjacencyListsGraph <SimpleAdjacencyList>(true, verticesCount);    //Directed

            // start - 0
            // target - 1
            // team pairs - 2 => 2 + pairLayerCount
            // teams - 2 + pairLayerCount => verticesCount
            var matchesToPlayBetweenTeams = new int[pairLayerCount];

            for (int i = 0; i < pairLayerCount + 1; i++)
            {
                if (i != teamId)    //If not input team
                {
                    for (int j = i + 1; j < teamsCount; j++)
                    {
                        if (j != teamId)                                                          //if not corresponding to input team
                        {
                            matchesToPlayBetweenTeams[i] = teams[i].NumberOfGamesToPlayByTeam[j]; //Number of games to play by team pairs
                        }
                    }
                }
            }
            for (int i = 0; i < pairLayerCount; i++)
            {
                if (i != teamId)
                {
                    for (int j = i + 1; j < teamsCount; j++)
                    {
                        h.AddEdge(0, i, matchesToPlayBetweenTeams[i]);
                    }
                }
            }
        }
Ejemplo n.º 27
0
        public static Graph eulerian2()
        {
            int   verticesCount = rnd.Next(4, 1000);
            Graph hamiltonian = new AdjacencyListsGraph <SimpleAdjacencyList>(false, verticesCount);
            int   timesInStartVertice = rnd.Next(1, verticesCount / 2);
            int   timesInStartv = 0;
            int   v = 0; int t;

            while (timesInStartv < timesInStartVertice)
            {
                do
                {
                    t = rnd.Next(0, verticesCount);
                } while (t == v);
                hamiltonian.AddEdge(v, t);
                v = t;
                if (v == 0)
                {
                    timesInStartv += 2;
                }
            }
            return(changeVerticesNumeration(hamiltonian));
        }
Ejemplo n.º 28
0
        //Część 2
        // Konstruowanie grafu na podstawie podanego ciągu grafowego
        // 1.5 pkt
        public Graph ConstructGraph(int[] sequence)
        {
            Graph wynik = new AdjacencyListsGraph <SimpleAdjacencyList>(false, sequence.Length);

            if (IsGraphic(sequence) == false)
            {
                return(null);
            }

            List <KeyValuePair <int, int> > listapar = new List <KeyValuePair <int, int> >();

            for (int i = 0; i < sequence.Length; i++)
            {
                KeyValuePair <int, int> el = new KeyValuePair <int, int>(i, sequence[i]);
                listapar.Add(el);
            }

            while (listapar.Count > 0)
            {
                listapar.Sort((x, y) =>
                {
                    return(-x.Value.CompareTo(y.Value));
                });
                for (int j = 1; j <= listapar[0].Value && j < listapar.Count; j++)
                {
                    wynik.AddEdge(listapar[0].Key, listapar[j].Key);
                    wynik.AddEdge(listapar[j].Key, listapar[0].Key);

                    listapar[j] = new KeyValuePair <int, int>(listapar[j].Key, listapar[j].Value - 1);
                }
                listapar.RemoveAt(0);
            }


            return(wynik);
        }
Ejemplo n.º 29
0
        public static IGraph CreateSimpleGraph(this GameMap gameMap, List <Fighter> fighters, List <Enemy> enemies, Vector2 start, Vector2 end)
        {
            Point  p1 = start.GetMapPosition(gameMap);
            Point  p2 = start.GetMapPosition(gameMap);
            IGraph g;

            if ((Math.Abs(p1.X - p2.X) + 4) * (Math.Abs(p1.Y - p2.Y) + 4) < 100)
            {
                g = new AdjacencyListsGraph(false, (Math.Abs(p1.X - p2.X) + 4) * (Math.Abs(p1.Y - p2.Y) + 4));
            }
            else
            {
                g = new AdjacencyListsGraph(false, 100); // TODO do poprawy
            }

            /*
             * Point sourceMap = source.GetMapPosition(gameMap);
             * Point destinationMap = source.GetMapPosition(gameMap);
             * Point shift = new Point((int)Math.Min(sourceMap.X, destinationMap.X), (int)Math.Min(sourceMap.Y, destinationMap.Y));
             *
             * IGraph g = new AdjacencyMatrixGraph(false,(int)(Math.Abs(destinationMap.X-sourceMap.X+4)*Math.Abs(destinationMap.Y-sourceMap.Y+4)));
             *
             * for (int i = -2; i < destinationMap.X - sourceMap.X + 2; i++)
             * {
             *  for (int j = -2; j < destinationMap.Y - sourceMap.Y + 2; j++)
             *  {
             *      if (shift.X+i >= 0 && shift.X+i < gameMap.width && shift.Y + j - 2 >=0 && shift.Y+j-2 < gameMap.height && gameMap[shift.X + i, shift.Y + j - 2].mapObjects.Count == 0)
             *      {
             *          //g.AddEdge((int)( j * (destinationMap.X - sourceMap.X + 4) + i ),(int)( (j - 2) * (destinationMap.X - sourceMap.X + 4) + i - 1 ));
             *      }
             *  }
             * }
             */

            return(g);
        }
Ejemplo n.º 30
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();
    }
Ejemplo n.º 31
0
        static void Main(string[] args)
        {
            try
            {
                var    rgg = new RandomGraphGenerator(123);
                IGraph h1, h2;
                IGraph g1 = new AdjacencyMatrixGraph(false, 5);
                IGraph g2 = new AdjacencyListsGraph(true, 4);
                Console.WriteLine("# licznik: {0}", Graph.Counter);

                g1.AddEdge(0, 1);
                g1.AddEdge(1, 2);
                g1.AddEdge(0, 2);
                g1.AddEdge(0, 4);
                g1.AddEdge(2, 4);
                g1.AddEdge(2, 3);
                Console.WriteLine("# licznik: {0}", Graph.Counter);
                Console.WriteLine("Graf g1 jest typu: {0} i jest skierowany: {1}", g1.GetType(), g1.Directed);


                h1 = g1.AddVertex();
                Console.WriteLine("\nDodawanie\nGraf h1 ma {0} (powinno być 6) wierzchołków, a ostatni wierzchołek ma stopień {1} (powinno być 0)",
                                  h1.VerticesCount, h1.InDegree(h1.VerticesCount - 1));
                Console.WriteLine("Graf h1 ma {0} (powinno być 6) krawędzi", h1.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h1 = g1.DeleteVertex(2);
                Console.WriteLine("\nUsuwanie\nGraf h1 ma {0} (powinno być 4) wierzchołków, a wierzchołki 1,2,3 mają odpowiednio stopienie {1} (powinno być 1),{2} (powinno być 0),{3} (powinno być 1)",
                                  h1.VerticesCount, h1.InDegree(1), h1.InDegree(2), h1.InDegree(3));
                Console.WriteLine("Graf h1 ma {0} (powinno być 2) krawędzi", h1.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h1 = g1.Complement();
                Console.WriteLine("\nDopełnienie g1 ma {0} (powinno być 4) krawędzi", h1.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h1 = g1.Closure();
                Console.WriteLine("\nDomknięcie g1 ma {0} (powinno być 10) krawędzi", h1.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);

                h1 = (g1.AddVertex()).Closure();
                Console.WriteLine("Domknięcie g1 + K1 ma {0} (powinno być 10) krawędzi", h1.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                Console.WriteLine("\nCzy h1 jest dwudzielny ?: {0} (powinno być False)", h1.IsBipartite());
                Console.WriteLine("# licznik: {0}", Graph.Counter);

                h1 = rgg.BipariteGraph(typeof(AdjacencyMatrixGraph), 30, 50, 0.5);
                Console.WriteLine("\nCzy nowy h1 jest dwudzielny ?: {0} (powinno być True)", h1.IsBipartite());
                Console.WriteLine("# licznik: {0}", Graph.Counter);

                Console.WriteLine("\n\n*************************\n\n");
                g2.AddEdge(0, 1);
                g2.AddEdge(2, 1);
                g2.AddEdge(3, 2);
                Console.WriteLine("# licznik: {0}", Graph.Counter);
                Console.WriteLine("Graf g2 jest typu: {0} i jest skierowany: {1}", g2.GetType(), g2.Directed);

                h2 = g2.AddVertex();
                Console.WriteLine("\nDodawanie\nGraf h2 ma {0} (powinno być 5) wierzchołków, a ostatni wierzchołek ma stopień wy: {1} (powinno być 0) i we: {2} (powinno być 0) ",
                                  h2.VerticesCount, h2.InDegree(h2.VerticesCount - 1), h2.OutDegree(h2.VerticesCount - 1));
                Console.WriteLine("Graf h2 ma {0} (powinno być 3) krawędzi", h2.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h2 = g2.DeleteVertex(1);
                Console.WriteLine("\nUsuwanie\nGraf h2 ma {0} (powinno być 3) wierzchołków, a wierzchołek 1 ma stopień wy: {1} (powinno być 0) ", h2.VerticesCount, h2.OutDegree(1));
                Console.WriteLine("Graf h2 ma {0} (powinno być 1) krawędzi", h2.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h2 = g2.Complement();
                Console.WriteLine("\nDopełnienie g2 ma {0} (powinno być 9) krawędzi", h2.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                h2 = g2.Closure();
                Console.WriteLine("\nDomknięcie g2 + K1 ma {0} (powinno być 4) krawędzi", h2.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);

                h2 = (g2.AddVertex()).Closure();
                Console.WriteLine("Domknięcie g2 + K1 ma {0} (powinno być 4) krawędzi", h2.EdgesCount);
                Console.WriteLine("# licznik: {0}", Graph.Counter);


                Console.WriteLine("\nCzy h2 jest dwudzielny ?: {0} (powinno być False)", g2.IsBipartite());
                Console.WriteLine("# licznik: {0}", Graph.Counter);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Dodaje 2 cykle fundamentalne
        /// </summary>
        /// <param name="c1">Pierwszy cykl</param>
        /// <param name="c2">Drugi cykl</param>
        /// <returns>null, jeśli wynikiem nie jest cykl i suma cykli, jeśli wynik jest cyklem</returns>
        public Edge[] AddFundamentalCycles(Edge[] c1, Edge[] c2)
        {
            int maxV = 0;

            foreach (Edge e in c1)
            {
                if (e.To > maxV)
                {
                    maxV = e.To;
                }
            }
            foreach (Edge e in c2)
            {
                if (e.To > maxV)
                {
                    maxV = e.To;
                }
            }
            Graph g = new AdjacencyListsGraph <SimpleAdjacencyList>(false, maxV + 1);

            foreach (Edge e in c1)
            {
                g.AddEdge(e);
            }
            foreach (Edge e in c2)
            {
                if (g.GetEdgeWeight(e.From, e.To).IsNaN())
                {
                    g.AddEdge(e);
                }
                else
                {
                    g.DelEdge(e);
                }
            }
            Edge[] result    = null;
            bool   moreEdges = false;

            bool[]           visited   = new bool[g.VerticesCount];
            List <Edge>      edgesList = new List <Edge>();
            Predicate <Edge> onNewEdge = delegate(Edge e)
            {
                if (edgesList.Count > 0 && e.To == edgesList[0].From && e.From != edgesList[0].To)
                {
                    edgesList.Add(e);
                    result = edgesList.ToArray();
                }
                else if (!visited[e.To])
                {
                    if (result == null)
                    {
                        edgesList.Add(e);
                    }
                    else
                    {
                        moreEdges = true;
                        return(false);
                    }
                }
                return(true);
            };
            Predicate <int> onEntering = delegate(int n)
            {
                visited[n] = true;
                return(true);
            };

            g.GeneralSearchAll <EdgesStack>(onEntering, null, onNewEdge, out _);
            if (moreEdges || result == null)
            {
                return(null);
            }
            else
            {
                return(result);
            }
        }
        public static IGraph CreateSimpleGraph(this GameMap gameMap, List<Fighter> fighters, List<Enemy> enemies, Vector2 start, Vector2 end)
        {
            Point p1 = start.GetMapPosition(gameMap);
            Point p2 = start.GetMapPosition(gameMap);
            IGraph g;
            if ((Math.Abs(p1.X - p2.X) + 4) * (Math.Abs(p1.Y - p2.Y) + 4) < 100)
                g = new AdjacencyListsGraph(false, (Math.Abs(p1.X - p2.X) + 4) * (Math.Abs(p1.Y - p2.Y) + 4));
            else
                g = new AdjacencyListsGraph(false, 100); // TODO do poprawy

            /*
            Point sourceMap = source.GetMapPosition(gameMap);
            Point destinationMap = source.GetMapPosition(gameMap);
            Point shift = new Point((int)Math.Min(sourceMap.X, destinationMap.X), (int)Math.Min(sourceMap.Y, destinationMap.Y));

            IGraph g = new AdjacencyMatrixGraph(false,(int)(Math.Abs(destinationMap.X-sourceMap.X+4)*Math.Abs(destinationMap.Y-sourceMap.Y+4)));

            for (int i = -2; i < destinationMap.X - sourceMap.X + 2; i++)
            {
                for (int j = -2; j < destinationMap.Y - sourceMap.Y + 2; j++)
                {
                    if (shift.X+i >= 0 && shift.X+i < gameMap.width && shift.Y + j - 2 >=0 && shift.Y+j-2 < gameMap.height && gameMap[shift.X + i, shift.Y + j - 2].mapObjects.Count == 0)
                    {
                        //g.AddEdge((int)( j * (destinationMap.X - sourceMap.X + 4) + i ),(int)( (j - 2) * (destinationMap.X - sourceMap.X + 4) + i - 1 ));
                    }
                }
            }
            */

            return g;
        }