web-dev-qa-db-ja.com

睡眠ソートの時間の複雑さは何ですか?

このソートアルゴリズムを考えると、その時間の複雑さをどのように表現しますか?

元々ここに表示 (部分アーカイブ)

#!/bin/bash
function f() {
sleep "$1"
echo "$1"
}
while [ -n "$1" ]
do
    f "$1" &
    shift
done
wait

example usage:
./sleepsort.bash 5 3 6 3 6 3 1 4 7
64
justinhj

Paxdiabloが最も近いと思いますが、それは正しい理由ではありません。時間の複雑さは、キャッシュサイズ、メモリ制限などの実際のハードウェアの問題、この場合はプロセスの数の制限、スケジューラーの動作を無視します。

時間の複雑さに関するウィキペディアのページ に基づいて、答えは、次のように定義されている場合、ランタイムの複雑さを判断できないということです。

通常、時間の複雑さは、アルゴリズムによって実行される基本操作の数をカウントすることで推定されます。基本操作では、実行に一定の時間がかかります。したがって、かかる時間とアルゴリズムによって実行される基本操作の数は、せいぜい一定の係数だけ異なります。

それから、このアルゴリズムの実行時の複雑さについて話すことはできません。なぜなら、基本操作にかかる時間は非常に異なるため、かかる時間は一定の要因以上に異なるからです。

16
justinhj

O(max(input)+n)

ほとんどのソートアルゴリズムはデータに依存しないため、複雑さは表現しにくいように見えます。それらの時間は、データ自体ではなく、データ量に応じて変化します。

FWIW、指摘されているように ここ 、これはデータをソートするための信頼できるアルゴリズムではありません。

29
blahdiblah

誰も対処していないと思われる1つのポイントは、それらのsleepsがどのように実装されているかです。最終的にはどこかでスケジューラーになり、操作の複雑さは使用されるスケジューリングアルゴリズムに依存します。たとえば、sleepsがイベントとして優先度キューに入れられると、複雑さO(n log n)のヒープソートに相当するものになります。単純なスケジューリングアルゴリズムは、O(n ^ 2)になる可能性があります。

19
hammar

そのアルゴリズムの時間の複雑さとプロセスの複雑さの両方がO(braindead)です:

  • データセットに十分な大きさのがあると、太陽が爆発するまで答えを待つことになります(264 秒は半兆年以上です)。
  • 十分に大きいデータセットサイズ、を使用すると、(a)プロセスの制限に達します。 (b)後の睡眠が始まる前に早期睡眠が終了すること、つまり(2,9,9,9,9,9,...,9,9,1)セットが12を正しくソートしないことを発見します。

この場合、時間の複雑さは関係ありません。 get "wrong"ほど最適化されていないことはできません。データセットのサイズが変化したときに複雑さの分析を使用してアルゴリズムを比較することはできますが、そもそもアルゴリズムが滑luな場合はそうではありません:-)

11
paxdiablo

線形に見えますが、複雑さはまだO(log(n) * max(input))です。

漸近的な時間の複雑さについて話すとき、それはnが無限に大きくなるときにどれだけの時間がかかるかを意味します。

比較ベースのソートアルゴリズムはO(n * log(n))より高速にすることはできません。また、Sleep-Sortは実際には比較ベースです。

プロセスはn秒スリープし、起動します。 OSは、すべてのスリーププロセスから残りの最小スリープ時間を見つけて、時間が経過したらスリープ状態を解除する必要があります。

これには、O(logN)要素の挿入にかかる時間、およびO(1)最小要素の検索、およびO(logN)最小要素を削除します。

Nが非常に大きくなると、プロセスの起動に1秒以上かかり、O(n)より大きくなります。

2
RnMss

スレッドを読むと、あなたの質問はすでに答えられていることがわかります。時間の複雑さはO(max(input))であり、操作の複雑さ(操作の数)はO(n)です。

2
Jordan Running

ヨルダンとは違いますが、壁時計の時間の複雑さは、O(max(input))ではなく、mが各アイテムのサイズであるO(2 ^ m)としてより適切に表現されると思います。

各アイテムのサイズがmの場合、最大のアイテムの整数値は2 ^ mになります(マイナス1、ただし誰も気にしません)。構造上、アルゴリズムでは、セットアップ時間が1よりも小さい定数である必要があります。

したがって、壁時計時間の複雑さO(2 ^ m)、操作カウントの複雑さO(n)。

セットアップ時間を考慮に入れた修正されたアルゴリズムは、壁時計時間の複雑さO(2 ^ m + n)を持つ可能性があります。たとえば、最初に現在の時刻を記録し、base_time = start_time + k*len(list)(適切な定数k)を計算してから、時刻_base_time+i_までスレッドをスリープさせることができます。 k*len(list)は明らかにO(n)であり、iはO(2 ^ m)であり、合計でO(2 ^ m + n)。

2
sabik