尝试为 Haskell 中的函数创建有效的算法

2023-11-30

我正在寻找一种有效的多项式时间解决方案来解决以下问题:

实现一个递归函数节点 x y 来计算数字三角形中的第 (x,y) 个数字,定义为

g(x,y) = 0 if |x| > y
       = 1 if (x,y) = (0,0)
       = sum of all incoming paths otherwise

到节点的所有传入路径的总和定义为从根节点 (x, y) = (0, 0) 到所考虑的节点的所有可能路径值的总和,其中在每个节点 (x,y ) 路径可以沿对角线向下和向左 (x−1,y+1)、直线向下 (x,y+1) 或对角线向下和向右 (x+1,y+1) 继续。到节点的路径的值定义为沿该路径直至(但不包括)所考虑的节点的所有节点的总和。

数字三角形中的前几个条目在表中给出:

\  x  -3  -2  -1  0  1  2  3 
 \  
y \ _________________________
   |
0  |   0   0   0  1  0  0  0
   |
1  |   0   0   1  1  1  0  0
   |
2  |   0   2   4  6  4  2  0
   |
3  |   4   16  40 48 40 16 4

我试图首先找到一个简单的解决方案,这就是我所拥有的:

node x y | y < 0                = error "number cannot be negative"
         | (abs x) > y          = 0
         | (x == 0) && (y == 0) = 1
         | otherwise            = node (x+1) (y-1) + node x (y-1) + node (x-1) (y-1)

每当我运行这个我得到:

"*异常:堆栈溢出”?


我相信您的问题比示例代码所示的要复杂一些。首先,让我们明确一些定义:

Let pathCount x y是结束于 (x, y) 的路径数。我们有

pathCount :: Int -> Int -> Integer
pathCount x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathCount (x + d) (y - 1) | d <- [-1..1]]

现在让我们pathSum x y是以 (x, y) 结尾的所有路径的总和。我们有:

pathSum :: Int -> Int -> Integer
pathSum x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathSum (x + d) (y - 1) + node x y * pathCount (x + d) (y - 1)
                     | d <- [-1..1] ]

有了这个助手,我们终于可以定义node x y适当地:

node :: Int -> Int -> Integer
node x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathSum (x + d) (y - 1) | d <- [-1..1]]

该算法目前的形式是指数时间。但是我们可以添加记忆化使加法次数成二次方。这memoizeHackage 上的软件包让这一切变得非常简单。完整示例:

import Control.Monad
import Data.List (intercalate)
import Data.Function.Memoize (memoize2)

node' :: Int -> Int -> Integer
node' x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathSum (x + d) (y - 1) | d <- [-1..1]]
node = memoize2 node'

pathCount' :: Int -> Int -> Integer
pathCount' x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathCount (x + d) (y - 1) | d <- [-1..1]]
pathCount = memoize2 pathCount'

pathSum' :: Int -> Int -> Integer
pathSum' x y
  | y == 0 = if x == 0 then 1 else 0
  | otherwise = sum [ pathSum (x + d) (y - 1) + node x y * pathCount (x + d) (y - 1)
                     | d <- [-1..1] ]
pathSum = memoize2 pathSum'

main =
  forM_ [0..n] $ \y ->
     putStrLn $ intercalate " " $ map (show . flip node y) [-n..n]
  where n = 5

Output:

0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 1 1 1 0 0 0 0
0 0 0 2 4 6 4 2 0 0 0
0 0 4 16 40 48 40 16 4 0 0
0 8 72 352 728 944 728 352 72 8 0
16 376 4248 16608 35128 43632 35128 16608 4248 376 16

