2013-07-16 1 views
1

Je trouve que tout appel pour obtenir/définir l'attribut vertex en utilisant la bibliothèque igraph dans le callback provoque un segfault dans R . Par exemple, le rappel trivial d'un segment de code:R/igraph: tout appel pour obtenir/définir l'attribut vertex dans un callback profondeur-première-recherche provoque un segfault

dfsCallBack <- function(graph, data, extra) { 
    cat("in:", paste(collapse=", ", data), "\n") 
    distFromRoot <- data[2] 
    vertexID <- data[1] 
    set.vertex.attribute(graph, 0, name = 'color', value = 'blue') 
    FALSE  
    } 
    graph.dfs(g, 1, in.callback = dfsCallBack) 

Produit cette erreur:

graph.dfs(g, 1, in.callback = dfsCallBack) 
in: 0, 0 

*** caught segfault *** 
address 0x0, cause 'memory not mapped' 

Traceback: 
1: .Call("R_igraph_dfs", graph, root, neimode, unreachable, as.logical(order),  as.logical(order.out), as.logical(father), as.logical(dist),  in.callback, out.callback, extra, rho, PACKAGE = "igraph") 
2: graph.dfs(g, 1, in.callback = dfsCallBack) 

Possible actions: 
1: abort (with core dump, if enabled) 
2: normal R exit 
3: exit R without saving workspace 
4: exit R saving workspace 
Selection: 

Quel est le problème ici? En outre, igraph devrait probablement être plus robuste dans le traitement de ces erreurs, l'écrasement de R n'est pas idéal pour un langage de haut niveau comme R.

Répondre

1

Quelques points.

  1. Si vous dites set.vertex.attribute(graph, ...), est en fait pas changé, mais une nouvelle copie est retourné avec l'attribut mis à jour. Les objets R sont (presque toujours) immuables, vous ne pouvez pas les modifier, mais seulement créer de nouveaux objets basés sur eux.

  2. set.vertex.attribute(graph, 0, name = 'color', value = 'blue') est erroné, car les identifiants de sommet commencent à 1, donc le 0 est invalide. Cela devrait être signalé comme une erreur, et a déjà été corrigé dans notre arbre de développement.

  3. Ce n'est pas une erreur, c'est un bug. Les erreurs igraph ne plantent pas R, elles donnent simplement un message d'erreur. Parce que le code igraph et R s'exécutent dans le même thread, les bugs d'igraph peuvent provoquer un crash de R, et en plus d'éviter les bugs, nous ne pouvons pas faire grand-chose à ce sujet.

Je suggère d'utiliser les résultats de igraph.dfs pour définir les attributs de manière appropriée. Vous pouvez bien sûr utiliser le rappel pour enregistrer des informations ou pour terminer le DFS.

+0

source primaire! merci pour les pointeurs. J'ai réalisé après avoir regardé plus d'exemples que la plupart d'entre eux utilisent les itérateurs plutôt que les rappels. Question stupide: comment puis-je tirer des identifiants de sommet à partir de séquences de front? Par exemple, je veux extraire le sommet parent du deuxième sommet traversé dans le DFS: E (g) [à (graph.dfs (g, 1) $ order [2])] donne la séquence de front e [1] 1 -> 2. Comment puis-je obtenir l'index 1 de l'objet igraph.es? Je voudrais faire une version modifiée d'un attribut de v1 et l'assigner comme un attribut de v2, mais d'abord le programme doit savoir que le parent de v2 est v1. – daj

+0

Vous pouvez utiliser 'get.edge' pour interroger les sommets incidents d'une arête. Mais ne voulez-vous pas juste utiliser 'father = TRUE' dans' graph.dfs() '? Cela renvoie les pères de chaque sommet visité. Zéro signifie ici pas de père, c'est-à-dire le sommet de départ. –

+0

Il y a quelque chose d'étrange dans la sortie utilisant father = TRUE. Avec un arbre qui ressemble à: 1-> 2 1-> 3 2-> 4 2-> 5 3-> 6 3-> 7, les valeurs de la commande sont: 1 2 4 5 3 6 7, ce qui est correct. Cependant, les valeurs du père sont: 0 1 1 2 2 3 3. Peut-être que je ne comprends pas la production du père, mais comment le père de 4 peut-il être 1? Le bord en 4 est de 2. – daj

Questions connexes