假设你有一个函数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取值并返回布尔值)我只是寻找最大的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]]
答案 0 :(得分:4)
让我们为您的问题绘制一个示例网格,以帮助您思考它。以下是每个f
和x
的{{1}}示例图。它在每个参数中都是单调的,这是一个有趣的约束,我们可以做一些聪明的事情。
y
由于我们对该属性一无所知,因此我们最好不要按递减顺序列出+------- 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 ] ]
不是必需的,但我需要它来否定度量函数,因为enumIncreasing返回增加而不是减少的列表 - 我也可以使用newtype包装器完成它。
使用此功能,我们可以找到最大的奇数,可以写成两个数字的乘积Num
100:
<=
我使用ghci> maximise (*) odd 100 100
Just 9801
编写了enumIncreasing来解决这个问题,但它非常普遍。您可以调整以上内容以在域上添加其他约束等。
答案 1 :(得分:1)
答案取决于什么是昂贵的。可能存在问题的情况是 f 价格昂贵。
您可能想要做的是查看 pareto-optimality 。假设你有两点
(1, 2) and (3, 4)
然后你知道后一点将是一个更好的解决方案,只要 f 是一个非减少函数。但是,当然,如果你有积分,
(1, 2) and (2, 1)
那时你无法知道。因此,一种解决方案是建立谓词 g 允许的点的帕累托最优边界,然后通过 f 来评估它们。< / p>