Reti43 has the right idea, but there is a quick recursive solution that works with less strict assumptions about your inequalities.
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
You would apply this to your original problem, for example,
smin, coef1 = 185, (97, 89, 42, 20, 16, 11, 2) smax, coef2 = 205, (98, 90, 43, 21, 17, 12, 3) solns7 = solve(smin, smax, coef1, coef2) len(solns7) 1013
and to a longer problem like this,
smin, coef1 = 185, (97, 89, 42, 20, 16, 11, 6, 2) smax, coef2 = 205, (98, 90, 43, 21, 17, 12, 7, 3) solns8 = solve(smin, smax, coef1, coef2) len(solns8) 4015
On my Macbook, both of these cases are resolved in milliseconds. This should scale well enough for a few larger problems, but itโs basically O (2 ^ N) in terms of the number of factors N. How well it actually scales depends on how large the additional coefficients are - the more coefficients (compared to smax-smin), the fewer possible solutions, the faster it will work.
Updated . From the discussion of the related message by M.SE, I see that the connection between the two inequalities here is part of the structure of the problem. Given this, a slightly simpler solution can be given. The code below also contains a couple of additional optimizations that speed up the solution for the case with 8 variables from 88 milliseconds to 34 milliseconds on my laptop. I tried it with examples with 22 variables and got the results in less than a minute, but it will not be practical for hundreds of variables.
def solve(smin, smax, 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
You would apply this for example with 8 variables, for example,
solutions = solve(185, 205, (97, 89, 42, 20, 16, 11, 6, 2)) len(solutions) 4015
This solution directly lists the lattice points in a restricted area. Since you want all these solutions, the time required to obtain them will be proportional (at best) to the number of connected lattice points, which grows exponentially with the number of dimensions (variables).