public static List<int> DijkstraAlgorithm(Dictionary<Node,Dictionary<Node,int>> graph, Dictionary<int,Node> nodes, int sourceNode, int destinationNode)
        {
            int[] previous = new int[graph.Count];
            bool[] visited = new bool[graph.Count];
            PriorityQueue<Node> priorityQueue = new PriorityQueue<Node>();
            var startNode = nodes[sourceNode];
            startNode.DistanceFromStart = 0;

            for (int i = 0; i < previous.Length; i++)
            {
                previous[i] = -1;
            }

            priorityQueue.Enqueue(startNode);

            while (priorityQueue.Count > 0)
            {
                var currentNode = priorityQueue.ExtractMin();

                if (currentNode.Index == destinationNode)
                {
                    break;
                }

                foreach (var edge in graph[currentNode])
                {
                    if (!visited[edge.Key.Index])
                    {
                        priorityQueue.Enqueue(edge.Key);
                        visited[edge.Key.Index] = true;
                    }

                    var distance = currentNode.DistanceFromStart + edge.Value;
                    if (distance < edge.Key.DistanceFromStart)
                    {
                        edge.Key.DistanceFromStart = distance;
                        previous[edge.Key.Index] = currentNode.Index;
                        priorityQueue.DecreaseKey(edge.Key);
                    }
                }
            }

            if (previous[destinationNode] == -1)
            {
                return null;
            }

            List<int> path = new List<int>();
            int current = destinationNode;
            while (current != -1)
            {
                path.Add(current);
                current = previous[current];
            }

            path.Reverse();
            return path;
        }
        public static void Main()
        {
            int nodesCount = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();
            int edgesCount = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();

            var queue = new PriorityQueue<Edge>();
            for (int i = 0; i < edgesCount; i++)
            {
                int[] edgeArgs = Console.ReadLine().Split().Select(int.Parse).ToArray();
                var edge = new Edge(edgeArgs[0], edgeArgs[1], edgeArgs[2]);
                queue.Enqueue(edge);
            }

            var nodes = new int[nodesCount];
            for (int i = 1; i < nodesCount; i++)
            {
                nodes[i] = i;
            }

            var resultMst = new List<Edge>();
            int mstWeight = 0;
            while (queue.Count > 0)
            {
                var minEdge = queue.ExtractMin();
                int from = minEdge.From;
                int to = minEdge.To;
                int weight = minEdge.Weight;
                int fromRoot = FindRoot(from, nodes);
                int toRoot = FindRoot(to, nodes);
                if (fromRoot != toRoot)
                {
                    resultMst.Add(minEdge);
                    MergeTrees(fromRoot, to, nodes);
                    mstWeight += weight;
                }
            }

            Console.WriteLine("Minimum spanning fores weight: " + mstWeight);
            Console.WriteLine(string.Join(Environment.NewLine, resultMst));
        }
        public static void Main()
        {
            int budget = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();
            int nodes = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();
            int edges = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();

            var usedVertex = new bool[nodes];
            var graph = new List<Edge>[nodes];
            for (int i = 0; i < nodes; i++)
            {
                graph[i] = new List<Edge>();
            }

            var priorityQueue = new PriorityQueue<Edge>();
            for (int i = 0; i < edges; i++)
            {
                string[] edgeAsString = Console.ReadLine().Split();
                int from = int.Parse(edgeAsString[0]);
                int to = int.Parse(edgeAsString[1]);
                int weight = int.Parse(edgeAsString[2]);
                var edge = new Edge(from, to, weight);
                graph[from].Add(edge);
                graph[to].Add(edge);

                if (edgeAsString.Length == 4)
                {
                    usedVertex[from] = true;
                    usedVertex[to] = true;
                }
            }

            for (int i = 0; i < nodes; i++)
            {
                if (usedVertex[i])
                {
                    foreach (var edge in graph[i])
                    {
                        priorityQueue.Enqueue(edge);
                    }
                }
            }

            var result = new List<Edge>();
            int budgetUsed = 0;

            while (priorityQueue.Count > 0)
            {
                var minEdge = priorityQueue.ExtractMin();
                int from = minEdge.From;
                int to = minEdge.To;
                int weight = minEdge.Weight;

                if ((usedVertex[from] && !usedVertex[to]) ||
                    (usedVertex[to] && !usedVertex[from]))
                {
                    budget -= weight;
                    if (budget < 0)
                    {
                        break;
                    }

                    if (!usedVertex[from])
                    {
                        foreach (var edge in graph[from])
                        {
                            priorityQueue.Enqueue(edge);
                        }
                    }
                    else
                    {
                        foreach (var edge in graph[to])
                        {
                            priorityQueue.Enqueue(edge);
                        }
                    }

                    budgetUsed += weight;
                    result.Add(minEdge);
                    usedVertex[from] = true;
                    usedVertex[to] = true;
                }
            }

            Console.WriteLine(string.Join(Environment.NewLine, result));
            Console.WriteLine("Budget used: " + budgetUsed);
        }
