查找返回线性函数相同结果的参数范围

时间:2016-10-09 21:07:21

标签: python numpy

考虑y = round(300000/x**2)。我想找到x的范围y100 < x < 40000返回structure = {}

我如何用python / numpy做到这一点?

2 个答案:

答案 0 :(得分:2)

10040000之间的所有值都会为0返回y = round(300/x**2)

我认为你的意思是以下

def y(x):
    return round((300/x)**2)

在这种情况下,您可以使用itertools.groupby

from itertools import groupby
keys, groups = groupby(range(100, 40000), y)

现在groups将包含分组整数,这些整数会导致函数y的输出相同。

答案 1 :(得分:2)

首先:即使在问题中的修复之后,此解决方案的功劳也应该转到@CoryKramer

from itertools import groupby
groups = groupby(range(100, 40000), key=lambda x: round(300000/x**2))

无论如何,由于您使用的除法运算符,您应该注意一些事项:目前您使用整数除法,但使用 true division 运算符可能导致因舍入而导致的分组略有不同(300000/x**2 vs 300000.0/x**2)。

from itertools import groupby
groups_int = groupby(range(100, 40000), key=lambda x: round(300000/x**2))
groups_true = groupby(range(100, 40000), key=lambda x: round(300000.0/x**2))


res_int  = [(g[0], [n for n in g[1]]) for g in groups_int]
res_true = [(g[0], [n for n in g[1]]) for g in groups_true]

for v_int, v_true in zip(res_int, res_true):
    # show the min and the max for each grouping 
    print v_int[0], min(v_int[1]), 'to', max(v_int[1]), '---', min(v_true[1]), 'to', max(v_true[1])

30.0 100 to 100 --- 100 to 100
29.0 101 to 101 --- 101 to 102
28.0 102 to 103 --- 103 to 104
27.0 104 to 105 --- 105 to 106
26.0 106 to 107 --- 107 to 108
25.0 108 to 109 --- 109 to 110
24.0 110 to 111 --- 111 to 112
23.0 112 to 114 --- 113 to 115
22.0 115 to 116 --- 116 to 118
21.0 117 to 119 --- 119 to 120
20.0 120 to 122 --- 121 to 124
19.0 123 to 125 --- 125 to 127
18.0 126 to 129 --- 128 to 130
17.0 130 to 132 --- 131 to 134
16.0 133 to 136 --- 135 to 139
15.0 137 to 141 --- 140 to 143
14.0 142 to 146 --- 144 to 149
13.0 147 to 151 --- 150 to 154
12.0 152 to 158 --- 155 to 161
11.0 159 to 165 --- 162 to 169
10.0 166 to 173 --- 170 to 177
9.0 174 to 182 --- 178 to 187
8.0 183 to 193 --- 188 to 200
7.0 194 to 207 --- 201 to 214
6.0 208 to 223 --- 215 to 233
5.0 224 to 244 --- 234 to 258
4.0 245 to 273 --- 259 to 292
3.0 274 to 316 --- 293 to 346
2.0 317 to 387 --- 347 to 447
1.0 388 to 547 --- 448 to 774
0.0 548 to 39999 --- 775 to 39999

替代解决方案

这里我提出另一个解决问题的解决方案:舍入的转折点是当值达到xxx.5时,我们可以尝试反转等式并求解

formula

为0到30之间的每个x整数计算y(我们知道它会进行一些域分析或只是从先前的解决方案中偷看:P)。

points = [(y, (300000.0/(y + 0.5))**.5) for y in range(30,0,-1)]
# [(30, 99.17694073609294), (29, 100.84389681792216), (28, 102.59783520851542), (27, 104.44659357341871), (26, 106.3990353197863), (25, 108.46522890932809), (24, 110.65666703449763), (23, 112.98653657320641), (22, 115.47005383792515), (21, 118.12488464372366), (20, 120.97167578182678), (19, 124.03473458920845), (18, 127.34290799340266), (17, 130.93073414159542), (16, 134.8399724926484), (15, 139.12166872805048), (14, 143.83899044561525), (13, 149.07119849998597), (12, 154.91933384829667), (11, 161.51457061744966), (10, 169.03085094570332), (9, 177.7046633277277), (8, 187.86728732554485), (7, 200.0), (6, 214.83446221182987), (5, 233.5496832484569), (4, 258.19888974716116), (3, 292.7700218845599), (2, 346.41016151377545), (1, 447.21359549995793)]

然后,对于每个点,我们可以计算您的结果,将我们刚刚计算的点之间的所有整数分组:

from math import ceil, floor
res = [(low[0], range(int(ceil(low[1])), int(floor(up[1]))+1)) for low, up in zip(points[:-1], points[1:])]