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); }
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)); }
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)); }
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; }