示例#4
0
        Vector2 GetTerrainPosition(Texture2D heightmap, Vector2 shapeScale, Vector2 heightRange, out float heightAtPosition, out float thetaAtPosition, List<Vector3> placedShapes)
        {
            Vector2 invRes = new Vector2(1.0f / (float)heightmap.Width, 1.0f / (float)heightmap.Height);

            RenderTarget2D rtVariance = new RenderTarget2D(GFX.Device, heightmap.Width, heightmap.Height, 1, SurfaceFormat.Vector2);
            RenderTarget2D rtNormal = new RenderTarget2D(GFX.Device, heightmap.Width, heightmap.Height, 1, SurfaceFormat.Vector2);
            GFX.Device.Textures[0] = heightmap;
            varianceShader.SetupShader();
            GFX.Device.SetVertexShaderConstant(GFXShaderConstants.VC_INVTEXRES, invRes);
            GFX.Device.SetPixelShaderConstant(0, invRes);
            GFX.Device.SetRenderTarget(0, rtVariance);
            GFXPrimitives.Quad.Render();
            GFX.Device.SetRenderTarget(0, null);

            GFX.Device.SetRenderTarget(0, rtNormal);
            gradientShader.SetupShader();
            GFXPrimitives.Quad.Render();
            GFX.Device.SetRenderTarget(0, null);
            GFX.Device.Textures[0] = null;

            int bufferSize = heightmap.Width * heightmap.Height;
            float[] heightData = new float[bufferSize];
            Vector2[] varianceData = new Vector2[bufferSize];
            rtVariance.GetTexture().GetData<Vector2>(varianceData);
            Vector2[] gradientData = new Vector2[rtNormal.Width * rtNormal.Height];
            rtNormal.GetTexture().GetData<Vector2>(gradientData);

            switch (heightmap.Format)
            {
                case SurfaceFormat.Single:
                    heightmap.GetData<float>(heightData);
                    break;
                case SurfaceFormat.Color:
                    Color[] colorData = new Color[bufferSize];
                    heightmap.GetData<Color>(colorData);
                    float invScale = 1.0f / 255.0f;
                    for (int i = 0; i < colorData.Length; i++)
                        heightData[i] = (float)colorData[i].R * invScale;
                    break;
            }

            List<Int2D> availableSpots = new List<Int2D>();
            for (int x = 0; x < heightmap.Width; x++)
            {
                for (int y = 0; y < heightmap.Height; y++)
                {
                    int index = x + y * heightmap.Width;
                    if (varianceData[index].Y >= heightRange.X && varianceData[index].Y <= heightRange.Y)
                    {
                        /*
                        Vector2 currPos = new Vector2(x, y) * invRes * 2.0f - Vector2.One;
                        bool canPlace = true;
                        for(int i = 0; i < placedShapes.Count; i++)
                        {
                            if (Vector2.Distance(currPos, new Vector2(placedShapes[i].X, placedShapes[i].Y)) <= placedShapes[i].Z)
                            {
                                canPlace = false;
                                break;
                            }
                        }
                        if(canPlace)*/
                            availableSpots.Add(new Int2D(x, y));
                    }
                }
            }

            for (int i = 0; i < availableSpots.Count; i++)
            {
                Int2D temp = availableSpots[i];
                int randIndex = RandomHelper.RandomGen.Next(i, availableSpots.Count);
                availableSpots[i] = availableSpots[randIndex];
                availableSpots[randIndex] = temp;
            }

            PriorityQueue<float, Int2D> plantSpots = new PriorityQueue<float, Int2D>();
            for (int i = 0; i < availableSpots.Count; i++)
            {
                int index = availableSpots[i].X + availableSpots[i].Y * heightmap.Width;
                Vector2 currPos = new Vector2(availableSpots[i].X, availableSpots[i].Y) * invRes * 2.0f - Vector2.One;
                float netPriority = 0;
                for (int j = 0; j < placedShapes.Count; j++)
                {
                    float radius = Vector2.Distance(currPos, new Vector2(placedShapes[j].X, placedShapes[j].Y)) * placedShapes[j].Z;
                    if (radius == 0.0f)
                        radius = 0.001f;
                        netPriority += 1.0f / (radius * radius);

                }
                plantSpots.Enqueue(availableSpots[i], varianceData[index].X + netPriority);
            }

            Int2D randPos = plantSpots.ExtractMin();// availableSpots[RandomHelper.RandomGen.Next(0, availableSpots.Count)];
            Vector2 pos = new Vector2(randPos.X, randPos.Y) * invRes * 2.0f - Vector2.One;
            int placedIndex = randPos.X + randPos.Y * heightmap.Width;
            heightAtPosition = varianceData[placedIndex].Y;
            thetaAtPosition = (float)Math.Atan2(gradientData[placedIndex].Y, gradientData[placedIndex].X);
            return pos;
        }
        public static void Main()
        {
            int rows = int.Parse(Console.ReadLine());
            int cols = int.Parse(Console.ReadLine());
            var matrix = new Cell[rows, cols];
            for (int i = 0; i < rows; i++)
            {
                int[] currentRow = Console.ReadLine().Split().Select(int.Parse).ToArray();
                for (int j = 0; j < cols; j++)
                {
                    matrix[i, j] = new Cell(i, j, currentRow[j]);
                }
            }

            matrix[0, 0].DijkstraDistance = 0;
            var queue = new PriorityQueue<Cell>();
            queue.Enqueue(matrix[0, 0]);
            while (queue.Count > 0)
            {
                var cell = queue.ExtractMin();
                int row = cell.Row;
                int col = cell.Col;

                if (IsValidCell(row, col + 1, rows, cols))
                {
                    var rightCell = matrix[row, col + 1];
                    if (rightCell.DijkstraDistance > cell.DijkstraDistance + rightCell.Value)
                    {
                        rightCell.DijkstraDistance = cell.DijkstraDistance + rightCell.Value;
                        rightCell.PreviousCell = cell;
                        if (queue.Contain(rightCell))
                        {
                            queue.DecreaseKey(rightCell);
                        }
                    }

                     if(!rightCell.IsVisited)
                    {
                        queue.Enqueue(rightCell);
                        rightCell.IsVisited = true;
                    }
                }

                if (IsValidCell(row + 1, col, rows, cols))
                {
                    var bottomCell = matrix[row + 1, col];
                    if (bottomCell.DijkstraDistance > cell.DijkstraDistance + bottomCell.Value)
                    {
                        bottomCell.DijkstraDistance = cell.DijkstraDistance + bottomCell.Value;
                        bottomCell.PreviousCell = cell;
                        if (queue.Contain(bottomCell))
                        {
                            queue.DecreaseKey(bottomCell);
                        }
                    }

                    if(!bottomCell.IsVisited)
                    {
                        queue.Enqueue(bottomCell);
                        bottomCell.IsVisited = true;
                    }
                }

                if (IsValidCell(row, col - 1, rows, cols))
                {
                    var leftCell = matrix[row, col - 1];
                    if (leftCell.DijkstraDistance > cell.DijkstraDistance + leftCell.Value)
                    {
                        leftCell.DijkstraDistance = cell.DijkstraDistance + leftCell.Value;
                        leftCell.PreviousCell = cell;
                        if (queue.Contain(leftCell))
                        {
                            queue.DecreaseKey(leftCell);
                        }
                    }

                    if(!leftCell.IsVisited)
                    {
                        queue.Enqueue(leftCell);
                        leftCell.IsVisited = true;
                    }
                }

                if (cell.Row == rows - 1 && cell.Col == cols -1)
                {
                    break;
                }
            }

            var lastCell = matrix[rows - 1, cols - 1];
            var path = new Stack<int>();
            while (lastCell != null)
            {
                path.Push(lastCell.Value);
                lastCell = lastCell.PreviousCell;
            }

            Console.WriteLine("Length: " + path.Sum());
            Console.WriteLine("Path: " + string.Join(" ", path));
        }
