私は長期実行アルゴリズムを開発しており、計算の現在の状態をユーザーに知らせたいと思っています。すでに行われたすべての計算のパーセンテージを示す進行状況バーを追加することを考えました。
私の問題は、実行する計算の合計数を事前に見積もることができないことです。どういうわけか私は木を発見していて、実際にそれを探査しないとその木がどれほど広大かを知ることができません。
プログレスバーに関しては、それは時々プログレスバーが後退する可能性があることを意味します。
たとえば、ツリーの最初に10個のルート要素があるとしましょう。最初の要素に対して計算を実行するので、1/10 = 10%
完了ですが、他の10個の新しい要素を同時に発見し、1/20 = 5%
完了。
プログレスバーはまだ役に立ちますか?報告だけはしたくないX out of Y elements processed
。
処理する要素の数が増える可能性がある場合に、処理された要素の数のステータスを報告するより良い方法はありますか?
処理を開始する前にツリー全体をトラバースできる場合は、分岐を発見している間に不確定の進行状況バーを表示し、最大値がわかったら従来の進行状況バーに切り替えます。
処理前にツリーの合計サイズを特定できない場合は、進行状況バーが最適なオプションではない可能性があります。進行状況バーは、既知の不変の最大値への進行状況を示します。最大値がわからない場合は、進行状況バーのパラメーターを定義できません。
その場合は、リアルタイムで更新されるテキストによる説明のほうが効果的です。何かのようなもの:
発見されたアイテム:115
加工品:32
プログレスバーを逆方向に動かすことは絶対にお勧めしません。これは、進行状況が逆方向に進んでいるか、元に戻されていることを視聴者に伝えますが、そうではありません。
深さ優先トラバーサルを実行していますか?
ノードを処理するとき、ノードがいくつの子を持っているか知っていますか?
そうである場合、1つのアプローチは、任意の特定のノードに対して、各子に等しい重みを割り当てます。
例:
開始ノードを調べると、2つの子があることがわかります。
100 / 2 = 50
したがって、これらのそれぞれに進行状況バーの50%が割り当てられます。
これらの最初のものを調べると、3人の子供が見つかります。
50 / 3 = 16.7
したがって、これらのそれぞれにプログレスバーの16.7%が割り当てられます。
これらの最初のものを調べると、葉ノードが見つかります。
このリーフで必要な作業を実行してから、プログレスバーを16.7%進めます。
長所:
進行状況バーは常に順方向に移動します。タスクをカウントするために事前にツリーを走査する必要はありません。
短所:
子の数が少ない(またはタスクが簡単な)ノードには、時間に関して過度の重みが与えられます。これにより、進行状況バーが「ジャンプ」して表示される場合があります。
ステータスバーの長さも長くするのはどうですか?そうすれば、達成率が下がっても、進捗は上がります。
[###-------] |30%| 3/10
[####----------------] |20%| 4/20
[#####---------------------] |19%| 5/26
2つのステータスバー、つまり「作業完了」と「合計作業」を重ね合わせたものと考える方が簡単です。彼らが会うとタスクは終了しますが、両方とも成長する可能性があります。
合計作業量が上限(バーの最大長)を超えている場合は、スケールを変更する必要があり、進行状況が視覚的に逆に表示されます。あなたが説明する問題-固定されたスクロールバーの長さでパーセントを使用する-は、合計が増加するたびに再スケーリングすることになります。
[#############-----------] 30|54%| 13/24
[##########------------] 60|45%| 20/44
補うために、
木を扱っているので、対数目盛を使用すると役立つでしょう。定数を掛けて上限を増やすことをお勧めします(例:bound = bound * 1.5)。
あなたが扱っている特定のタイプのデザインパターンに関して、私は不確定なプログレスバーのデザインを見ていると思います。これらは一般的に非常に基本的な傾向があるため、少し注意が必要ですが、詳細を提供する場合は、正確でユーザーを混乱させないようにする必要があります。
ツリーの展開を視覚化して表示でき、プロセス全体の進行状況バーを表示する代わりに、進行状況インジケーターがツリーの個々のブランチの進行状況を表示することをお勧めします。したがって、新しい分岐点に到達すると、基本的に前のプロセスが終了し、新しい分岐点を開始しますが、ユーザーはこれがツリーの特定の部分にすぎず、プロセス全体ではないことを知っています。
基本的に、各ノードに進行状況バーがあるツリーを想像してみてください。
コメントからの追加情報に基づいて、次の状況が適用されるようです:
したがって、既知の範囲内の進行状況を進行状況バーとして表現し、それを現在のノードまたはサブツリーの名前など、頻繁に変化する何かを表示するラベルと組み合わせるかオーバーレイすることを選択します。これは、ユーザーに何らかのアクティビティがあることを示しています。アプリケーションが実際にハングアップする場合は、プロセスがフリーズした場所を正確に示すバグレポートの情報があり、問題のサブツリーの完全な範囲に関する知識を必要としない情報です。
はい!
プログレスバーには、利用可能な完了の見積もりが表示されます。理想的には完全にスムーズに移動し、100%に達した瞬間に進行が完了するはずです。実際には、進行状況の推定は常に最悪であり、進行状況バーはびくびくしています。
ユーザーに正直になるためにできる限り頑張ってください。それらに最良の推定値を与えます。
しかし、もしあなたが本当に独善的に見えたいなら、現実が追いつくまでそれを待つことができます。逆方向に進むよりもユーザーに良い体験を与えるかもしれません。何と言えばいい?ほとんどの人は嘘に慣れています。
2つの進行状況バーを使用する多くのアプリケーションを見てきました。たとえば、全体の進行状況を示す1つの進行状況バーと、現在のアイテムの進行状況を示す2つ目の進行状況バーです。このように、一部のアイテムは高速で、他のアイテムは低速になる場合があります。全体的なプロセスは、たとえば、すでに処理されているツリーのレベル2のサブツリーの数です。現在のアイテムはレベル3に依存する場合があります。
実際の例:
多くの回答は、ユーザーエクスペリエンスが不確定な進行状況バー、または進行が遅くなる/ジャンプする/後方に移動する進行状況で苦しむ可能性があることを示唆しているため、ロード時間が長いコンピューターゲームの数と同様の別のアプローチで解決できます。
Processing Level 1 Nodes...
[#######----------] 35% done
「処理レベル1のノード」から始めて、ノードの数を推測してください。ノードの処理中にプログレスバーに正確なプロセスを表示します。新しいノードの検出は、最初の進行状況バーが100%になるまで表示されません(したがって、最初の推定値が20ノードだった場合、20ノードが処理された後、現在70ノードであっても100%になります。より多くのノードを処理する)
次に、上部のテキストを変更して、操作の2番目のステップが開始されたことをユーザーが確認できるようにします。進行状況バーを0%にリセットし、新しい推定値を計算係数として使用します。したがって、さらに50 Node処理が推定される場合、各ノードは2%を追加します
Processing Level 2 Nodes...
[#----------------] 2% done
ユーザーは常にバーのスムーズな進行を体験し、おそらく完全な不確定バーよりも少し良い感じになります。そして、実際には常に新しいレベルが処理されているので、プログラムがスタックしているかどうか、彼は質問しません。アプリケーションを何度も使用すると、期待するレベルの数がわかる場合があります。
編集:これらの「レベルX」番号は、ツリーの実際の深さレベルまたはコードの実際の論理処理ステップに対応する必要はありません。それらは単に「最初の見積もり」、「2番目の見積もり」などです...ユーザーがいつでも感じられるように任意の数値だけ-実行する必要がある「新しい」作業がいくつかありますが、処理は高速でスムーズです
後戻りするのは変だと思います。基本的で視覚的なものが必要な場合は、進行状況が表示されたときにのみプログレスバーを更新するように指定できます。その結果、最初の進行が速くなり、その後に急激な進行が見られる場合がありますが、多くの進行状況バーはとにかくそのように機能します。
または、2つの数値(45完了/ 345待機)を表示して、リアルタイムで数値を増やすこともできます。一部の検索がこのように機能するのを見たことがありますが、どこで思い出せないでしょう。
推定の良い方法がない場合は、推定しないほうがよい-ロールバックは悪い推定の形式として数えられるため、回避する必要がある-代わりに、処理された要素の数と所要時間を表示し、ユーザーが「前回これを行ったとき、要素は10kでしたが、今回は15kでした...」の論理
これが私の提案です。ツリー全体のサイズを事前に知ることはできません。ただし、ルートのすぐ下にあるオブジェクトの数はわかります。1レベルの深さをスキャンすると、ルートのN番目のオブジェクトにあるオブジェクトの数もわかります。これら2つを組み合わせると、デュアルプログレスバー設定を使用できる場合があります。ルートレベルオブジェクトに1つのプログレスバーがあり、2番目のプログレスバーは、現在進行中のルートレベルオブジェクトの直接の子である要素を参照します。ただし、この方法には2つの欠点があります。
ただし、ツリーが持っているオブジェクト(または拡張メソッドを記述できるオブジェクト)を制御できる場合は、現在のアイテムが持つ子の数をカウントする再帰関数を作成することができます。できれば、アイテムが更新されるたびに更新されるツリーの作成中に追加されます。 @Bobwiseによって提案された回答を使用できることを意味するため、このメソッドが高速であるほど、ネイティブプロパティの使用が手動の反復よりも推奨されます。
アプリはウイルス対策ソフトウェアによく似ているようです。
前述のように、テキストのみのインジケーターが必要な場合があります。本当に進行状況バーに設定している場合は、まずマーキーを使用してツリーを特定のレベルまでスキャンし、「メイン」ブランチの数をスキャンしてから、それを使用して、十分に機能することを期待します。
また、プログレスバーの値をゆっくりと減らし、約10%の減少に制限することもできます。それが小さくて段階的である場合、ユーザーはこれに気付くべきではありません。目を騙してlessを目立たせたい場合は、アニメーションを追加して、ほぼ同じように見せることもできます。
合計がまだ更新中であり、%値の信頼度が低い/変更される可能性があることを明確に明らかにしてはどうでしょうか?
これは、複数のディレクトリ(ノードのツリー)をスキャンするときに「WinMerge」が採用するアプローチの修正バージョンです。
**Progress**
Total items: 500 (still scanning for more..)
Proccessed: 100 (~20%)
..「ジャンプ」して戻る:
**Progress**
Total items: 1500 (still scanning for more..)
Proccessed: 150 (~10%)
..その後、次のように進化します。
**Progress**
Total items: 2000
Proccessed: 1000 (50%)
進行状況バーで思い出したいくつかの調査では、進行状況の表示が一時停止または減速するだけの場合、これがユーザーの懸念の理由になり、経過時間の認識が高まることがわかりました。
他の回答と同様に、完了したユニットの数を表示すると肯定的です。これまでに数々の既知のアイテムを表示しています。時間間隔ごとに完了したユニットの割合は便利です。この情報は問題の特定に役立ち、効率の認識とユーザー主導の推定をサポートするためです。
ただし、絶対に重要なのはwhenを示すことです。つまり、ディスカバリプロセスが終了すると、リストにアイテムが追加されなくなります。
非常に便利なのは、検出プロセスの方法と理由を示すことです。これにより、ユーザーは残りのアイテム数が増加したときに驚きなしを得ることができます。