我正在创建一个解决平面系统的程序,而且我一直在检测飞机是否重合。 AKA:我需要检查数组A的元素是否是数组B元素的倍数。 这就是我到目前为止所做的:
def coincident(one, two):
div_ = one[0]/two[0]
for v in zip(one[1:], two[1:]):
if v[0]/v[1] != div_:
return False
return np.dot(one, two) != 0
它需要2个数组,目前不再是4个元素,并将第一个元素与它们分开。然后它遍历剩余的元素并检查被除数是否与' div _'相同。最后一行是考虑其中包含全零的数组,它使用numpy来点积,并检查它是否为零。
由于某些原因,它不能很好地工作,也不能很好地处理零(除以零)。
答案 0 :(得分:5)
如果您确实需要完全倍数,那么:
Cygwin-PC ~/code_practice/Computing/stack
$ gcc -DARRAY main.c stackImpl.c ../list/arrayImpl.o
/tmp/ccapgYQI.o:stackImpl.c:(.text+0x25): undefined reference to
`createList'
/tmp/ccapgYQI.o:stackImpl.c:(.text+0x4b): undefined reference to
这是因为A⋅B= | A | * | B | * cos(t),其中t是两个向量之间的角度,所以(A⋅B)²= | A |²* | B |² *cos²(t)。如果向量是彼此的倍数,那么t是0或180度,并且cos²(t)== 1.
如果您正在使用浮点数,那么您应该允许一点舍入误差。例如,如果您希望向量的线性度在0.01度以内,并且您想要排除其中一个为0的情况,那么您可以这样做:
def coincident(one, two):
return np.dot(one,two)*np.dot(one,two) == np.dot(one,one)*np.dot(two,two)
答案 1 :(得分:2)
创建一个二维数组,其列是输入数组(我假设它是一维的),并使用rank计算矩阵numpy.linalg.matrix_rank。如果输入数组重合,则等级将为1或更小。
以下是一些例子。首先,两个随机输入。一般来说,这些不一致,所以排名应该是2:
In [114]: np.random.seed(12345)
In [115]: x = np.random.rand(4)
In [116]: y = np.random.rand(4)
In [117]: np.linalg.matrix_rank(np.column_stack((x, y)))
Out[117]: 2
现在让y
成为x
的倍数:
In [118]: y = x/23
In [119]: np.linalg.matrix_rank(np.column_stack((x, y)))
Out[119]: 1
等级是1,正如预期的那样。
请注意,您的代码没有检测到这一点,因为它没有考虑正常的浮点不精确性:
In [120]: coincident(x, y)
Out[120]: False
答案 2 :(得分:1)
稍作修改,您可以按如下方式避免除零:
def coincident(one, two):
div_ = one[0]/two[0] if two[0] else 1
for v in zip(one[1:], two[1:]):
if v[0] != div_ * v[1]:
return False
return True
试验:
print(coincident([1.1,2.2,3.3],[2.2,4.4,6.6])) # True
print(coincident([0,0,0],[0,0,0])) # True
print(coincident([0,0,0],[0,1,0])) # False
print(coincident([1,-2,3],[2,4,6])) # False
答案 3 :(得分:0)
我认为这可以处理所有情况。
def coincident(l1, l2):
try :
d = l2[0] / l1[0]
except ZeroDivisionError as e:
d = 0
if [x*d for x in l1] == l2:
return True
return False
l1 = [1,2,3]
l2 = [3,6,9]
print(coincident(l1, l2))
l1 = [0,6,9]
print(coincident(l1, l2))
输出:
True
False
答案 4 :(得分:0)
保持接近原始代码并考虑浮动pt数字,这是一种方法 -
def coincident(a, b):
M = a/b.astype(float)
return np.allclose(np.round(M),M) & np.allclose(np.diff(M),0)
我们的想法很简单,我们将第一个数组除以原始代码中的第二个数组,并通过将其与圆形数组版本进行比较来查看除法结果是或接近整数。
我们还检查所有元素的除法结果是否相同,并且区分这些结果并检查是否所有元素都接近0
。
样品运行 -
In [318]: b = np.random.rand(4)
In [319]: a = b*4.0
In [320]: coincident(a, b)
Out[320]: True
In [321]: a = b*4.5
In [322]: coincident(a, b)
Out[322]: False
In [323]: a = b*np.array([3,2,5,6])
In [325]: coincident(a, b)
Out[325]: False
In [326]: a = b*4.0
In [327]: coincident(a, b)
Out[327]: True
In [328]: a[1] = 100.0
In [329]: coincident(a, b)
Out[329]: False
如果您不关心被除数是否为整数,即多重性是否为整数,我们只考虑区分部分 -
def coincident_ignore_exact_divisibilty(a, b):
return np.allclose(np.diff(a/b.astype(float)),0)