示例#6
0
        public static void Main()
        {
            int vertexCount = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();
            int[] startEndPoints = Console.ReadLine().Split(new[] { ' ', '-' }, StringSplitOptions.RemoveEmptyEntries).Skip(1).Select(int.Parse).ToArray();
            int edgesCount = Console.ReadLine().Split().Skip(1).Select(int.Parse).First();

            var graph = new Vertex[vertexCount];
            for (int i = 0; i < vertexCount; i++)
            {
                graph[i] = new Vertex(i);
            }

            for (int i = 0; i < edgesCount; i++)
            {
                int[] edgesArgs = Console.ReadLine().Split().Select(int.Parse).ToArray();
                int from = edgesArgs[0];
                int to = edgesArgs[1];
                int weight = edgesArgs[2];
                graph[from].Neighbors.Add(graph[to]);
                graph[to].Neighbors.Add(graph[from]);
                graph[from].Edges.Add(new Edge(to, weight));
                graph[to].Edges.Add(new Edge(from, weight));
            }

            int sourceVertex = startEndPoints[0];
            int destinationVertex = startEndPoints[1];
            graph[sourceVertex].DijkstraDistance = 100;
            var visitedVertex = new bool[vertexCount];
            visitedVertex[sourceVertex] = true;
            var queue = new PriorityQueue<Vertex>();
            queue.Enqueue(graph[sourceVertex]);

            while (queue.Count > 0)
            {
                var curentVertex = queue.ExtractMin();

                foreach (var edge in graph[curentVertex.Index].Edges)
                {
                    if (graph[edge.To].DijkstraDistance < curentVertex.DijkstraDistance * edge.Weight/100)
                    {
                        graph[edge.To].DijkstraDistance = curentVertex.DijkstraDistance * edge.Weight/100;
                        graph[edge.To].From = curentVertex.Index;
                    }
                }

                foreach (var neighbor in graph[curentVertex.Index].Neighbors)
                {
                    if (!visitedVertex[neighbor.Index])
                    {
                        visitedVertex[neighbor.Index] = true;
                        queue.Enqueue(neighbor);
                    }
                }
            }

            Console.WriteLine("Most reliable path reliability: {0:F2}%", graph[destinationVertex].DijkstraDistance);
            var pathVertex = new Stack<int>();
            pathVertex.Push(destinationVertex);
            while (graph[destinationVertex].Index != graph[destinationVertex].From)
            {
                destinationVertex = graph[destinationVertex].From;
                pathVertex.Push(destinationVertex);
            }

            Console.WriteLine(string.Join(" -> ", pathVertex));
        }
