オブジェクトのリストがあるとします。ユーザーは、作業中にほとんどすべてのオブジェクトを使用します。ユーザーが主に使用する順序にリストが適応するように、オブジェクトのリストをどのように並べ替えることができますか? そのためにどのアルゴリズムを使用できますか?
編集:多くの回答は、オブジェクトが使用された回数を数えることを提案しました。すべてのオブジェクトが同じ量で、異なる順序で使用されるため、これは機能しません。
オブジェクトのリストがあるとします。ユーザーは、作業中にほとんどすべてのオブジェクトを使用します。ユーザーが主に使用する順序にリストが適応するように、オブジェクトのリストをどのように並べ替えることができますか? そのためにどのアルゴリズムを使用できますか?
編集:多くの回答は、オブジェクトが使用された回数を数えることを提案しました。すべてのオブジェクトが同じ量で、異なる順序で使用されるため、これは機能しません。
オブジェクトが何回使用され、どの順序で使用されたかをカウントします。
したがって、オブジェクト X が 3 番目に使用された場合は、それを現在のカウントで平均し、その結果をリスト内の位置として使用します。
例えば:
アイテムの用途 使用順序 ------------------------------------------------------ オブジェクト X 10 1,2,3,1,2,1,3,1,2,2 (18) オブジェクト Y 10 3,1,2,3,3,3,1,3,3,1 (23) オブジェクト Z 10 2,3,1,2,1,2,2,2,2,3 (20)
使用は、ユーザーがオブジェクトを使用した回数であり、使用順序は、アイテムが順序で使用された場所のリスト (または合計) です。
各注文のリストを個別に使用すると、パフォーマンスの問題が発生する可能性があるため、ポジションの合計を保持することをお勧めします。合計を保持する場合は、オブジェクトが使用されるたびにその合計に注文を追加するだけです。
順位を計算するには、順位の合計を使用回数で割って平均を求めるだけです。その時点でしなければならないことは、リストを平均で並べ替えるだけです。
上記の例では、次の平均 (および順序) が得られます。
オブジェクト X 1.8 オブジェクト Z 2.0 オブジェクト Y 2.3
Userクラスが次のようになっている場合:
class User
{
Collection<Algo> algosUsed = new List<Algo>(); //Won't compile, used for explanation
...
}
そして、あなたのアルゴクラスは次のようになります:
class Algo
{
int usedCount;
...
}
Algo
オブジェクトの特定のインスタンスをオブジェクトにバインドしUser
て、使用頻度を記録できるようにする必要があります。最も基本的なレベルでは、情報をファイルまたはストリームにシリアル化します。ほとんどの場合、データベースで何が使用されているかを追跡する必要があります。次に、を取得して関数をUser
呼び出すと、のパラメータを次のパラメータで並べ替えます。sort
algos
User
usedCount
Algo
また、オブジェクトごとにカウンターを使用してその使用を監視しますが、使用するたびにリスト全体を並べ替えるのではなく、リストを「ローカル」に並べ替えることをお勧めします。バブルソートのように、カウンターを増やしたばかりのオブジェクトを上のオブジェクトと比較し、必要に応じてそれらを交換します。交換した場合は、オブジェクトとその新しい上位オブジェクトなどを比較します。
ただし、ソートが適切に実装されていれば、以前のメソッドとそれほど違いはありません。
キャッシュが必要なようです。キャッシュが使用するアルゴリズムを見て、コンテキスト切り替えに関するビジネス全体を取り上げることができると思います...「クロックスイープ」と呼ばれるアルゴリズムがあります...しかし、それはあなたが探しているものには複雑すぎるかもしれません. 怠惰な方法で行くには、「使用済みのもの」のハッシュを作成するだけです:num_of_uses、またはクラスで、オブジェクトが使用されるたびにvar you ++を使用します。
ときどきハッシュを num_of_uses でソートするか、オブジェクトを ++ 化された変数の値でソートします。
編集:注文設定を追加しました!!! コードを見てください
Carraが言ったように、Last usedメソッドは好きではありません。これは、混乱を招く多くのソート変更を引き起こすためです。
count_accessed フィールドははるかに優れていますが
、ユーザーが過去 XX 分/時間/日などにこのアイテムにアクセスした回数に平準化する必要があると思います...
そのための最良のデータ構造は確かに
static TimeSpan TIME_TO_LIVE;
static int userOrderFactor = 0;
LinkedList<KeyValuePair<DateTime, int>> myAccessList = new LinkedList<KeyValuePair<DateTime, int>>();
private void Access_Detected()
{
userOrderFactor++;
myAccessList.AddLast(new KeyValuePair<DateTime, int>(DateTime.Now, userOrderFactor));
myPriority += userOrderFactor; // take total count differential, so we dont waste time summing the list
}
private int myPriority = 0;
public int MyPriority
{
get
{
DateTime expiry = DateTime.Now.Subtract(TIME_TO_LIVE);
while (myAccessList.First.Value.Key < expiry)
{
myPriority += myAccessList.First.Value.Value; // take care of the Total Count
myAccessList.RemoveFirst();
}
return myPriority;
}
}
これが役立つことを願っています...ほとんどの場合O(1)ところで...
オペレーティングシステムのスリープメカニズムを思い出させます
number_of_views フィールドをオブジェクト クラスに追加し、++ オブジェクトが使用されるたびにそのフィールドでリストを並べ替えることができます。また、すべてのオブジェクトの number_of_views が同じであるが 0 でない場合は、すべてのオブジェクトに対してこのフィールドを 0 にする必要があります。
ユーザーがオブジェクトを操作するときは、その 2 番目のオブジェクトに作用した前のオブジェクトの ID を保存して、特定のオブジェクトの前に使用されたオブジェクトへのポインターを常に保持できるようにします。
さらに、最も頻繁に最初に使用されるオブジェクトの ID を保存して、どこから始めればよいかがわかるようにします。
表示するオブジェクトのリストを作成するときは、最初に使用する頻度が最も高いオブジェクトとして保存したオブジェクトから始めて、最初に使用したオブジェクトの ID が保存されているオブジェクトを検索して、次に表示します。
https://stackoverflow.com/a/2619065/1429439から:
usedCount をキーとして、オブジェクトを値として OrderedMultiDictionary を使用することもできます。