问题描述
|
这已经困扰了我一段时间。
假设您有一个函数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]]
解决方法
让我们为您的问题画一个示例网格,以帮助您思考问题。这是每个
x
和y
f
的示例图。它在每个参数中都是单调的,这是一个有趣的约束,我们也许可以做一些聪明的事情。
+------- 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 ] ]
签名并不像可能的那么普遍(不必要7),但我需要它来抵消度量函数,因为enumIncreeasing返回的是递增列表而不是递减列表-我也可以用新型包装器来完成。
使用此功能,我们可以找到最大的奇数,该奇数可以写成两个数字<=
100的乘积:
ghci> maximise (*) odd 100 100
Just 9801
我写了enumIncreeasing在黑客上使用ѭ10来解决这个问题,但这很笼统。您可以调整上述内容以在域上添加其他约束,等等。
, 答案取决于昂贵的东西。可能令人感兴趣的情况是f昂贵时。
您可能想做的就是查看pareto-optimality。假设你有两点
(1,2) and (3,4)
然后您知道,只要f是一个非递减函数,则后一点将是更好的解决方案。但是,当然,如果您有积分,
(1,2) and (2,1)
那你就不知道因此,一种解决方案是建立谓词g所允许的点的最佳局部边界,然后通过f评估这些点。