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]