0

我正在为我的 GA 工作(实际上是健身计算),我需要从一个值最接近零的列表中获取两个值的索引。我一直在互联网上寻找大约一个小时,虽然看起来我已经变得非常接近,而且看起来它应该可以工作,但使用打印语句进行测试表明我的代码不起作用..

我现在的流程是:

  1. 找到最近的索引并存储它
  2. 从原始数组中删除它
  3. 寻找新的最近的

这是有问题的代码:

closest = min(range(len(fitness_levels)), key=lambda i: abs(fitness_levels[i]-0))
fitness_levels.pop(closest)
second_closest = min(range(len(fitness_levels)), key=lambda i: abs(fitness_levels[i]-0))

fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]被授予时,这些数字是完全随机生成的。

就像我说的,当我对打印语句进行一些检查时,我发现这种方法不能以多种方式工作,有时我什至最终得到了相同的索引不同的值。有没有人有更好的可行方法来做到这一点?- 蟒蛇2.7.x

旁注-我来自 php 背景,仍在准备使用 python,因此某些语法可能是错误的...

4

4 回答 4

3

虽然使用密钥进行排序abs会起作用,但这是一个 nlogn 解决方案。这是一个线性解决方案

fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]
a,b = sorted(fitness_levels[:2], key=abs) # setting defaults. a<=b
ia, ib = 0,1 # indices
for i,val in enumerate(fitness_levels[2:]): # use itertools.islice for large lists (for constant space)
  if abs(val) < abs(a):
    b,a = a,val
    ib, ia = ia, i
  elif abs(val) < abs(b):
    b = val
    ib = i
于 2013-08-23T14:53:32.450 回答
0

像这样的东西:

>>> lis = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]
for i,x in enumerate(sorted(enumerate(lis), key=lambda x:abs(0 - x[1]))[:2]):
    x = list(x)
    x[0] -= i    #reduce index as an item was removed from the list
    ind, val = x
    print "{}->{}".format(ind, val)
...     
4->10
13->10

如果您不想减少索引,那么这就足够了:

>>> sorted(enumerate(lis), key=lambda x:abs(0-x[1]))[:2]
[(4, 10), (14, 10)]
于 2013-08-23T14:53:00.817 回答
0

我会去:

fitness_levels = [-20, 23, -55, 11, 10, -18, -48, 16, -60, 20, 22, 16, 21, 66, 10, 46, -42]

import heapq
closest2 = heapq.nsmallest(2, ((abs(val), idx) for idx, val in enumerate(fitness_levels)))
# [(10, 4), (10, 14)]
indices = [el[1] for el in closest2]
# [4, 14]
于 2013-08-23T14:53:21.757 回答
0

怎么样:

>>> from numpy import argsort,abs
>>> fitness_levels = [-20,23,-55,11,10,-18,-48,16,-60,20,22,16,21,66,10,46,-42]
>>> i,j = argsort(abs(fitness_levels))[:2]
>>> print (i,fitness_levels[i]),(j,fitness_levels[j])
>>> (14 10) (4 10)
于 2013-08-23T15:30:34.580 回答