Algorithm 使用haskell打印所有可能的路径

Algorithm 使用haskell打印所有可能的路径,algorithm,haskell,Algorithm,Haskell,我需要写一个程序,在给定的矩阵中画出所有可能的路径,这些路径只需向左、向右和向上移动即可。 一个人不应该跨越同一地点不止一次。还要注意的是,在一条特定的路径上,我们可能会也可能不会在所有可能的方向上使用运动 路径将从矩阵的左下角开始,并到达右上角。 以下符号用于表示当前位置的运动方向: +---+ | > | right +---+ +---+ | ^ | up +---+ +---+ | < | left +---+ 路径2 +---+---+---+-

我需要写一个程序,在给定的矩阵中画出所有可能的路径,这些路径只需向左、向右和向上移动即可。 一个人不应该跨越同一地点不止一次。还要注意的是,在一条特定的路径上,我们可能会也可能不会在所有可能的方向上使用运动

路径将从矩阵的左下角开始,并到达右上角。 以下符号用于表示当前位置的运动方向:

 +---+
 | > |  right
 +---+
 +---+
 | ^ |  up
 +---+
 +---+
 | < |  left
 +---+
路径2

 +---+---+---+---+---+---+---+---+
 |   |   |   | > | > | > | > | * |
 +---+---+---+---+---+---+---+---+
 |   |   |   | ^ | < | < |   |   |
 +---+---+---+---+---+---+---+---+
 |   |   |   |   |   | ^ |   |   |
 +---+---+---+---+---+---+---+---+
 |   |   | > | > | > | ^ |   |   |
 +---+---+---+---+---+---+---+---+
 | > | > | ^ |   |   |   |   |   |
 +---+---+---+---+---+---+---+---+

看起来像是家庭作业,所以我会尽量给出足够的提示

  • 尝试首先填充从单元格到目标的路径数
所以

这里需要注意的是,从顶层的单元格到
*
始终有一条路径

  • 来自同一行中单元格的可能路径数将相同。您可以意识到这一点,因为所有路径最终都必须向上移动,因为没有向下操作,所以在任何路径中,当前行中的任何单元格都可以到达当前行上方的单元格

  • 您可以感觉到来自当前单元格的所有可能路径都与来自单元格左侧、右侧和上方的可能路径相关。但正如我们所知,我们可以从一行中的一个单元格中找到所有可能的路径,其余单元格的可能路径将是同一行中的一些移动,然后是来自该单元格的可能路径的后缀

也许我会给你举个例子

 +---+---+---+
 | 1 | 1 | * | 
 +---+---+---+
 |   |   |   |  
 +---+---+---+
 |   |   |   |   
 +---+---+---+
