Как я могу оптимизировать создание этой матрицы смежности? - PullRequest
0 голосов
/ 09 октября 2018

Я хочу создать матрицу смежности в MATLAB для имитации сети дорог в общем городе с шахматной разметкой, в частности, тогда каждый узел может быть связан только с его основными соседями (максимум 8 ссылок на узел).Я написал этот код, который выдает желаемый результат:

rng('shuffle');

NRoads = 25;
CitySize = sqrt(NRoads);

PCross = 0.8;
Adj = zeros(NRoads);

for i = 1:NRoads
    for j = i+1:NRoads

        x = rand;
        if ismember(j, [i+1, i+CitySize, i+CitySize+1]) && x < PCross

            Adj(i, j) = 1;

        end;

    end;
end;

Adj = Adj | Adj';

Но мне интересно, есть ли оптимизированный способ сделать это (например, без двойного цикла for или специальной функции).

Ответы [ 2 ]

0 голосов
/ 15 августа 2019

Даже без умного наблюдения , которое gnovice сделал , код легко упростить.

Внутренний цикл:

    for j = i+1:NRoads
        x = rand;
        if ismember(j, [i+1, i+CitySize, i+CitySize+1]) && x < PCross
            Adj(i, j) = 1;
        end
    end

Зацикливается на всех j затем видит, является ли j одним из 3 заданных значений.Почему бы просто не зациклить только эти три значения?

    for j = [i+1, i+CitySize, i+CitySize+1]
        x = rand;
        if j <= NRoads && x < PCross
            Adj(i, j) = 1;
        end
    end

Это, конечно, больше не нуждается в цикле:

    j = [i+1, i+CitySize, i+CitySize+1];
    x = rand(1,3);
    j = j(j <= NRoads & x < PCross); % note elementwise &, not &&
    Adj(i, j) = 1;
0 голосов
/ 09 октября 2018

По сути, ваш код случайным образом заполняет первую, пятую и шестую недиагональные единицы (с заданной скоростью PCross), а затем добавляет эту матрицу для транспонирования самой себя.Поэтому ваши циклы можно заменить тремя вызовами на diag:

Adj = (diag(rand(1, NRoads-1), 1) + ...
       diag(rand(1, NRoads-5), 5) + ...
       diag(rand(1, NRoads-6), 6)) > (1-PCross);
Adj = Adj | Adj.';
...