简体   繁体   English

在矩阵中从左上角到右下角找到路径的问题?

[英]Problem with finding the path in matrix from top left corner to bottom right?

I have a 20x30 matrix filled with random numbers [ 0, 1, 2 ] .我有一个20x30矩阵,其中填充了随机数[ 0, 1, 2 ] I need to find a path consisting of only 1s that starts in the top left and ends in the bottom right.我需要找到一条仅由 1 组成的路径,该路径从左上角开始并在右下角结束。 I need help finding the path of 1s.我需要帮助找到 1s 的路径。 Also, how can I print the coordinates of each number where I stepped?另外,如何打印我踩过的每个数字的坐标? I can display the number where I stepped, but I'm having problems with displaying its coordinate.我可以显示我踩过的数字,但我在显示它的坐标时遇到了问题。 Here is my current code这是我当前的代码

#include <iostream>
#include <vector>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;

const int N = 3;
const int M = 3;

void mtxFeltolt(int (&mat)[N][M]);

void mtxPrint(int (&mat)[N][M]);

void printPaths(int mat[M][N], vector<int> &route, int i, int j)
{
    // if last cell is reached
    if (i == M - 1 && j == N - 1)
    {
        // print the current route

        for (int i: route) {
            cout << i << " - ";
        }

        cout << mat[i][j] << endl;
        return;
    }

    // include current cell in route
    route.push_back(mat[i][j]);


    // move right
    if (j + 1 < N){
        printPaths(mat, route, i, j + 1);
    }
    // move down
    if (i + 1 < M){
        printPaths(mat, route, i + 1, j);
    }
    // move diagonally
    if (i + 1 < M && j + 1 < N){
        printPaths(mat, route, i + 1, j + 1);
    }
    // backtrack
    route.pop_back();
}

// Print all shortest routes in a rectangular grid
void printPaths(int mat[][N])
{
    // vector to store current route
    vector<int> route;

    // start from the first cell (0, 0)
    printPaths(mat, route, 0, 0);
}

// main function
int main()
{
    int mat[N][M];

    srand (time(NULL));

    mtxFeltolt(mat);


    cout << "A matrix: " <<endl;
    mtxPrint(mat);

    cout << endl;
    cout << "---- A megfelelo utak ----" << endl;
    printPaths(mat);

    return 0;
}
void mtxFeltolt(int (&mat)[N][M]){
    for(int i=0; i < N; i++){
        for(int j=0; j < M; j++)
            mat[i][j] = rand() % 3;
    }

}

void mtxPrint(int (&mat)[N][M]){
    for(int i=0; i < N; i++){
        for(int j = 0; j < M; j++){
            cout << mat[i][j] << " ";
        }
        cout << endl;
    }
}

Hopefully you can follow this code.希望您可以遵循此代码。 Instead of using std::pair I've made a simple struct Coord to contain the row and column of a coordinate in the path.我没有使用std::pair而是创建了一个简单的 struct Coord来包含路径中坐标的行和列。 It was easier to read that way.这样读起来更容易。 I've also included a better way to generate random numbers.我还提供了一种生成随机数的更好方法。

I used a depth-first search to find the path.我使用深度优先搜索来找到路径。 It doesn't guarantee the shortest path but it will find a path from the top left to the bottom right.它不保证最短路径,但会找到从左上角到右下角的路径。

#include <algorithm>
#include <iostream>
#include <random>
#include <vector>

struct Coord {unsigned long row, col;};

template<typename T>
using Matrix = std::vector<std::vector<T>>;
using Path = std::vector<Coord>;

/**
 * Generate a random number from [low, high]
 *
 * @param low  The lower bound
 * @param high The upper bound
 * @return     A random number on the range [low, high]
 */
int random_int(int low, int high)
{
  static std::random_device rd;

  // static std::mt19937 mt(rd()); // different random numbers each time
  static std::mt19937 mt(30); // seed that generates a matrix with a path

  std::uniform_int_distribution<> dist(low, high);
  return dist(mt);
}

Matrix<int> generateMatrix(const int m, const int n)
{
  Matrix<int> mat;
  for(int row = 0; row < m; ++row)
  {
    mat.push_back({});
    for(int col = 0; col < n; ++col)
    {
      mat[row].push_back(random_int(0,2));
    }
  }
  return mat;
}

