1

これは、バイナリおよびプリミティブのエキスパート向けです。float R3 ベクトル構造体を実装していますが、「等しい」という私の定義は実際には「ほぼ等しい」です。具体的には、比較されたベクトルのすべての座標に対して Abs( (a[i] - b[i]) / (a[i] + b[i]) ) < .00001 は true を返します。

private static bool FloatEquality(float a, float b)
    {
        if (a == b)
        {
            return true;
        }
        else
        {
            float e;
            try
            {
                e = (b - a) / (b + a);
            }
            catch (DivideByZeroException)
            {
                float g = float.Epsilon;
                e = (b - a) / g;
            }
            //AppConsole.AppConsole.Instance.WriteLine(e);
            if (e < .00001f && e > -.00001f)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

私の問題は、これらのベクトルを Dictionary の「キー」として使用できるようにしたいという事実のために、この要件を満たすベクトルでハッシュ値を同じにする方法があるかどうかを判断することです。

ご覧のとおり、上記のコードは 3 つの異なる座標で等しいかどうかをチェックするために使用されます。

3 つの float 座標からバイトを抽出し、それぞれの中間の 2 つを使用することを考えていました。

(以下はコードではありませんが、Stack Overflow ではインデントしない限り投稿できません)

Vector(x,y,z):
x's float byte[] = [ x1 x2 x3 x3 ]
y's float byte[] = [ y1 y2 y3 y4 ]
z's float byte[] = [ z1 z2 z3 z4 ]

Hash code: byte[] {x2^x3 , y2^y3, z2 ^ z3, x2 ^ z3}

またはそのようなもの...要するに、equalsメソッドに適合するベクトルのハッシュコードが常に同じになるようにする方法に興味があります...誰かが非常に低コストの計算で素晴らしいアイデアを持っている場合、私は'ぜひ聞いてください。または、フロートがどのように格納されるか、および上記の比較メソッドが等しい場合に常に同じになるバイトについて詳しく説明している場所に私を導くことができれば.

ハッシュ関数ではなく新しい比較方法が必要になるかもしれません。バイトのいずれかが一致することを確認できる方法が本当にないからです...

4

1 に答える 1

1

基本的な考え方は単純です - float の精度を人為的に下げる必要があります。これを効率的に行う方法は、期待するデータの種類に大きく依存します。

たとえば、主に小さな値を使用している場合は、次のように簡単に使用できます。

(int)Math.Round(x1 * 1000) 
^ (int)Math.Round(x2 * 1000) 
^ (int)Math.Round(x3 * 1000)

私は実際にあなたのif (e < .00001f && e > -.00001f)条件を満たしているわけではありませんが、問題ではないことに注意してください-アイデアは、衝突を減らし、等しい値が等しいハッシュコードを持つようにすることです。等しくない値のハッシュ コードが等しくならないようにする必要もありません (可能でもありません)。残りはEquals==などのオーバーライドで処理する必要があります。ここでは、厳密な等価性チェックが存在する必要があります。Equalsand companyとは異なり、単一のベクトルに関するデータGetHashCode() しかないため、そこにある複数のベクトルからのデータを使用するオプションさえありません。

ハッシュ コードは、キーの衝突をまれにするためだけに存在します。したがってDictionary、各ベクトルが返される場合でも機能します0-GetHashCode()パフォーマンスが低下するだけです. 等しいベクトルが等しいハッシュコードで終わる限り、ハッシュコードはニーズに合ったものにすることができます:)

もちろん、ベクトルをディクショナリのキーとして使用しないことが最善の方法です。関心のある (最も役立つ) ベクトルの部分を見つけて、それをキーとして使用します。いずれにせよ、それが実際にはあなたが望むものではないことがわかるかもしれませDictionaryん (たとえば、ゲームでは、単純なグリッドのようなレイアウトから手動の空間分割まで、ベクトルで使用できるさまざまな空間分割方法がたくさんあります。 BSPのようなもの)。

于 2014-07-16T06:53:16.670 に答える