2012-06-28 53 views
5

假設您有一個對象列表。用戶在工作時主要使用所有對象。 如何訂購對象列表,以便列表適應訂單,用戶主要使用?你可以使用什麼算法?排序對象列表的算法

編輯:許多答案建議計算一個對象被使用的次數。這不起作用,因爲所有對象的使用量相同,只是按不同的順序。

+0

這真的很寬泛。你有什麼特別的想法嗎?您是否打算按首選列排序?或者使用更多的啓發式方法? –

+0

'List .Sort()?' – Habib

+0

這些是同一類型的對象嗎?您可能可能創建一個基類,所有對象類型都將繼承,並將公開(int)UsageCount屬性。然後,您可以在每次使用時增加此功能,並通過它訂購 – Dimitri

回答

0

添加用戶訪問對象時的日期時間列表。每次用戶使用一個對象時,添加一個日期時間。

現在只需計算您的列表中日期時間條目的數量爲w(現在 - x天)並按此排序。您可以刪除>(現在 - x天)的日期時間。

用戶可能在一個月內使用不同的項目,這將反映這些更改。

+0

這不是他想要的。如果我使用對象A 100次然後使用對象B一次,那麼B對象將位於頂部,而他希望對象A位於頂部,因爲它最常用的一個 – Dimitri

+0

夠公平,改變了我的答案。 – Carra

+0

我不想煩人,但爲什麼不添加每次使用對象時都會增加的int字段。然後按字段順序:) – Dimitri

2

在您的對象內部,保留一個usedCount。每當使用該對象時,增加此計數。通過那場

objects.OrderByDescending(o => o.UsedCount); 
0

您可以將NUMBER_OF_VIEWS字段添加到您的對象類,++中,它每次對象的使用和對列表進行排序: 然後,你可以簡單地做到這一點。而且,當所有對象的number_of_views相同但不爲0時,您應將此字段設爲0。所有對象的number_of_views都相同,但不爲0.

0

我也會爲每個對象使用一個計數器來監視其使用情況,而不是重新排序整個列表在每次使用後,我會建議僅對「本地」列表進行排序。 就像在氣泡排序中一樣,我只是將其計數器剛剛增加的對象與上層對象進行比較,並在需要時將其交換。如果交換,我會然後比較對象和它的新的上層對象,等等。

但是,如果正確實施排序,它與以前的方法並沒有很大的不同。

0

如果您的用戶類看起來像這樣:

class User 
{ 
    Collection<Algo> algosUsed = new List<Algo>();  //Won't compile, used for explanation 
    ... 
} 

而且你的算法中類看起來像這樣:

class Algo 
{ 
    int usedCount; 
... 
} 

你應該能夠在Algo對象的特定實例綁定到User對象允許記錄使用頻率。在最基本的級別上,您將信息序列化到文件或流。很可能你想要一個數據庫來跟蹤正在使用的內容。然後,當你抓你User並調用sort功能你用usedCount PARAM Algo

+0

問題是所有的對象都被用於相同的擴展,所以每個對象的usedCount是相同的。只是使用順序各不相同... –

+0

@TombiUnnso我會建議你重新考慮應用程序的設計。 – Woot4Moo

0

編輯的命令algos PARAM的User:增加了一個令Preferrence!在代碼

我不喜歡最後使用的方法,因爲卡拉說,因爲它造成許多排序變化,這是混亂。

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)BTW ...
讓我想起有些操作系統

的睡眠機制
+0

說一個用戶在列表中工作一年。然後,該列表應按整個訓練實例中不同可能性的概率排序... –

+0

每次您要推送一個項目時,都可以調用Access_Detected(),這會增加鏈接列表的計數=>更好該項目是第一次的概率...但我試圖實現的是,「長時間」以前非常活躍的項目將與當前項目相比「過時」。 –

+0

關於編輯......節點的優先級越低,對象越有用 –

0

聽起來就像你想要一個緩存。我假設你可以看看緩存使用的算法,然後取出關於上下文切換的整個業務......有一種叫做「時鐘掃描」的算法......但是,對於你正在尋找的東西來說,這可能太複雜了。要走懶惰的方式,我會說只是做一個「使用的東西」的散列:num_of_uses或,在你的類中,每次使用該對象時都有一個var ++。

每隔一段時間通過num_of_uses或其對象的++'d變量的值對散列進行排序。

1

我會保持對象使用次數以及使用次數的運行次數。

因此,如果對象X被使用第三,平均它與運行計數,並使用結果,因爲它的位置在列表中。

例如:

 
Item  Uses  Order of Use 
--------------------------------------- 
Object X 10  1,2,3,1,2,1,3,1,2,2 (18) 
Object Y 10  3,1,2,3,3,3,1,3,3,1 (23) 
Object Z 10  2,3,1,2,1,2,2,2,2,3 (20) 

用途將是多少次用戶使用的對象,使用順序將是其中項目中的順序使用的列表(或總和)。

單獨使用每個訂單的列表可能會有一些性能問題,因此您可能只想保留一個位置的總和。如果保留一筆款項,每次使用該對象時只需將該訂單添加到該總和中。

要計算位置,您只需使用位置總和除以使用次數即可得出平均值。所有你在這一點上必須做的是按平均值排序。

在上面的例子中,你會得到下列平均(和順序):

 
Object X 1.8 
Object Z 2.0 
Object Y 2.3 
0

當用戶與對象交互時,保存前一對象的ID即第二對象上採取行動,從而你總是有一個指向任何給定對象之前使用的對象的指針。

此外,存儲最常使用的第一個使用對象的ID,以便您知道從何處開始。

當您構建要顯示的對象列表時,首先從您存儲爲最常使用的第一個使用對象開始,然後搜索具有存儲在其上的第一個使用對象ID的對象以顯示下一個。