【问题标题】:Closed path in the two-dimensional array二维数组中的闭合路径
【发布时间】:2011-08-27 10:08:32
【问题描述】:

有一个由 0 和 1 组成的二维数组。需要算法(实现)来确定在这个数组中是否包含围绕零的闭合路径

示例:

存在一条封闭路径(中心):

1 0 0 0 0
0 0 1 0 0
0 1 0 1 0
0 0 1 1 0
0 0 1 0 0

没有

0 0 0 0 1 
0 1 0 1 0
0 0 1 0 0
0 0 1 0 1
0 1 0 1 0

【问题讨论】:

  • 看起来像家庭作业?有一个标签。
  • 你的意思是 0 被 1 包围?
  • 哦,所以如果你有一个 2x2 子数组,全是1s,那不会被认为是封闭路径?对我来说看起来像一个。
  • 是的,你说得对,里面需要一些零
  • 嗯,这让它有点复杂。没有它,你可以使用图论。

标签: c# algorithm


【解决方案1】:

您可以查看 Connected Components Labeling 算法,例如在Wikipedia 或谷歌为他们。这些算法用于例如将数字白色/黑色图像中的前景像素与背景像素分开。要将它们应用于您的特定问题,您可以将矩阵视为数字图像,其中 0 表示前景,1 表示背景(根据您的需要反之亦然)。该算法找到被背景(1)包围的最大连接前景区域(仅包含 0)。所以,如果你发现了这样一个前景区域,你就知道它周围有一个 1 的循环。当前景区域处于边界时,您可以决定是否将其视为被包围。

【讨论】:

    【解决方案2】:

    这是家庭作业,所以我将给出一个大致的草图。构造一个无向图;每个1 是一个节点,相邻的1s 之间有一条边。谷歌undirected graph cycle detection 查找封闭路径。然后你必须回到原来的矩阵,确保里面至少有一个0

    【讨论】:

    • 相邻1s的定义是什么?还有谁说在定义的图中找到循环会导致找到闭合路径?
    • @Saeed Amiri 对于每个1,查看相邻单元格中的其他1s。如果那里有一个,它们是相邻的,在它们之间添加一条边。 OP 定义的任何闭合路径都将对应于图中的一个循环。不幸的是,由于0 必须包含在内的限制,反之不正确,因此您必须检查。
    • 首先相邻(在行列或直径或...)的含义是什么?其次(假设仅行和列相邻),假设所有正方形都是1s,您的算法返回 n^4 闭合路径,但根据 OP 的定义没有任何闭合路径。
    • 好点,对于这种情况,这不是一个好的算法。问题中的示例清楚地表明我们应该检查对角线。所以对于[x,y],你查看从x-1x+1y-1y+1 的所有点,除了点本身,并正确处理外部边界。
    【解决方案3】:

    另一个想法是从每个0 开始填充,以1s 为界。如果它没有到达边缘,它就会被包围。

    【讨论】:

      【解决方案4】:

      这是我尝试过的示例代码。通过测试 我尝试的逻辑是遍历除第一行和最后一行之外的所有行。 如果你找到 0 然后检查它的邻居到左、右、上和下如果所有的邻居都是 1 然后关闭。

             private void Form1_Load(object sender, EventArgs e)
          {
              int[,] graph = new int[5, 5] { 
              { 1, 0, 0, 0, 0 }, 
              { 0, 0, 1, 0, 0 },
              { 0, 1, 0, 1, 0 }, 
              { 0, 0, 1, 1, 0 }, 
              { 0, 0, 1, 0, 0 } 
              };
      
              int[,] graph1 = new int[5, 5] { 
              { 0, 0, 0, 0, 1 }, 
              { 0, 1, 0, 1, 0 },
              { 0, 0, 1, 0, 0 }, 
              { 0, 0, 1, 0, 0 }, 
              { 0, 1, 0, 1, 0 } 
              };
      
              isClosed(graph1);
      
      
      
          }
      
          private bool isClosed(int[,] graph)
          {
      
      
              for (int i = 1; i < graph.GetUpperBound(0); i++)
              {
                  for (int j = 1; j < graph.GetUpperBound(1); j++)
                  {
                      if (graph[i, j] == 0)
                      {
                          if (graph[i - 1, j] == 1 && graph[i + 1, j] == 1 && graph[i, j - 1] == 1 && graph[i, j + 1] == 1)
                          {
                              return true;
                          }
                      }
                  }
              }
      
              return false;
          }
      

      【讨论】:

      • 多个零被一包围怎么样?
      • 不,它不适用于所有矩阵,假设图形像耳线,它不适用于它。
      猜你喜欢
      • 2017-08-08
      • 1970-01-01
      • 1970-01-01
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-11
      • 1970-01-01
      相关资源
      最近更新 更多