Reti43有正确的想法,但有一个快速的递归解决方案,对你的不等式有较少的限制性假设.
def solve(smin,smax,coef1,coef2):
"""
Return a list of lists of non-negative integers `n` that satisfy
the inequalities,sum([coef1[i] * n[i] for i in range(len(coef1)]) > smin
sum([coef2[i] * n[i] for i in range(len(coef1)]) < smax
where coef1 and coef2 are equal-length lists of positive integers.
"""
if smax < 0:
return []
n_max = ((smax-1) // coef2[0])
solutions = []
if len(coef1) > 1:
for n0 in range(n_max + 1):
for solution in solve(smin - n0 * coef1[0],smax - n0 * coef2[0],coef1[1:],coef2[1:]):
solutions.append([n0] + solution)
else:
n_min = max(0,(smin // coef1[0]) + 1)
for n0 in range(n_min,n_max + 1):
if n0 * coef1[0] > smin and n0 * coef2[0] < smax:
solutions.append([n0])
return solutions
你会把它应用到这样的原始问题上,
smin,coef1 = 185,(97,89,42,20,16,11,2)
smax,coef2 = 205,(98,90,43,21,17,12,3)
solns7 = solve(smin,coef2)
len(solns7)
1013
而对于这样的长期问题,6,7,3)
solns8 = solve(smin,coef2)
len(solns8)
4015
在我的Macbook上,这两种情况都在几毫秒内完成.这应该可以很好地扩展到稍微大一些的问题,但从根本上说,它是系数N的O(2 ^ N).实际扩展的程度取决于附加系数的大小 – 更大的系数(与smax-相比) smin),解决方案越少,运行速度越快.
更新:从关于链接M.SE post的讨论中,我看到这里两个不等式之间的关系是问题结构的一部分.鉴于此,可以给出稍微简单的解决方案.下面的代码还包括一些额外的优化,可以在我的笔记本电脑上将8变量的解决方案从88毫秒加速到34毫秒.我已经尝试了多达22个变量的示例,并在不到一分钟的时间内得到了结果,但对于数百个变量来说,它永远不会实用.
def solve(smin,coef):
"""
Return a list of lists of non-negative integers `n` that satisfy
the inequalities,sum([coef[i] * n[i] for i in range(len(coef)]) > smin
sum([(coef[i]+1) * n[i] for i in range(len(coef)]) < smax
where coef is a list of positive integer coefficients,ordered
from highest to lowest.
"""
if smax <= smin:
return []
if smin < 0 and smax <= coef[-1]+1:
return [[0] * len(coef)]
c0 = coef[0]
c1 = c0 + 1
n_max = ((smax-1) // c1)
solutions = []
if len(coef) > 1:
for n0 in range(n_max + 1):
for solution in solve(smin - n0 * c0,smax - n0 * c1,coef[1:]):
solutions.append([n0] + solution)
else:
n_min = max(0,(smin // c0) + 1)
for n0 in range(n_min,n_max + 1):
solutions.append([n0])
return solutions
您可以将它应用于这样的8变量示例,
solutions = solve(185,205,2))
len(solutions)
4015
该解决方案直接列举有界区域中的晶格点.由于您需要所有这些解决方案,因此获取它们所需的时间将与绑定的网格点的数量成比例(最多),这些网格点随着维度(变量)的数量呈指数增长.