2010-12-10 14 views
0

私は、サイズNのアイテムのセットを持っています。アイテムは確率でソートされています。これらのアイテムの正方行列m [N] [N]は、Cスタイルのメモリ構成では、類似の確率を持つ要素が広がっています。例えば、m [0] [100]は、m [100] [0]から非常に遠くにあり、他はすべて同様の確率である。単純な方法で要素を並べ替える必要があるので、より可能性の高いものは0に近づく傾向があります。正方行列である必要はなく、ベクトル[N * N]になります。そして、それは完璧である必要はありません、同様の確率を持つ要素がいくらかグループ化されていれば十分です。正方行列順列

私は、置換された行列/ベクトル上の位置を与える関数f(i、j)を探しています。可能であれば、非常に簡単な操作で(例えば、正方形や区切りは使用できませんが、プログラムの条件はOKです)

もっとグラフィカルなリファレンスとして、私はこのようなものを探しています。 [BBCのCantorの議論に関する数学の話から] alt text

しかし、正確にその順列である必要はありません。対角線上を歩いている要素は、ほとんどが近くにグループ化されています。

まあ、これはおそらく非常に単純なことだと知っていますが、学校/ユニとWolframalphaが助けになってから何年も経ちました。

ありがとうございます!

+1

スペースフィルカーブをお探しですか? http://en.wikipedia.org/wiki/Space-filling_curve – ltjax

+0

必ずしもそうではありません。イメージのような便利なものがあれば、(i、j)から後ろへの実用的な変換があります。しかし、同じ対角線の要素が主にグループ化されている限り、他の方法でも構いません。 – alecco

+0

あなたの例では、 'm [0] [100]'と 'm [100] [0]'は同じ鍵を持っています(ここでの確率 - ここで確率を呼ぶのは状況を混乱させると思います)。だからあなたがあなたのインデックス_i_と_j_を呼び出すならば、ソートするキーは 'i + j'です。これは正しいです? – nategoose

答えて

3

あなたの質問は少し不明であるが、グラフィックによって、あなたは、例えば、F(1,2)= 8

I + jがために、そのパスのマッピングを記述する機能をしたいのインデックスを与えます対角、それをdと呼ぶ。その上の対角線に(d + 1)d/2個の要素があります。 dが偶数の場合、右にカウントアップし、右にカウントダウンして左にカウントするので、対角でカウントした要素の数は、それぞれj + 1またはi + 1です。

unsigned int f(unsigned int i, unsigned int j) 
{ 
    unsigned int d = i+j; 
    unsigned int k = (d+1)*d/2 + (d%2 ? i : j) + 1; 
    return(k); 
} 

EDIT:
私は馬鹿のように感じます。
上記の関数は、d < = Nでは動作しますが、d> N(行列の右下半分)では動作しません。

最初のものが最初です。何らかの理由で、私は0の代わりに1でインデックスを開始したので、f(0,0)= 1となり、これは実際には一貫していません。あなたが気にしないなら、私はそれを削除します+1、そのようにf(0,0)=0。右下の半分を処理するために、

unsigned int f(unsigned int i, unsigned int j, unsigned int N) 
{ 
    unsigned int d = i+j; 
    if(d>=N) 
    return(N*N - f(N-1-i, N-1-j, N) - 1); 
    unsigned int k = (d+1)*d/2 + (d%2 ? i : j); 
    return(k); 
} 
+0

これは非常によく見えます。テストの後に受け入れます:) – alecco

+1

+1。しかし実際には 'd%2 '部分は必要ありません(なぜなら対角線上の方向は問題の文から実際には重要ではないからです)。私は平方根を使用せずに逆変換を実装する方法を実際には見ていませんでした。 – lijie

+1

@lijie: 'd%2'がなければ連続性の問題があると思いますが、必要がなければ必要ありません。逆関数については、必要に応じてsqrtを使わずに行うことができます。シンプルさ、明快さ、効率のトレードオフです。 – Beta