2016-11-09 78 views
2

我正在研究基於項目的協作過濾器,爲此您需要項目之間的相似性。我發現創建一個像下面這樣的矩陣效果很好,但我現在想阻止它計算雙精度。填充沒有雙打的矩陣

我會用一個例子來解釋我的意思。假設您有5個項目的列表,每個項目的評分都基於相似性。

計算的相似之處後,我想出了以下矩陣:

 I1 | I2 | I3 | I4 | I5 | 
I1 | 1 | 0.5| 0.3| 0.2| 0.9| 
I2 | 0.5| 1 | 0.2| 0.1| 0.8| 
I3 | 0.3| 0.2| 1 | 0.5| 0.1| 
I4 | 0.2| 0.1| 0.5| 1 | 0.7| 
I5 | 0.9| 0.8| 0.1| 0.7| 1 | 

我用下面的代碼這樣做:

//allItems is a list of the 5 items 
foreach (var item1 in allItems) 
    foreach (var item2 in allItems) 
     ComputeSimilarity(item1, item2); 

//ComputeSimilarity(); returns a double, a.k.a. the similarity between items 

可以忽略功能的內部運作因爲它工作正常,我只是不知道改變代碼,所以它不會計算兩次。

我該如何改變這個函數來使計算矩陣看起來像這樣?

 I1 | I2 | I3 | I4 | I5 | 
I1 | | 0.5| 0.3| 0.2| 0.9| 
I2 | | | 0.2| 0.1| 0.8| 
I3 | | | | 0.5| 0.1| 
I4 | | | | | 0.7| 
I5 | | | | | | 

讓我知道如果我應該詳細說明更多!提前致謝!

+0

作爲第一個想法,怎麼樣'如果(ITEM1! = item2)ComputeSimilarity(item1,item2);' – Pikoh

+0

@MongZhu,我知道。這就是爲什麼我說「作爲第一個想法」 – Pikoh

回答

1

你可以計算前添加一個檢查

for (int i = 0; i < allItems.Count;i++) 
    for (int j = 0; j < allItems.Count; j++) 
     if(i<j) 
     ComputeSimilarity(allItems[i], allItems[j]); 
+0

這工作得很好,很簡單,謝謝! – RandomStranger

+0

太棒了,不客氣 – fubo

2

這應做到:

int n = allItems.Length; 

double[,] similarity = new double[n,n]; 

for (int i = 0; i < n; ++i) 
{ 
    for (int j = i + 1; j < n; ++j) 
    { 
     similarity[i, j] = computeSimilarity(allItems[i], allItems[j]); 
    } 
} 
+0

純粹以一種將它存儲在SQL數據庫中的方式,是否可以將這些項目放入列表中? – RandomStranger

+0

@Bas是的,而不是'相似性[i,j] = computeSimilarity(allItems [i],allItems [j]);'你會把'myList.Add(computeSimilarity(allItems [i],allItems [j]) );' –

0

試試這個

 double val; 
     for (int i = 0; i < allItems.Count; i++) 
     { 
      for (int j = i; j < allItems.Count; j++) 
      { 
       if (i!=j) 
        val = ComputeSimilarity(allItems[i], allItems[j]); 
      } 
     } 
+0

我認爲它應該是'if(i Pikoh

+0

@Pikoh,nope。運行它,它會在其「所需的」計算矩陣中準確返回i-j元素OP的顯示。 – user3598756

+0

你是對的。我錯過了'int j = i'part。對不起:) – Pikoh