logo

Minimale kostenpad met bewegingen naar links, rechts, onder en omhoog toegestaan

Probeer het eens op GfG Practice ' title=

Gegeven een 2D-raster van grootte n*n waar elke cel de kosten vertegenwoordigt om door die cel te reizen, is het de taak om de minimale kosten om te verhuizen van de linksboven cel naar de rechtsonder cel. Vanuit een bepaalde cel kunnen we naar binnen gaan 4 richtingen : links rechts omhoog omlaag.

Opmerking: Er wordt aangenomen dat negatieve kostencycli niet voorkomen in de invoermatrix.

Madhubala

Voorbeeld:



Invoer: raster = {{9 4 9 9}
{6 7 6 4}
{8 3 3 7}
{7 4 9 10}}
Uitgang: 43
Uitleg: Het minimale kostenpad is 9 + 4 + 7 + 3 + 3 + 7 + 10.

Benadering:

Het idee is om te gebruiken Het algoritme van Dijkstra om het minimale kostenpad door het netwerk te vinden. Deze benadering behandelt het raster als een grafiek waarbij elke cel een knooppunt is en het algoritme onderzoekt dynamisch het meest kosteneffectieve pad naar de cel rechtsonder door altijd eerst de goedkoopste paden uit te breiden.

Stap voor stap aanpak:

die school maakte
  1. Gebruik een min-heap om altijd eerst het pad met de laagste kosten te verwerken en de cel linksboven erin te duwen.
  2. Initialiseer een kostenmatrix met maximale waarden, waarbij de kosten van de startcel worden ingesteld op de rasterwaarde.
  3. Controleer voor elke cel alle 4 aangrenzende cellen
    1. Als er een pad met lagere kosten wordt gevonden, werkt u de kosten van de cel bij en plaatst u deze in de hoop.
  4. Retourneer de minimale kosten om de cel rechtsonder te bereiken.

Hieronder vindt u de implementatie van de bovenstaande aanpak:

