Пример работы с Rocs

В этом разделе будет представлен пример проекта для изучения некоторых наиболее важных функций Rocs. Цель состоит в том, чтобы создать граф и сценарий, иллюстрирующий простой алгоритм для задачи минимального вершинного покрытия. Задача минимального вершинного покрытия — это задача поиска подмножества вершин графа С минимального размера, такого, чтобы каждое ребро графа было соединено по крайней мере с одной вершиной в С. Эта задача является NP-сложной, и пример ниже иллюстрирует, как найти приближение фактора 2, вычисляя соответствие на заданном графе.

Цель — визуализировать взаимосвязь соответствия и минимального покрытия вершин. Для этого следует указать два типа рёбер, один для отображения совпадающих рёбер, а другой — для отображения «обычных». Также следует указать два типа вершин, которые будут использоваться для обозначения вершин, содержащихся и не содержащихся в C.

Построение графа

Для создания графа используется построитель графов, предоставляемый Rocs. Он находится в главном меню ГрафИнструментыПостроитель графов. В открывшемся диалоге выберите вариант Случайный граф и укажите количество вершин: 30, количество рёбер: 90 и семя: 1 (семя является начальным значением для генератора случайных графов; многократное использование одного и того же начального значения приводит к одинаковым и воспроизводимым графам).

Создание типов элементов

Далее потребуется создать второй тип вершин и второй тип рёбер с помощью панели Типы элементов. Для обоих типов следует открыть диалог со свойствами с помощью соответствующих кнопок Свойства и установить значение идентификатора 2. После этого поменяйте цвета элементов этих двух новых типов (чтобы отличать их от типов по умолчанию). Затем установите все типы рёбер двунаправленными, а идентификаторы типов по умолчанию должны иметь значение 1.

Алгоритм

После всех проделанных действий требуется запустить алгоритм. Для этого будет использоваться следующий код:

for (var i=0; i < Document.nodes.length; i++) {
    Document.nodes[i].type = 1;
}
for (var i=0; i < Document.edges.length; i++) {
    Document.edges[i].type = 1;
}

var E = Document.edges(); // набор необработанных рёбер
var C = new Array();      // совпадающие рёбра
while (E.length 
> 0) {
    var e = E[0];         // первое ребро e={u,v}
    var u = e.from();
    var v = e.to();
    e.type = 2;           // указать ребру свойство «совпадающее»
    E.shift();            // убрать e (то есть, E[0]) из списка рёбер
    C.push(u);            // добавить u к C
    C.push(v);            // добавить v к C

    // отметить u,v как вершины в C
    u.type = 2;
    v.type = 2;

    // убрать из E все рёбра, присоединённые к u или v
    var adjacent = u.edges();
    for (var i=0; i < adjacent.length; i++) {
        var index = E.indexOf(adjacent[i]); // найти индекс
        if (index != -1) {
            E.splice(index, 1); // убрать индекс, если найден
        }
    }
    var adjacent = v.edges();
    for (var i=0; i < adjacent.length; i++) {
        var index = E.indexOf(adjacent[i]); // найти индекс
        if (index != -1) {
            E.splice(index, 1); // убрать индекс, если найден
        }
    }
}
Console.log("Вершинное покрытие содержит вершин: " + C.length + ".");

Запуск алгоритма

Чтобы запустить алгоритм, нажмите кнопку Запустить на панели управления сценарием.