示例#7
0
        int[,] WaterShed(int[,] image)
        {
            int[,] watershedLine = new int[InputImage.Size.Width, InputImage.Size.Height];
            int[,] localMinima = new int[InputImage.Size.Width, InputImage.Size.Height];
            int[,] erosion = Erosion(image, 5);
            for (int y = InputImage.Size.Height - 1; y >= 0; y--)
            {
                for (int x = InputImage.Size.Width - 1; x >= 0; x--)
                {
                    bool lower = false;
                    for (int sx = -1; sx <= 1; sx++)
                    {
                        for (int sy = -1; sy <= 1; sy++)
                        {
                            if (x + sx > 0 && x + sx < image.GetLength(0) && y + sy > 0 && y + sy < image.GetLength(1) && image[x, y] < image[sx + x, sy + y])
                            {
                                lower = true;
                            }
                        }

                        if (erosion[x, y] == image[x, y] && lower)
                        {
                            localMinima[x, y] = 255;
                        }
                    }
                }
            }

            int[,] labeledMinima = FindObjects(localMinima);

            PriorityQueue q = new PriorityQueue();
            for (int y = InputImage.Size.Height - 1; y >= 0; y--)
            {
                for (int x = InputImage.Size.Width - 1; x >= 0; x--)
                {
                    if (labeledMinima[x, y] > 0)
                        q.Add(x, y, image[x, y], labeledMinima[x, y]);
                }
            }

            Tuple<int, int, int, int> min = q.ExtractMin();
            
            while(min!= null)
            {
                int x = min.Item1;
                int y = min.Item2;

                for (int sx = -1; sx <= 1; sx++)
                {
                    for (int sy = -1; sy <= 1; sy++)
                    {
                        if (x + sx > 0 && x + sx < image.GetLength(0) && y + sy > 0 && y + sy < image.GetLength(1))
                        {
                            if(labeledMinima[x+sx,y+sy] == 0 && image[x+sx,y+sy] != 255)
                            {
                                labeledMinima[x + sx, y + sy] = min.Item4;
                                q.Add(x + sx,y + sy,image[x,y],labeledMinima[x,y]);
                            }
                            else
                            {
                                if (labeledMinima[x + sx, y + sy] != labeledMinima[x, y] && labeledMinima[x+sx,y+sy] != 0)
                                    watershedLine[x + sx, y + sy] = 255;
                            }
                        }
                    }
                }
                min = q.ExtractMin();
            }
            
            return watershedLine;
        }