Как работают итераторы V и E в igraph с использованием R?

Я просмотрел источник для 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

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


person starflyer    schedule 25.08.2011    source источник
comment
Я не использовал igraph, поэтому не могу ответить на ваш общий вопрос, но обычно в R, когда вы видите явно лишние среды, которые создаются и назначаются, цель состоит в том, чтобы предотвратить создание копии. Я предполагаю, что это то, к чему давайте V(g) вернемся и изменим g (stackoverflow.com/questions/3693121/)   -  person Owen    schedule 26.08.2011
comment
Да, я думаю, ты прав. Это позволяет вам изменять g.   -  person starflyer    schedule 26.08.2011
comment
@starflyer: ты нашел четкий ответ? Если да, то не могли бы вы опубликовать его? Вы меня заинтересовали...   -  person Ryogi    schedule 13.10.2011


Ответы (1)


При создании последовательности вершин с помощью 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"
person John Colby    schedule 13.11.2011