Как работают итераторы V и E в igraph, использующие R? - PullRequest
5 голосов
/ 26 августа 2011

Я просмотрел источник для V и E, и я не совсем уверен, как они работают. Вот код для V:

> V
function (graph)
{
    if (!is.igraph(graph)) {
        stop("Not a graph object")
    }
    vc <- vcount(graph)
    if (vc == 0) {
        res <- numeric()
    }
    else {
        res <- 0:(vc - 1)
    }
    class(res) <- "igraph.vs"
    ne <- new.env()
    assign("graph", graph, envir = ne)
    attr(res, "env") <- ne
    res
}

Я не совсем уверен, с какой целью служат вызовы для назначения и атрибута. Создает ли назначение графа новую копию графа? Насколько это эффективно / неэффективно? То есть, сколько копий графа это генерирует, скажем, в коде вроде:

V(g)$someattr <- somevector

Спасибо за помощь.

1 Ответ

1 голос
/ 14 ноября 2011

При генерации последовательности вершин с V вызовы assign и attr сохраняют копию графа, который использовался для создания последовательности, вместе с самим объектом последовательности вершин.Таким образом, когда вы делаете что-то вроде V(g)$color = 'blue', последовательность вершин удобно оценивать в контексте этой копии g.Это ясно, если вы проверяете один из методов, доступных для класса igraph.vs.

> methods(class='igraph.vs')
[1] [.igraph.vs     [<-.igraph.vs   $.igraph.vs     $<-.igraph.vs   print.igraph.vs

> `$.igraph.vs`
function (x, name) 
{
    get.vertex.attribute(get("graph", attr(x, "env")), name, 
        x)
}
<environment: namespace:igraph>

Здесь ясно, что операция индексирования $ будет оценена в контексте графической среды, которая былаиспользуется для создания последовательности вершин.

Вы отметили, что это создает несколько копий графа (который, вероятно, собирает мусор, но все же хорошо знать).Это легко продемонстрировать, если вы измените атрибуты графа g после того, как вы уже создали последовательность вершин vs = V(g).Атрибут обновляется в g, но не в копии g, которая хранится в среде, прикрепленной к vs.

> g = graph(c(0:1), directed=F)
> g = set.vertex.attribute(g, 'color', value='blue')
> vs = V(g)
> vs$color
[1] "blue" "blue"
> g = set.vertex.attribute(g, 'color', value='red')
> V(g)$color
[1] "red" "red"
> vs$color
[1] "blue" "blue"
...