2011-05-13 48 views
4

我有一個網站,用戶可以發佈並投票建議。在起始頁上,我最初列出了10條建議,標題每7秒提取一條新的隨機建議。根據人氣選擇項目:避免美化排序

我希望投票影響建議將出現的概率,無論是在10-建議列表還是在標題建議中。爲此,我有一個小算法來計算人氣,考慮到投票,年齡和其他一些事情(需要大量調整)。

不管怎樣,算法運行後我的建議和人氣指數字典人氣排序:

{ S = Suggestion1, P = 0.86 } 
{ S = Suggestion2, P = 0.643 } 
{ S = Suggestion3, P = 0.134 } 
{ S = Suggestion4, P = 0.07 } 
{ S = Suggestion5, P = 0.0 } 
{ . . .} 

我不希望這是一個榮耀的排序,所以我想介紹一些隨機元素的選擇過程。

總之,我希望人氣是從列表列表中挑選出一個建議的概率。

有一個完整的建議/流行清單,我該如何去選擇基於概率的10出?我怎樣才能應用相同的循環標題建議?

+0

基本上你想要的建議1至約6.4倍,可能比建議3到採摘( '0.86/0.134〜6.4179 ...')。是對的嗎? – 2011-05-13 09:13:24

+0

你也有多次建議3,我認爲這是一個簡單的錯字 – 2011-05-13 09:13:42

+0

@Lasse - 你對兩條評論都是正確的。我解決了這個問題,謝謝;) – 2011-05-13 09:15:00

回答

7

我怕我不知道如何做到這一點非常快,但如果你有收集在內存中,你可以做這樣的:

請注意,您不需要排序名單這個算法起作用。

  1. 第一總和的所有概率(如果該概率被鏈接到普及,只是總結普及數字,其中I假設較高值意味着較高的概率)
  2. 計算在0到的範圍內的隨機數但不包括總和
  3. 開始在列表的一端,並通過它
  4. 迭代對於每一個元素,如果產生的隨機數小於普及,挑選元素
  5. 如果沒有,減去人氣來自隨機數的元素,以及繼續e到下一個

如果列表是靜態的,您可以構建範圍並執行一些二進制搜索,但是如果列表不斷更改,那麼我不知道更好的方法。

下面是一個簡單LINQPad程序演示:

void Main() 
{ 
    var list = Enumerable.Range(1, 9) 
     .Select(i => new { V = i, P = i }) 
     .ToArray(); 
    list.Dump("list"); 

    var sum = 
     (from element in list 
     select element.P).Sum(); 

    Dictionary<int, int> selected = new Dictionary<int, int>(); 
    foreach (var value in Enumerable.Range(0, sum)) 
    { 
     var temp = value; 
     var v = 0; 
     foreach (var element in list) 
     { 
      if (temp < element.P) 
      { 
       v = element.V; 
       break; 
      } 

      temp -= element.P; 
     } 
     Debug.Assert(v > 0); 
     if (!selected.ContainsKey(v)) 
      selected[v] = 1; 
     else 
      selected[v] += 1; 
    } 

    selected.Dump("how many times was each value selected?"); 
} 

輸出:

 
list 
[] (9 items) 
V P 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
9 9 
45 45 <-- sum 

how many times was each value selected? 
Dictionary<Int32,Int32> (9 items) 
Key Value 
1 1 
2 2 
3 3 
4 4 
5 5 
6 6 
7 7 
8 8 
9 9 
    45 <-- again, sum 
+0

要將其應用於單標題提示(異步提取),我應該記住或重新計算概率的總和,對嗎? – 2011-05-13 09:18:31

+1

是正確的,但如果您在開始迭代之前不知道總概率/流行度,我的算法將無法正常工作。我知道有一種算法在不知道集合中有多少元素的情況下工作,如果您只想以相同的概率選取每個元素,但對於加權概率,我不知道任何這樣的算法(這僅表示我不知道它,這並不意味着沒有這樣的算法。) – 2011-05-13 09:30:13

+0

這將做得很好,非常感謝你=) – 2011-05-13 09:31:56