您知道第一行单元格中所有可能的路径。您需要在第二行找到相同的。因此,一个好的策略是为最合适的细胞做这件事

 +---+---+---+
 | > | > | * | 
 +---+---+---+
 | ^ | < | < |  
 +---+---+---+
 |   |   |   |   
 +---+---+---+

 +---+---+---+
 |   | > | * | 
 +---+---+---+
 |   | ^ | < |  
 +---+---+---+
 |   |   |   |   
 +---+---+---+

 +---+---+---+
 |   |   | * | 
 +---+---+---+
 |   |   | ^ |  
 +---+---+---+
 |   |   |   |   
 +---+---+---+
  • 任何有效路径都将是该路径排列的前缀,您可以对其进行彻底搜索。使用
    数据中的
    排列
    。列出
    以获取所有可能的排列。然后生成一个函数,该函数给定一条路径,从中删除一条有效路径。将此映射到排列列表并删除重复项。需要注意的是,path将是从排列中得到的前缀,因此对于同一条路径可以有多个排列
      看起来像是一个家庭作业,所以我会尽量给出足够的提示

      • 尝试首先填充从单元格到目标的路径数
      所以

      这里需要注意的是,从顶层的单元格到
      *
      始终有一条路径

      • 来自同一行中单元格的可能路径数将相同。您可以意识到这一点,因为所有路径最终都必须向上移动,因为没有向下操作,所以在任何路径中,当前行中的任何单元格都可以到达当前行上方的单元格

      • 您可以感觉到来自当前单元格的所有可能路径都与来自单元格左侧、右侧和上方的可能路径相关。但正如我们所知,我们可以从一行中的一个单元格中找到所有可能的路径,其余单元格的可能路径将是同一行中的一些移动,然后是来自该单元格的可能路径的后缀

      也许我会给你举个例子

       +---+---+---+
       | 1 | 1 | * | 
       +---+---+---+
       |   |   |   |  
       +---+---+---+
       |   |   |   |   
       +---+---+---+
      
      您知道第一行单元格中所有可能的路径。您需要在第二行找到相同的。因此,一个好的策略是为最合适的细胞做这件事

       +---+---+---+
       | > | > | * | 
       +---+---+---+
       | ^ | < | < |  
       +---+---+---+
       |   |   |   |   
       +---+---+---+
      
       +---+---+---+
       |   | > | * | 
       +---+---+---+
       |   | ^ | < |  
       +---+---+---+
       |   |   |   |   
       +---+---+---+
      
       +---+---+---+
       |   |   | * | 
       +---+---+---+
       |   |   | ^ |  
       +---+---+---+
       |   |   |   |   
       +---+---+---+
      
      • 任何有效路径都将是该路径排列的前缀,您可以对其进行彻底搜索。使用
        数据中的
        排列
        。列出
        以获取所有可能的排列。然后生成一个函数,该函数给定一条路径,从中删除一条有效路径。将此映射到排列列表并删除重复项。需要注意的是,path将是从排列中得到的前缀,因此对于同一条路径可以有多个排列
      您能创建该矩阵并定义“字段”吗?即使你不能(给出了一个特定的矩阵),你也可以将一个
      [(Int,Int)]
      矩阵(对于这种任务来说这听起来很合理)映射到你自己的表示

      由于您没有具体说明您的技能水平,我希望您不介意我建议您首先尝试创建某种网格,以便进行一些工作:

      data Status = Free | Left | Right | Up
          deriving (Read, Show, Eq)
      type Position = (Int, Int)
      type Field = (Position, Status)
      type Grid = [Field]
      
      grid :: Grid
      grid = [((x, y), stat) | x <- [1..10], y <- [1..10], let stat = Free]
      
      data Status=Free | Left | Right | Up
      导出(读取、显示、均衡)
      类型位置=(Int,Int)
      类型字段=(位置、状态)
      类型Grid=[字段]
      网格::网格
      
      grid=[((x,y),stat)| x你能创建那个矩阵并定义“字段”吗?即使你不能(给出了一个特定的矩阵),你也可以将一个
      [(Int,Int)]
      矩阵(听起来对这类任务很合理)映射到你自己的表示

      由于您没有具体说明您的技能水平,我希望您不介意我建议您首先尝试创建某种网格,以便进行一些工作:

      data Status = Free | Left | Right | Up
          deriving (Read, Show, Eq)
      type Position = (Int, Int)
      type Field = (Position, Status)
      type Grid = [Field]
      
      grid :: Grid
      grid = [((x, y), stat) | x <- [1..10], y <- [1..10], let stat = Free]
      
      data Status=Free | Left | Right | Up
      导出(读取、显示、均衡)
      类型位置=(Int,Int)
      类型字段=(位置、状态)
      类型Grid=[字段]
      网格::网格
      
      grid=[((x,y),stat)| x这个ASCII网格比启发性的网格更混乱。让我描述一种更好的方法来表示每个可能的路径

      每个非顶行将正好有一个带有UP的单元格。我声明,一旦选择了每个UP单元格,就可以确定左、右和空单元格。我声明,每个非顶行中所有可能的单元格都可以在所有组合中向上

      因此,每个路径同构于一个(行-1)长度的数字列表,该列表的范围(1..columns)决定向上单元格。因此,允许的路径数为columns^(行-1),并且以这种格式枚举可能的路径应该很容易


      然后,您可以制作一台打印机,将此格式转换为ASCII艺术。这可能会很烦人,具体取决于技能水平。

      此ASCII网格比启发性的更容易混淆。让我描述一种更好的方法来表示每种可能的路径

      每一个非顶行将有一个带有UP的单元格。我声明,一旦选择了每个UP单元格,就可以确定左、右和空单元格
      data Status = Free | Left | Right | Up
          deriving (Read, Show, Eq)
      type Position = (Int, Int)
      type Field = (Position, Status)
      type Grid = [Field]
      
      grid :: Grid
      grid = [((x, y), stat) | x <- [1..10], y <- [1..10], let stat = Free]