2011-09-13 6 views
0

Je suis un nouvel utilisateur R et j'ai une sorte de problème d'algorithme. J'ai fait quelques recherches sur le web et sur Stackoverflow, mais je ne trouve pas ma réponse.Multiplier chaque rangée d'une matrice par la matrice

J'ai une matrice carrée, par exemple:

A B C D 
A 0 0 0 1 
B 0 1 1 0 
C 1 0 0 0 
D 0 1 1 1 

Cette matrice représente les liens entre les mots-clés (A, B, C et D ici). Un '1' (ou un VRAI) signifie que les mots-clés sont en relation. Par exemple, le '1' sur la première ligne signifie que A est lié à D.

Je dois trouver les deux mots-clés les plus liés sur la matrice. Je sais que j'ai besoin de calculer le produit scalaire entre chaque rangée et la matrice initiale. Ensuite, je prends la somme des rangées et obtiens le maximum. Mais, quel est le programme R qui a mis dans une nouvelle matrice le produit entre chaque rangée de ma matrice, et la matrice elle-même?

Merci!

Répondre

3

Je pensais avoir une réponse, mais il intelligent se révèle être plus lent ...

tmp1 <- function(a) { 
    n <- nrow(a) 
    aa <- apply(array(apply(a,1,"*",a), 
        rep(n,3)),3,rowSums) 
    apply(aa,2,which.max) 
} 

solution précédente:

tmp2 <- function(a) { 
    n <- nrow(a) 
    r <- numeric(n) 
    for(i in seq(n)) { 
    b <- rowSums(a[i,]*a) 
    r[i] <- which.max(b) 
    } 
    r 
} 

Test cette sur quelque chose assez grand:

n <- 50 
a <- matrix(0,nrow=n,ncol=n) 
a[sample(length(a),size=n^2/5,replace=TRUE)] <- 1 

all(tmp1(a)==tmp2(a)) ## TRUE 

library(rbenchmark) 
benchmark(tmp1(a),tmp2(a)) 
> benchmark(tmp1(a),tmp2(a)) 
    test replications elapsed relative user.self sys.self 
1 tmp1(a)   100 4.030 9.264368  2.052  1.96 
2 tmp2(a)   100 0.435 1.000000  0.232  0.20 

Vous allez pré faire encore mieux, si vous pouvez le faire en termes de matrices creuses.

+1

La réponse acceptée est celle qui dit que le mien est meilleur? Hahaha! – Benjamin

1

Comme ça?

a=matrix(c(0,0,0,1,0,1,1,0,1,0,0,0,0,1,1,1), ncol=4, byrow=T) 
for(i in 1:4){ 
b = rowSums(a[i,]*a) 
print(which(b==max(b))) 
} 
+0

Merci pour votre réponse! J'ai déjà écrit un code avec 2 boucles imbriquées et il a fallu plus de 15 minutes pour calculer une matrice 1000x1000. Votre code semble beaucoup plus rapide. Au lieu d'imprimer tout le matériel à chaque itération, est-il possible de le mettre dans une matrice? –

Questions connexes