3
4

3 に答える 3

2

配列を大きさでソートするのはどうですか?

def foo(a):
    return a[np.argsort(a*a.conjugate())]
np.testing.assert_array_almost_equal(foo(a),foo(b))
于 2014-01-04T05:31:44.087 に答える
0

最悪の場合よりも良い方法でこれを行う方法があるかどうかはわかりO(n^2)ませんが、それが受け入れられる場合は、リストの1つをコピーequalsし、削除された変更された関数を使用してそれらが一致するかどうかを確認できます.

def equals(a, b, tolerance):
    return abs(a-b) < tolerance

次に、リストを繰り返し処理し、一致するものを見つけたら削除します

def equivalent_lists(a, b, tolerance):
    new_b = b[:]
    for a_item in a:
        truths = [equals(a_item, b_item, tolerance) for b_item in new_b]
        if not any(truths):
            return False
        else:
            new_b.pop(truths.index(True))
    return not bool(new_b)

少なくとも大雑把な方法で、最初のケースで機能するようです:

a = [1+1j, 1-1j, 2+2j, 2-2j, 2+2j, 2-2j]
b = [2+2j, 2-2j, 1+1j, 1.000000000000001-1j, 2+2j, 2-2j]
c = [2+2j, 2-2j, 1+1j, 2-1j, 2+2j, 2-2j]

equivalent_lists(a, b, 0.0001)
>>> True
equivalent_lists(a, c, 0.0001)
>>> False

最も美しいソリューションではありませんが、少なくともかなり透過的な方法で機能しているようです。

于 2014-01-04T02:57:22.067 に答える
0

もう 1 つのアプローチは、2 次元空間の点で考えることです。 aポイントのセットです。 b別のセットです。の各点はbの点に近い必要がありaます。

diff = np.array(a)[None,:]-np.array(b)[:,None]
X = np.round(diff*diff.conjugate())==0  # round to desired error tollerance
X

array([[False, False,  True, False,  True, False],
       [False, False, False,  True, False,  True],
       [ True, False, False, False, False, False],
       [False,  True, False, False, False, False],
       [False, False,  True, False,  True, False],
       [False, False, False,  True, False,  True]], dtype=bool)

次のステップはテストXです。a(およびb)内の値が異なる場合True、各列および各行に 1 つ存在する必要があります。しかし、ここには重複があります。

In [29]: I,J=np.where(X)

In [30]: I
Out[30]: array([0, 0, 1, 1, 2, 3, 4, 4, 5, 5])

In [31]: J
Out[31]: array([2, 4, 3, 5, 0, 1, 2, 4, 3, 5])

set(I)set(J)はどちらも [0,1,..5] であるため、すべての行と列が一致します。重複があっても、このセット テストで十分な場合があります。ポイントとミスマッチの他の組み合わせを探る必要があります。

この回答は不完全ですが、いくつかの有用なアイデアを提供する可能性があります。

于 2014-01-04T23:35:51.487 に答える