我在确定下面给出的2个递归关系之间的关系时遇到了一些麻烦。
f(0) = 1
f(1) = 1
f(2) = 2
f(2n) = f(n) + f(n + 1) + n (for n > 1)
f(2n + 1) = f(n - 1) + f(n) + 1 (for n >= 1)
所以这个系列就像:(索引:0,1,2,3 ...... n)
1,1,2,3,7,4,13,6,15,11,22,12,25,18,28,20,34 ......
目标是找到系列中任何给定数字出现的索引
例如:
鉴于:7
输出:4即f(4)= 7
此外,由于可能在给定序列中出现多次,因此返回上次该数字。
例如:
鉴于:22
这里,f(10)= 22和f(17)= 22
所以,输出:17
从python代码 - 我发现一个数字最多发生两次(虽然不是100%肯定..)。
我的代码可以找到系列中的第n个数字:
memo = {}
def rep(k):
if k<=1:
return 1
if k == 2:
return 2
if not k in memo:
if k%2==0:
memo[k] = (k/2) + rep((k/2)+1) + rep(k/2)
else:
memo[k] = 1 + rep(((k-1)/2)-1) + rep((k-1)/2)
value_key[memo[k]] = k
return memo[k]
我使用memo
来散列我已经生成的值,但是使用这种方法生成并尝试从0开始的数字,直到我得到一个等于给定数字的值(简单的暴力)需要永远,并导致MemoryErrors更大的数字(输入将从1到20位数。)
那么,我失踪的给定方程之间是否存在任何关系?
如果我能找到f(n)
(给定输入)和n
之间的关系 - 我认为它可以很容易地在代码中实现,但我无法用数学方式简化它 - 我尝试过替换一个接一个(给定的复发关系),但到目前为止,我无法弄清楚任何事情。
答案 0 :(得分:0)
现在使用二进制搜索最接近的值以及memoization,需要测试,但这个想法很简单。这仍然依赖于even
和odd
正在增加序列的事实。
#!/usr/bin/env python
# inspired by your code
memo = {'even': {0: 1, 2: 2}, 'odd': {1: 1}}
def f(k):
if k in memo['even']:
return memo['even'][k]
if k in memo['odd']:
return memo['odd'][k]
else:
if k % 2 == 0:
memo['even'][k] = (k / 2) + f((k / 2) + 1) + f(k / 2)
else:
memo['odd'][k] = 1 + f(((k - 1) / 2) - 1) + f((k - 1) / 2)
return f(k)
# binary search on even values
def seek_even(x):
left = 0
right = f(x)
if right % 2 != 0:
right += 1
middle = (right - left) / 2
if middle % 2 != 0:
middle += 1
while f(middle) != x and left < middle < right:
if f(middle) < x:
left = middle
else:
right = middle
middle = (left + right) / 2
if middle % 2 != 0:
middle += 1
return middle
# binary search on odd values
def seek_odd(x):
left = 1
right = x
if right % 2 == 0:
right += 1
middle = (right - left) / 2
if middle % 2 == 0:
middle += 1
while f(middle) != x and left < middle < right:
if f(middle) < x:
left = middle
else:
right = middle
middle = (left + right) / 2
if middle % 2 == 0:
middle += 1
return middle
def seek(x):
indices = [seek_even(x), seek_odd(x)]
print "closest indices: " % indices
return max(filter(lambda c: f(c) == x, indices) + [-1])
tests = [264227, 22, 10, 100000000000000000000, 31]
for i in tests:
print "seek range [0, %d] for %d" % (f(i), i), seek(i)