algorithm - 找到满足给定 f 的属性的最大 f 在其参数中是非递减的

标签 algorithm math haskell

这个问题困扰了我一段时间。

假设您有一个函数 f x y,其中 x 和 y 是整数,并且您知道 f 在其参数中是严格非递减的,

即f (x+1) y >= f x y 且 f x (y+1) >= f x y。

在给定 x 和 y 有界的情况下,找到满足属性的最大 f x y 的最快方法是什么。

我在想这可能是鞍背搜索的变体,我想知道是否有此类问题的名称。

另外,更具体地说,我想知道如果您知道 f 是乘法运算符,是否有更快的方法来解决这个问题。

谢谢!

编辑:看下面的评论,属性可以是任何东西

给定一个属性 g(其中 g 接受一个值并返回一个 bool 值)我只是在寻找最大的 f 使得 g(f) == True

例如,一个简单的实现(在 haskell 中)是:

maximise :: (Int -> Int -> Int) -> (Int -> Bool) -> Int -> Int -> Int
maximise f g xLim yLim = head . filter g . reverse . sort $ results
    where results = [f x y | x <- [1..xLim], y <- [1..yLim]]

最佳答案

让我们为您的问题画一个示例网格以帮助思考它。这是 f 的示例图对于每个 xy .它在每个参数中都是单调的,这是一个有趣的约束,我们可以用它来做一些聪明的事情。

+------- x --------->
| 0  0  1  1  1  2 
| 0  1  1  2  2  4
y 1  1  3  4  6  6
| 1  2  3  6  6  7
| 7  7  7  7  7  7
v

由于我们对该属性一无所知,所以除了列出 f 范围内的值外,我们真的不能做得更好了。按降序排列。问题是如何有效地做到这一点。

首先想到的是从右下角开始像图一样遍历。这是我的尝试:

import Data.Maybe (listToMaybe)

maximise :: (Ord b, Num b) => (Int -> Int -> b) -> (b -> Bool) -> Int -> Int -> Maybe b
maximise f p xLim yLim = 
    listToMaybe . filter p . map (negate . snd) $ 
       enumIncreasing measure successors (xLim,yLim)
  where
    measure (x,y) = negate $ f x y
    successors (x,y) = [ (x-1,y) | x > 0 ] ++ [ (x,y-1) | y > 0 ] ]

签名并不像它应该的那样通用(Num 应该不是必需的,但我需要它来否定测量函数,因为 enumIncreasing 返回一个递增的而不是递减的列表——我也可以这样做它带有一个新的包装器)。

使用这个函数,我们可以找到可以写成两个数字乘积的最大奇数<= 100:

ghci> maximise (*) odd 100 100
Just 9801

我写了enumIncreasing使用 meldable-heap on hackage 来解决这个问题,但它很一般。您可以调整以上内容以在域等上添加额外的约束。

关于algorithm - 找到满足给定 f 的属性的最大 f 在其参数中是非递减的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6301259/

相关文章:

python - Python中(专家系统)的后向和前向链接算法

java - 算法,图像处理,洪水填充

haskell - 制作在自身上运行其输入的函数时出现无限类型错误

c++ - 如何在 Qt 5.0.2 中添加/使用 <QtMath>

haskell - 等效于 NumPy 的 argsort 的高效 Haskell

list - 如何在 Haskell 中生成两个列表

r - R中hclust使用的聚类算法是什么?

c - 是否有任何加扰单词的算法?

javascript - 计算两个椭圆之间的重叠

Java减去没有库的月份