C++
// C++ program to find minimum Cost Path with  // Left Right Bottom and Up moves allowed #include    using namespace std; // Function to check if cell is valid. bool isValidCell(int i int j int n) {  return i>=0 && i<n && j>=0 && j<n; } int minimumCostPath(vector<vector<int>> &grid) {  int n = grid.size();    // Min heap to implement dijkstra  priority_queue<vector<int>   vector<vector<int>> greater<vector<int>>> pq;    // 2d grid to store minimum cost  // to reach every cell.  vector<vector<int>> cost(n vector<int>(n INT_MAX));  cost[0][0] = grid[0][0];    // Direction vector to move in 4 directions  vector<vector<int>> dir = {{-10} {10} {0-1} {01}};    pq.push({grid[0][0] 0 0});    while (!pq.empty()) {  vector<int> top = pq.top();  pq.pop();    int c = top[0] i = top[1] j = top[2];    // Check for all 4 neighbouring cells.  for (auto d: dir) {  int x = i + d[0];  int y = j + d[1];    // If cell is valid and cost to reach this cell   // from current cell is less  if (isValidCell(x y n) &&   cost[i][j]+grid[x][y]<cost[x][y]) {    // Update cost to reach this cell.  cost[x][y] = cost[i][j]+grid[x][y];    // Push the cell into heap.  pq.push({cost[x][y] x y});  }  }  }    // Return minimum cost to   // reach bottom right cell.  return cost[n-1][n-1]; } int main() {  vector<vector<int>> grid =   {{9499}{6764}{8337}{74910}};    cout << minimumCostPath(grid) << endl;    return 0; } 
Java
// Java program to find minimum Cost Path with  // Left Right Bottom and Up moves allowed import java.util.PriorityQueue; import java.util.Arrays; class GfG {  // Function to check if cell is valid.  static boolean isValidCell(int i int j int n) {  return i >= 0 && i < n && j >= 0 && j < n;  }  static int minimumCostPath(int[][] grid) {  int n = grid.length;    // Min heap to implement Dijkstra  PriorityQueue<int[]> pq =   new PriorityQueue<>((a b) -> Integer.compare(a[0] b[0]));    // 2D grid to store minimum cost  // to reach every cell.  int[][] cost = new int[n][n];  for (int[] row : cost) {  Arrays.fill(row Integer.MAX_VALUE);  }  cost[0][0] = grid[0][0];    // Direction vector to move in 4 directions  int[][] dir = {{-1 0} {1 0} {0 -1} {0 1}};    pq.offer(new int[]{grid[0][0] 0 0});    while (!pq.isEmpty()) {  int[] top = pq.poll();    int c = top[0] i = top[1] j = top[2];    // Check for all 4 neighbouring cells.  for (int[] d : dir) {  int x = i + d[0];  int y = j + d[1];    // If cell is valid and cost to reach this cell   // from current cell is less  if (isValidCell(x y n) && cost[i][j] + grid[x][y] < cost[x][y]) {    // Update cost to reach this cell.  cost[x][y] = cost[i][j] + grid[x][y];    // Push the cell into heap.  pq.offer(new int[]{cost[x][y] x y});  }  }  }    // Return minimum cost to   // reach bottom right cell.  return cost[n - 1][n - 1];  }  public static void main(String[] args) {  int[][] grid = {  {9 4 9 9}  {6 7 6 4}  {8 3 3 7}  {7 4 9 10}  };    System.out.println(minimumCostPath(grid));  } } 
Python
# Python program to find minimum Cost Path with  # Left Right Bottom and Up moves allowed import heapq # Function to check if cell is valid. def isValidCell(i j n): return i >= 0 and i < n and j >= 0 and j < n def minimumCostPath(grid): n = len(grid) # Min heap to implement Dijkstra pq = [] # 2D grid to store minimum cost # to reach every cell. cost = [[float('inf')] * n for _ in range(n)] cost[0][0] = grid[0][0] # Direction vector to move in 4 directions dir = [[-1 0] [1 0] [0 -1] [0 1]] heapq.heappush(pq [grid[0][0] 0 0]) while pq: c i j = heapq.heappop(pq) # Check for all 4 neighbouring cells. for d in dir: x y = i + d[0] j + d[1] # If cell is valid and cost to reach this cell  # from current cell is less if isValidCell(x y n) and cost[i][j] + grid[x][y] < cost[x][y]: # Update cost to reach this cell. cost[x][y] = cost[i][j] + grid[x][y] # Push the cell into heap. heapq.heappush(pq [cost[x][y] x y]) # Return minimum cost to  # reach bottom right cell. return cost[n - 1][n - 1] if __name__ == '__main__': grid = [ [9 4 9 9] [6 7 6 4] [8 3 3 7] [7 4 9 10] ] print(minimumCostPath(grid)) 
C#
// C# program to find minimum Cost Path with  // Left Right Bottom and Up moves allowed using System; using System.Collections.Generic; class GfG {  // Function to check if cell is valid.  static bool isValidCell(int i int j int n) {  return i >= 0 && i < n && j >= 0 && j < n;  }  static int minimumCostPath(int[][] grid) {  int n = grid.Length;    // Min heap to implement Dijkstra  var pq = new SortedSet<(int cost int x int y)>();    // 2D grid to store minimum cost  // to reach every cell.  int[][] cost = new int[n][];  for (int i = 0; i < n; i++) {  cost[i] = new int[n];  Array.Fill(cost[i] int.MaxValue);  }  cost[0][0] = grid[0][0];    // Direction vector to move in 4 directions  int[][] dir = { new int[] {-1 0} new int[] {1 0}   new int[] {0 -1} new int[] {0 1} };    pq.Add((grid[0][0] 0 0));    while (pq.Count > 0) {  var top = pq.Min;  pq.Remove(top);    int i = top.x j = top.y;    // Check for all 4 neighbouring cells.  foreach (var d in dir) {  int x = i + d[0];  int y = j + d[1];    // If cell is valid and cost to reach this cell   // from current cell is less  if (isValidCell(x y n) &&   cost[i][j] + grid[x][y] < cost[x][y]) {    // Update cost to reach this cell.  cost[x][y] = cost[i][j] + grid[x][y];    // Push the cell into heap.  pq.Add((cost[x][y] x y));  }  }  }    // Return minimum cost to   // reach bottom right cell.  return cost[n - 1][n - 1];  }  static void Main(string[] args) {  int[][] grid = new int[][] {  new int[] {9 4 9 9}  new int[] {6 7 6 4}  new int[] {8 3 3 7}  new int[] {7 4 9 10}  };    Console.WriteLine(minimumCostPath(grid));  } } 
JavaScript
// JavaScript program to find minimum Cost Path with // Left Right Bottom and Up moves allowed function comparator(a b) {  if (a[0] > b[0]) return -1;  if (a[0] < b[0]) return 1;  return 0; } class PriorityQueue {  constructor(compare) {  this.heap = [];  this.compare = compare;  }  enqueue(value) {  this.heap.push(value);  this.bubbleUp();  }  bubbleUp() {  let index = this.heap.length - 1;  while (index > 0) {  let element = this.heap[index]  parentIndex = Math.floor((index - 1) / 2)  parent = this.heap[parentIndex];  if (this.compare(element parent) < 0) break;  this.heap[index] = parent;  this.heap[parentIndex] = element;  index = parentIndex;  }  }  dequeue() {  let max = this.heap[0];  let end = this.heap.pop();  if (this.heap.length > 0) {  this.heap[0] = end;  this.sinkDown(0);  }  return max;  }  sinkDown(index) {  let left = 2 * index + 1  right = 2 * index + 2  largest = index;  if (  left < this.heap.length &&  this.compare(this.heap[left] this.heap[largest]) > 0  ) {  largest = left;  }  if (  right < this.heap.length &&  this.compare(this.heap[right] this.heap[largest]) > 0  ) {  largest = right;  }  if (largest !== index) {  [this.heap[largest] this.heap[index]] = [  this.heap[index]  this.heap[largest]  ];  this.sinkDown(largest);  }  }  isEmpty() {  return this.heap.length === 0;  } } // Function to check if cell is valid. function isValidCell(i j n) {  return i >= 0 && i < n && j >= 0 && j < n; } function minimumCostPath(grid) {  let n = grid.length;  // Min heap to implement Dijkstra  const pq = new PriorityQueue(comparator)  // 2D grid to store minimum cost  // to reach every cell.  let cost = Array.from({ length: n } () => Array(n).fill(Infinity));  cost[0][0] = grid[0][0];  // Direction vector to move in 4 directions  let dir = [[-1 0] [1 0] [0 -1] [0 1]];  pq.enqueue([grid[0][0] 0 0]);  while (!pq.isEmpty()) {  let [c i j] = pq.dequeue();  // Check for all 4 neighbouring cells.  for (let d of dir) {  let x = i + d[0];  let y = j + d[1];  // If cell is valid and cost to reach this cell  // from current cell is less  if (isValidCell(x y n) && cost[i][j] + grid[x][y] < cost[x][y]) {  // Update cost to reach this cell.  cost[x][y] = cost[i][j] + grid[x][y];  // Push the cell into heap.  pq.enqueue([cost[x][y] x y]);  }  }  }  // Return minimum cost to  // reach bottom right cell.  return cost[n - 1][n - 1]; } let grid = [  [9 4 9 9]  [6 7 6 4]  [8 3 3 7]  [7 4 9 10]  ]; console.log(minimumCostPath(grid)); 

Uitvoer
43 

Tijdcomplexiteit: O(n^2 logboek(n^2))
Hulpruimte: O(n^2 logboek(n^2))

Waarom kan dynamisch programmeren niet worden gebruikt?

Dynamisch programmeren mislukt hier omdat het toestaan ​​van beweging in alle vier de richtingen cycli creëert waarin cellen opnieuw kunnen worden bezocht, waardoor de aanname van de optimale substructuur wordt doorbroken. Dit betekent dat de kosten om een ​​cel vanuit een bepaalde cel te bereiken niet vast zijn, maar afhankelijk zijn van het gehele pad.

Gerelateerde artikelen:

Min. kostenpad

Quiz maken