正如您所看到的算法,数字的大小很快就会失控。所以运行时间是notO(n^2),而算术运算次数为。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试为 Haskell 中的函数创建有效的算法 的相关文章

  • 对列表中的相邻元素进行分组

    假设我想编写一个函数来执行此操作 输入 1 1 3 3 4 2 2 5 6 6 输出 1 1 3 3 4 2 2 5 6 6 它将相同的相邻元素分组 这个方法的名称应该是什么 此操作有标准名称吗 In 1 1 3 3 4 2 2 5 6 6
  • 如何只修改记录的一个字段而不完全重写它? [复制]

    这个问题在这里已经有答案了 It s the second time I m tackling this problem And for the second time this is while working with the Stat
  • Haskell 中多核编程的现状如何?

    Haskell 中多核编程的现状如何 现在有哪些项目 工具和库可用 有哪些经验报道 2009年至2012年期间 发生了以下事件 2012 从 2012 年开始 并行 Haskell 状态更新开始出现在并行 Haskell 摘要 http w
  • 如何确定字符串的最小公约数?

    我在面试时被问到以下问题 并被它难住了 我遇到的部分问题是要下定决心要解决什么问题 起初我并不认为这个问题在内部是一致的 但后来我意识到它要求你解决两个不同的问题 第一个任务是弄清楚一个字符串是否包含另一个字符串的倍数 但第二个任务是在两个
  • 我可以从 GHCi 中找到 GHC 版本吗?

    gt 我在里面输入什么GHCi发现它正在使用哪个 GHC 版本 gt import System Info gt browse arch String compilerName String compilerVersion Data Ver
  • java中的Anagram算法

    我想做字谜算法但是 这段代码不起作用 我的错在哪里 例如 des 和 sed 是字谜 但输出不是字谜 同时我必须使用字符串方法 不是数组 public static boolean isAnagram String s1 String s2
  • 在列表中查找元素及其索引

    我需要让列表的两个元素都满足谓词and这些元素的索引 我可以通过以下方式实现这一点 import Data List findIndices list Int list 3 2 4 1 9 indices findIndices gt 2
  • Python 比编译的 Haskell 更快?

    我有一个用 Python 和 Haskell 编写的简单脚本 它读取包含 1 000 000 个换行符分隔的整数的文件 将该文件解析为整数列表 对其进行快速排序 然后将其写入已排序的不同文件中 该文件与未排序的文件具有相同的格式 简单的 这
  • 读取4个点的坐标。他们做一个正方形吗?

    我计算点之间的距离 如果距离相等 则点构成一个正方形 否则不 仅当我按以下顺序读取坐标 A x y B x y C x y D x y 或相反时 我的代码才有效 但是如果我这样读 例如 A x y B x y D x y C x y 它将不
  • 如何在大空间尺度上加速A*算法?

    From http ccl northwestern edu netlogo models community Astardemo http ccl northwestern edu netlogo models community Ast
  • 让电脑实现360度=0度,旋转炮塔

    我正在制作一个游戏 其中有一个计算机控制的炮塔 炮塔可360度旋转 它使用 trig 找出枪瞄准所需的角度 obj deg 并将枪的当前角度存储在 gun deg 下面的代码以设定的速度旋转枪 if objdeg gt gundeg gun
  • 使用默认值压缩而不是删除值?

    我正在 haskell 中寻找一个函数来压缩两个长度可能不同的列表 我能找到的所有 zip 函数都只是删除列表中比其他列表长的所有值 例如 在我的练习中 我有两个示例列表 如果第一个比第二个短 我必须用 0 填充 否则我必须使用 1 我不允
  • Haar级联正例图像大小调整

    我正在迈出第一步 为自定义对象识别创建 haar 级联 我花了时间获取大量数据并编写了一些预处理脚本以将视频转换为帧 我的下一步是裁剪感兴趣的对象 以创建一些积极的训练示例 我有几个问题 我确实在网上寻找答案 我有点困惑 我读到我应该致力于
  • 如何与更高级别的类型合作

    玩弄教堂的数字 我遇到了无法指导 GHC 类型检查器处理高阶类型的情况 首先我写了一个版本 没有任何类型签名 module ChurchStripped where zero z z inc n z s s n z s natInteger
  • Haskell 为替代的 Either 数据类型定义 Functor 实例

    通过 Typeclassopedia 获得一些使用类型类的路由 想要替代Either的一个实例Functor 但即使检查定义Either作为一个例子Functor总是给我带来麻烦 有这个 但不会编译 data Alt a b Success
  • 模式识别算法

    过去我必须开发一个充当规则评估器的程序 你有一个先行词和一些后续词 动作 所以如果先行词评估为真 则执行的动作 当时我用的是修改版RETE算法 http en wikipedia org wiki Rete algorithm RETE 有
  • 在 O(n) 时间内对列表中的数字方块进行排序?

    给定一个按排序顺序排列的整数列表 例如 9 2 0 2 3 我们必须对每个元素进行平方并按排序顺序返回结果 所以 输出将是 0 4 4 9 81 我可以找出两种方法 O NlogN 方法 我们将每个元素的平方插入哈希集中 然后将元素复制到列
  • 具有最小刻度的图表的漂亮标签算法

    我需要手动计算图表的刻度标签和刻度范围 我知道漂亮刻度的 标准 算法 参见 我也知道这个Java实现 http erison blogspot nl 2011 07 algorithm for optimal scaling on char
  • 在 Haskell 中调试时打印时间戳

    我仍在学习 Haskell 并调试一些函数 并且通常有一个时间戳函数来了解某些操作何时开始和停止 doSomeAction String gt IO doSomeAction arg1 do putStrLn lt lt makeTime
  • 线性问题和非线性问题之间的区别?点积和核技巧的本质

    核技巧将非线性问题映射为线性问题 我的问题是 1 线性问题和非线性问题的主要区别是什么 这两类问题的差异背后的直觉是什么 核技巧如何帮助在非线性问题上使用线性分类器 2 为什么点积在这两种情况下如此重要 Thanks 当人们说到分类问题的线

