2011-12-28 52 views
0

我有一个从http://www.albertauyeung.com/mf.php的Python代码,但我不知道任何有关Python编程来改进和更改此代码。不管怎么样,我开始用C++重新编写它,但是我的结果是如此不同。 的Python代码:Python与C++。不同的结果

import numpy 

def matrix_factorisation(R, P, Q, K, steps=5000, alpha=0.0002, beta=0.02): 
Q = Q.T 
for step in xrange(steps): 
    for i in xrange(len(R)): 
     for j in xrange(len(R[i])): 
      if R[i][j] > 0: 
       eij = R[i][j] - numpy.dot(P[i,:],Q[:,j]) 
       for k in xrange(K): 
        P[i][k] = P[i][k] + alpha * (2 * eij * Q[k][j] - beta * P[i][k]) 
        Q[k][j] = Q[k][j] + alpha * (2 * eij * P[i][k] - beta * Q[k][j]) 
    eR = numpy.dot(P,Q) 
    e = 0 
    for i in xrange(len(R)): 
     for j in xrange(len(R[i])): 
      if R[i][j] > 0: 
       e = e + pow(R[i][j] - numpy.dot(P[i,:],Q[:,j]), 2) 
       for k in xrange(K): 
        e = e + (beta/2) * (pow(P[i][k],2) + pow(Q[k][j],2)) 
    if e < 0.001: 
     break 
return P, Q.T 

if __name__ == "__main__": 
R = [ 
[5,3,0,1], 
[4,0,0,1], 
[1,1,0,5], 
[1,0,0,4], 
[0,1,5,4], 
] 

R = numpy.array(R) 

N = len(R) 
M = len(R[0]) 
K = 2 

P = numpy.random.rand(N,K) 
Q = numpy.random.rand(M,K) 

nP, nQ = matrix_factorisation(R, P, Q, K) 
nR = numpy.dot(nP, nQ.T) 

====================================== =========================================== 和C++代码:

int main(int argc, char *argv[]) 
{ 
QCoreApplication a(argc, argv); 

//=============preliminary================= 
long double R[5][4]={5,3,0,1, 
       4,0,0,1, 
       1,1,0,5, 
       1,0,0,4, 
       0,1,5,4},newR[5][4]={0}; 
int n=5, m=4,k=2; 
long double Q[2][4],P[5][2]; 

for (int i=0;i<k;i++){ 
    for (int j=0;j<n;j++){ 
     P[j][i]=random2(0,1); 
    } 
    for(int l=0;l<m;l++){ 
     Q[i][l]=random2(0,1); 
    } 
} 



// ============= MatrixFactorization(R,P,Q,k)======================= 
long double eij=0,sigmaPQ=0; 
long double e; 
long double alpha=0.0002, beta=0.02; 
int t; 
for(long step=0;step <5000;step++){ 
    t=step; 
    for (int i=0;i<n;i++){ 
     for(int j=0;j<m;j++){ 
      if(R[i][j]>0){ 
       sigmaPQ=0; 
       for (int z=0;z<k;z++){ 
        sigmaPQ += P[i][z]*Q[z][j]; 
       } 
       eij=R[i][j]-sigmaPQ; 

       for (int z=0;z<k;z++){ 
        P[i][z] += alpha*(2*eij*Q[z][j]-beta*P[i][z]); 
        Q[z][j] += alpha*(2*eij*P[i][z]-beta*Q[z][j]); 
       } 
      } 
     } 
    } 
    e=0; 
    for (int i=0;i<n;i++){ 
     for(int j=0;j<m;j++){ 
      if(R[i][j]>0){ 
       sigmaPQ=0; 
       for (int z=0;z<k;z++){ 
        sigmaPQ += P[i][z]*Q[z][j]; 
       }     
       for (int z=0;z<k;z++){ 
        e+=(beta/2)*(qPow(P[i][z],2)+qPow(Q[z][j],2));       
       } 
       e=qSqrt(e); 
      }     
     } 
    }  
    if(e<0.001) 
     break; 

}  
//=========== calculate approximate R ============= 
long double temp; 
for (int i=0;i<n;i++){ 
    for(int j=0;j<m;j++){ 
     temp=0; 
     for(int z=0;z<k;z++){ 
      temp+=P[i][z]*Q[z][j]; 
     } 
     newR[i][j]=temp; 
    } 
} 
} 

Python代码是正确答案。 我该怎么做,修复这个C++代码?

+2

首先你确定在C++中的numpy.random和random2会返回相同的结果吗?我不这么认为...... – 2011-12-28 11:27:19

+0

Tnx,random2是我写的一个函数。问题不是随机数。如果我们用一个常量值初始化P和Q,Python将再次正常工作。 – dare 2011-12-28 12:47:31

+4

投票结束:通过使用调试器可以解决(或至少确定)此问题。 – 2011-12-28 13:29:09

回答

0

将其分解成步骤并检查每个步骤的输出。 print和printf是你的朋友。 :) 或者学习足够的Python来创建一个可以转换为C++的伪代码版本。

通常情况下,当调试大代码段时,我只监视进程中每个逻辑步骤的数据。通过在关键位置插入打印语句,Python变得很容易。

相关问题