2016-11-09 52 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