このドキュメントは http://edu.net.c.dendai.ac.jp/ 上で公開されています。
並列計算とは複数のプロセッサを使って問題を解く計算モデルです。 モデルには大きく分けて二つがあります。
並列計算ではいくつかの前提があります。 現実的なモデルではプロセッサ数はあらかじめ決まってますが、理論的な並列 計算ではプロセッサはいくつも使って良いです。 また、プロセッサの構成や接続は入力の長さ毎に変えて構いません (入力ごとに構成することは、 1 を出す回路、 0 を出す回路を並べるだけで問題が解けてし まうので許されない)。 なお、長さ n に対して回路がプログラムにより決定可能であることが必要で、 これを Uniformityと言います。
計算量は実行時間やメモリ使用量の他、プロセッサの数、接続段数等も考慮し ます。
入力の長さ n に対して、 O(nk) 個のプロセッサで O(logk n) 段数で計算でき る問題のクラスを NC と言います。 NC ⊆ P は知られていますが、異なるかどうかはわかっていません。 P=NP 問題同様 NC も P と異なると信じられています。 なお、 k を 1 や 2 に固定したクラスを NC1, NC2 などと呼ぶこともあります。
二入力二出力のゲートとして、数 x, y を入力した時、出力 p, q が x≤y なら p=x, q=y、一方 x>y なら p=y, q=x となるもの を Comparator と呼びます。 この Comparator ゲートのみを使って入力された数列をソートすることを考え ます。 これを実現するためのネットワークをソーティングネットワーク と呼びます。
簡単のため左側に入力列が縦に与えられるとし、横線でデータの流れを表しま す。 そして、 Comparator を二つの横線を結ぶ縦の線分で表します。
3 入力のソーティングネットワークを示します。
逐次実行型の Bubble Sort とは次のようなプログラムでした。
#include <stdio.h>
#define N 5
int main(void){
int a[5]={4,5,3,2,1};
int i,j,temp;
for(i=0;i<N;i++){
for(j=1;j<N-i;j++){
if(a[j-1]>a[j]){
temp=a[j-1];
a[j-1]=a[j];
a[j]=temp;
}
}
}
return 0;
}
この中の if 文の部分は二つのデータを比較して交換するので、 Comparator にあたります。 したがって、この for 文が示す Comparator 通りにソーティングネットワー クを構築すれば、任意の n 入力に対して回路を作ることができます。
Comparator の数は N-1+N-2+...+1=N(N-1)/2=O(n2), 段数は N-1+N-2=2N-3=O(n) となります。
二つのソート列が存在する時、その二つを合成して一つのソート列とするのが マージソートです。 さらに、最初全てのデータを一つだけからなるソート列と見なし、それぞれを 合成して全体をソート列にするのもマージソートと呼ばれます。
ソート列 a0,a1,a2,...,an-1 と b0, b1,...,bn-1 に対して、マージソー トは次のように帰納的に行います。 ソート列の部分列はソート列になりますので、偶数番列: a0,a2,...,an-2 と b0,b1,...,bn-2 同士をマージします。こ れを c0,c2,...,c2n-2 と呼び直すことに します。 一方、奇数番列: a1, a3, ..., an-1 と b1, b3, ..., bn-1 も同様にマージし c1,c3,...,c2n-1 と呼ぶことにします。 ここで ai が bj<ai<bj+1 という関係になってい たとします。 j または j+1 と i は偶奇を共にします。
同様の議論で、全体で j 番目の大きさの要素は j が偶数の時は cj-1 か cj に、j が奇数の時は cj か cj+1 のどちらかに置かれることになります。 従って、この偶数番目、奇数番目ごとのソートの後、 c1と c2、c3とc4、... の順番を調整すれば全 体をソートできることになります。 つまり、n 要素(0番目から n-1 番目)のマージソートは次の ようにするとできます。
但し、 2 要素は単純に Comparator をつなぐだけでできます。 このようにして作った 8 要素のマージソートのソーティングネットワークを 示します。
n/2 個のソート列ふたつを n 個につなげるために必要な段数 s(n) は偶数、 奇数番目のソートは並列にできますので、s(n)=s(n/2)+1,s(2)=1 より、 s(n)=O(log n)。 また Comparator の個数 g(n)=2g(n/2)+(n-2)/2 より g(n)=2(2(g(n/4)+n/4-1)+n/2-1)=22g(n/4)+n/2-2+n/2-1 =...= 2log n+n/2log n + 2log n =O(nlogn) これを 1 個ずつ、2個ずつ、4 個ずつ、...、n 個と log n 段重ねますので、 全体の段数と Comparator の個数はそれぞれ O( log2n) と O(n log 2n)。
以下にアルゴリズムの複雑さを示します。 AKS はこれからお話するアルゴリズムです。
ソート名 | 段数 | ゲート数 |
---|---|---|
Bubble | O(n) | O(n2) |
マージ | O(log2n) | O(n log2 n) |
AKS | O(log n) | O(n log n) |
Knuth の Lower Bound により、ゲート数の最小値は Ω(n log n) でし た。 また段数も Ω(log n) なので、 AKS は最適な回路になっています。 但し、定数が巨大(2100)なので実用的な回路ではありません。
M. Ajitai, J. Komlós, E. Szemerédi "An O(n log n) Sorting Network", 15th STOC(1983)
グラフを G=(V,E) で表す。 但し、 V は頂点の集合を表す有限集合、 E は辺の集合を表し、 E ⊆V×V である。 この時、 V の部分集合 A に対して、A の隣接頂点の集合を Γ(A)={ v∈V | (v,a)∈E , a∈A} で表す。 二部グラフ(bipartite Graph) G=(V1,V2,E) とは、頂点集合 V1, V2 でそれぞれ、 V1 内部、V2 内部に辺 が存在しない、つまり E ⊆ V1×V2 となる。
bipartite graph (V1, V2, E) |V1|=|V2|=n が (λ, α, c) expander graph とは、V= V1, V2 について、 G の最大次数は c かつ、 V の任意の部分集合 A に対して、 |A|≤ αn の時、|Γ(A)|≥λ|A| が成り立つことを言 う。
1 より大きい任意の λ と 正の数 α がλα<1 を満たすとき、 (λ, α, c) expander graph が存在するような c を λ と α から定めることができる。
(2,1/3,2^100) expander graph を構成的に作れることが示されている。 一方、(2,1/3,8) が存在することが言えている。 また、頂点数 n に対して、 O(log n) の次数のランダムグラフも高い確率で Expander になるらしい。
ε=10-15 などとする時、 ε-halver とは次のよ うな性質をもつ回路です。
なお、 m が小さくなるとエラーが発生しなくなることに注意
((1-ε)/ε, ε, c) expander graph を用意します。 これを入力 m 入力に対して、上半分、下半分で m/2 個ずつに分割します。 この expander graph は次数が c なので、c 個の 1-factor に分割します。 1-factor の定義は「次数が 1 の全域部分グラフ」というものです。 次数が 1 とは他とは接続していない辺を意味しますので、すべての頂点を含 む独立辺の集合になります。 この c 個の 1-factor に対応させて Comparator を配置し、 c 段の並列回路 とします。
エラー確率を ε-halver とは別に設定します (ε=10-6など)。 m 入力に対して、 1 段目は m/2 ずつ、 2 段目は m/4 ずつとどんどん ε-halver を使用して、ひとつの部分の大きさが m10-9 になるまで半分ずつに分割していきます。 この段数は log 109 になります。 途中の ε-halver で一回もエラーが出ない確率は (1-εm/2) (1-εm/4)...(1-εw) となり、エラーが出る確率はこれを 1 から引いたものになります。 これを展開すると ε の一次の項は (m/2+m/4+...+w) となり、m/2 が 支配的になります。これは w の大きさの 109 倍になるので、 結 局エラーの確率は 109wε=10-6w 程度になりま す。 前半部分のエラーに関しても同様の議論でできます。
基本的には与えられた列に対してさまざまな分割を組み合わせて ε near sort をかけまくります。 小さい列に関しては ε-nearsort は実際にエラー無しでソートします。 3log n 段かけると ε-nearsort は定数段、O(n) プロセッサですの で、全体で O(log n) 段、 O(n log n) 個の Comparator になります。
Sorting Network http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/networks/sortieren.htm