随机推荐

  • 将特定内容分支到一个文件中

    我试图拥有一个特定于每个分支的文件 我不希望在合并时覆盖或更新此文件 为什么这不起作用 我的尝试是基于如何防止跟踪的配置文件被 git 中的合并更改 但由于某种原因它不起作用 我也关注了更详细的博客文章这个答案是基于这个答案的 而且它的行为
  • 查找小数点后的位数[重复]

    这个问题在这里已经有答案了 我正在尝试编写Python 2 5 4代码来编写一个函数 该函数将浮点数x作为输入并返回x中小数点后的位数 这是我的代码 def number of digits post decimal x count 0 r
  • 文件 PixelFormat 中的 BitmapImage 始终为 bgr32

    我正在使用以下代码从文件加载图像 BitmapImage BitmapImg null BitmapImg new BitmapImage BitmapImg BeginInit BitmapImg UriSource new Uri im
  • 操作类不适用于 Selenium 3.5.3

    我想将元素从一个地方拖放到另一个地方 因此 我使用操作类来实现我的功能 问题是我的代码成功执行 没有显示任何错误 但功能目标没有实现 我在 Firefox 和 Chrome 浏览器中尝试了相同的代码 但在这两个浏览器中都重复了同样的问题 这
  • 使用交互触发器调用可见性更改方法 WPF

    我想弄清楚的是两件事 如何在用户控件的可见性更改时触发触发器以及将可见性值作为参数传递 无论出于何种原因 扳机似乎都没有触发 我刚刚添加了 ControlVisible 参数来显示我想要发生的情况 在测试时它不存在 只是在内部有一个消息框来
  • 在 Wow6432Node 中写入不重定向的注册表值

    此代码插入注册表值 Microsoft Win32 RegistryKey key key Microsoft Win32 Registry LocalMachine CreateSubKey SOFTWARE Microsoft Inte
  • 如何停止 requestAnimationFrame 递归/循环?

    我使用 Three js 和 WebGL 渲染器来制作一个游戏 当play链接被点击 对于动画 我使用requestAnimationFrame 我这样启动它 self animate function self camera lookAt
  • 在Android应用程序中显示TIFF格式图像

    我只能找到一篇关于此问题的先前帖子 并且提供的答案似乎无法正常工作 有没有办法在 Android 中显示具有捏合 缩放功能的 TIFF 图像 编写一个应用程序 我需要显示 TIFF 图像 事实上 似乎有一种方法可以在 Android 上显示
  • 如果.NET SqlConnection对象没有关闭,它会导致内存泄漏吗?

    我明白你需要打电话 Close on a SqlConnection对象在使用完毕后将底层 SQL 连接释放回池中 但如果您不这样做 即使超出范围后 NET 对象是否仍保留在内存中 我问这个问题是因为我正在处理一些遇到内存泄漏的代码 并且我
  • 如何在linux操作系统中设置solr/home?

    我知道如何配置solr home使用Tomcat 6 但我不知道如何设置solr home使用 Glassfish V2 1 我尝试过设置solr home in profile作为研究员 export solr home home hue
  • 打印时间时出现意外输出。时间类型别名

    我正在尝试为自定义类型编写一个解组函数 考虑下面的代码 操场 package main import encoding json fmt strings time type Time time Time func st Time Unmar
  • Spring Boot 安全注销不会使会话失效

    我的增强型宠物诊所应用程序需要安全性 目前注销功能似乎不起作用 我有一个 GET 版本 简单链接 和一个 POST 版本 通过链接提交的隐藏表单 登录后 无论我使用哪种方式注销 一旦我尝试再次登录 就不允许新的登录 我相信这与本节相关 se
  • 如何绘制Windows经典风格的窗口元素

    我们在程序中创建了一些自定义 窗口 当VisualStyles启用后 我们可以找到窗口的每个元素及其大小 并使用适当的渲染器自行绘制它们 包括最小化和关闭按钮 我们想做同样的事情VisualStyles已被禁用 目前正在绘制我们自己的窗口
  • JFreeChart PolarPlot:数学方向

    我想创建一个极坐标图 其中数据以数学方向绘制 因此 该系列从东方开始 然后逆时针继续 JFreeChart 的默认行为PolarPlot是从北开始并顺时针继续系列 是否有对此内置的支持PolarPlot班级 我知道如何转换数据以达到目标 但
  • 合并 2 个具有不同列名的数据框

    在 R 中 我有 2 个数据框 它们都有不同的列名称 我想根据列号组合每个数据框的行 我的数据框如下 gt d1 X 0 52 V2 X 0 52 V4 1 ABT 700 2 AMD 9600 3 AMG 600 4 AGCO 800 g
  • 如何将 Eigen::Matrix 映射到 std::vector

    例如 如果我有一个Eigen MatrixXd大小为 10 列和 3 行 我如何将其别名为std vector的 10 个元素Eigen Vector3d 当我说别名时 我的意思是使用相同的内存块而不进行复制 我知道我可以通过以下方式进行反
  • 如何使用 Firebase 云消息传递

    我找不到任何有关新版本的文档 版本7和版本6有大量文档 而版本9几乎不存在 不仅是我 大多数人都找不到 我只是想向后台发送简单的通知 如果有人分享有关新版本的文档 我将非常高兴 或者我应该使用旧版本 我想您知道如何将 firebase 添加
  • 在 C# 中将字符串转换为枚举标记[重复]

    这个问题在这里已经有答案了 可能的重复 如何在 C 中将字符串转换为枚举 如何在 C 中将字符串 文本 转换 强制转换 为 Enum 标记值 你可以这样做 MyEnum oMyEnum MyEnum Enum Parse typeof My
  • 使用 VBA 获取在 VBA 中使用的唯一值?

    我目前会使用类似的东西与范围 单元格或类似的许多不同的方式相同的基本原理 Range A1 Range A1 End xlDown AdvancedFilter Action xlFilterCopy CopyToRange Range I
  • 尝试为 Haskell 中的函数创建有效的算法

    我正在寻找一种有效的多项式时间解决方案来解决以下问题 实现一个递归函数节点 x y 来计算数字三角形中的第 x y 个数字 定义为 g x y 0 if x gt y 1 if x y 0 0 sum of all incoming pat