void print(const Matrix<int>& mat)
{
  for(const auto & row : mat)
  {
    for(const auto & col : row)
      std::cout << col << " ";
    std::cout << std::endl;
  }

}

Path findPath(const Matrix<int>& mat,
              Matrix<bool>& visited,
              const Coord cur,
              const Coord end) 
{
  // out of range -> no path
  if(cur.row < 0
     || cur.row >= mat.size()
     || cur.col < 0
     || cur.col >= mat[0].size())
  {
    return {};
  }

  // visited current location -> no path
  if(visited[cur.row][cur.col])
  {
    return {};
  }
    visited[cur.row][cur.col] = true;

  // current location is not a 1 -> no path
  if(mat[cur.row][cur.col] != 1)
  {
    return {};
  }

  // if at the end, the path is trivial
  if(cur.row == end.row && cur.col == end.col)
  {
    return {cur};
  }

  Path p {cur};
  std::vector<Path> paths;

  // try to go in each direction
  // right
  paths.push_back(findPath(mat, visited, {cur.row, cur.col+1}, end));
  // left
  paths.push_back(findPath(mat, visited, {cur.row, cur.col-1}, end));
  // up
  paths.push_back(findPath(mat, visited, {cur.row-1, cur.col}, end));
  // down
  paths.push_back(findPath(mat, visited, {cur.row+1, cur.col}, end));
  // up-right
  paths.push_back(findPath(mat, visited, {cur.row-1, cur.col+1}, end));
  // down-right
  paths.push_back(findPath(mat, visited, {cur.row+1, cur.col+1}, end));
  // down-left
  paths.push_back(findPath(mat, visited, {cur.row+1, cur.col-1}, end));
  // up-left
  paths.push_back(findPath(mat, visited, {cur.row-1, cur.col-1}, end));

  Path longest = *std::max_element(paths.begin(), paths.end(),
    [](const auto a, const auto b){
      return a.size() < b.size();
  });

  p.insert(p.end(), longest.begin(), longest.end());


  return p;
}

Path findPath(const Matrix<int>& mat,
              const Coord cur,
              const Coord end) 
{
  Matrix<bool> visited;
  for(int row = 0; row < mat.size(); ++row)
  {
    visited.push_back({});
    for(int col = 0; col < mat[0].size(); ++col)
    {
      visited[row].push_back(false);
    }
  }

  return findPath(mat, visited, cur, end);
}

int main()
{
  auto mat = generateMatrix(5, 5);
  print(mat);
  auto path = findPath(mat, {0, 0}, {mat.size()-1, mat[0].size()-1});

  if(path.size() > 0
     && path.back().row == mat.size()-1 && path.back().col == mat[0].size()-1)
  {
    std::cout << "path length: " << path.size() << std::endl;
    for(const auto c : path)
    {
      std::cout << "(" << c.row << ", " << c.col << ")" << std::endl;
    }
  }
  else
    std::cout << "no path" << std::endl;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在矩阵中从左、右、上、下查找岛 - Find the island from left, right, top and bottom in c++ in a matrix 从左上方到右下方对坐标进行排序 - Sort Coordinates from top left to bottom right 通过 DP 打印 mXn 矩阵从左上角到右下角的所有可能路径 - Print all possible paths from top left to bottom right of a mXn matrix by DP 计算 mXn 矩阵从左上角到右下角的所有可能路径 - Count all possible paths from top left to bottom right of a mXn matrix 查找左上角和右下角点 (C++) - Finding Top Left and Bottom Right Points (C++) 如何以小于指数的时间复杂度找到矩阵中从左上角到右下角的路径乘积? - How to find the product of paths in a matrix from top-left to bottom-right in less than exponential time complexity? 如何顺时针交换四分之一平方矩阵(从左上角开始)? - How to swap the quarters of quadratic matrix clockwise (beginning from top left corner)? 排序向量 <Points> 在C ++中使用STL从上到下然后从左到右 - Sorting Vector<Points> from Top to Bottom then from Left to Right using STL in c++ 优化网格中从左上到右下的所有路径的回溯算法,每个正方形只访问一次 - Optimisation of the backtracking algorithm for all paths in a grid from top left to bottom right visiting each square just once 在按键上更改gluLookAt。 上,右,下,左 - Change gluLookAt on key press. Top, Right, Bottom, Left
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM