2016-12-20 136 views
0

我正在創建一個程序來解決平面系統問題,而且我一直在檢測飛機是否重合。 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

具有初始列表和期望結果的示例示例在這裏將有所幫助 –

+0

您可以添加一些帶有預期輸出的輸入示例嗎?你的意思是你的函數在這種情況下應該返回'True',例如:'l1 = [1,2,3]'和'l2 = [2,4,6]'? – ettanany

+0

如果'one = two * 4.5',即'one'中的元素是'two'中相應元素的4.5倍,那麼輸出結果是什麼? – Divakar

回答

2

做一個雙二維數組的列是輸入陣列(我假設它是一維的),並使用numpy.linalg.matrix_rank計算矩陣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 

現在讓yx的倍數:

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 
+0

感謝+1注意到浮點不精確 – Memcallen

5

如果你真的需要一個確切的多個,則:

def coincident(one, two): 
    return np.dot(one,two)*np.dot(one,two) == np.dot(one,one)*np.dot(two,two) 

這工作,因爲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): 
    abab = np.dot(one,two)*np.dot(one,two) 
    aabb = np.dot(one,one)*np.dot(two,two) 
    return abab > aabb*0.99999997 
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 
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 
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) 
相關問題