2015-09-22 3 views
2

У меня есть сеть с краями и точками. FID показывает идентификационный номер каждого ребра, который создается Start_Point и End_Point. Например, край 3 находится между двумя точками 2 и 3 в сети.создание матрицы из набора данных

FID  Start_Point End_Point 
1  1   2 
2  1   4 
3  2   3 
4  2   4 

Я хочу, чтобы создать матрицу из этих точек 4 матрицы с размерностью. если есть ребро между 2 точками значения 1 остальным inf:

[inf, 1, inf, 1; 
1, inf, 1, 1; 
inf, 1, inf, inf; 
1, 1, inf, inf] 

Как я могу создать такую ​​матрицу в MATLAB?

+1

Просьба уточнить ваш вопрос. Сделайте свой вывод правильными для вас данными * 5 * -by- * 3 *. Объясните, почему точка в вашей матрице будет 'inf' и почему она будет' 1'. Какой формат (тип данных) - ваш вход? Пожалуйста, * ИЗМЕНИТЬ * ваш вопрос, чтобы добавить эти данные. – Dan

+0

Это все еще не ясно. Объясните размеры вашей выходной матрицы, как вы попали в '(inf 1 inf inf inf ... 1)'? Что означают круглые скобки? – Dan

+0

имеется 127 ребер (FID) между сетью точек. Если между двумя точками есть грань, это означает, что существует разгром! поэтому значение этого ребра будет равно 1, и если между двумя точками нет разрыва, то между ними нет ребра. поэтому значение ребра будет inf. –

ответ

3

Вы можете преобразовать его в разреженную матрицу, а затем использовать полную команду, чтобы получить матрицу смежности.

edges= [1 2; 
    3 4; 
    3 1 
    2 3]; 
n=size(edges,1); 
% create sparse matrix with given edges and their reverse direction 
A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]); 
% create adjacency matrix 
B=full(A); 
% set zeros to inf 
B(B==0)=inf; 

и это результат:

A = 

    (2,1)  1 
    (3,1)  1 
    (1,2)  1 
    (3,2)  1 
    (1,3)  1 
    (2,3)  1 
    (4,3)  1 
    (3,4)  1 

>> B 

B = 

    Inf  1  1 Inf 
    1 Inf  1 Inf 
    1  1 Inf  1 
    Inf Inf  1 Inf 

Edit: редкие команды создают разреженную матрицу адресации значений ее элементов. Один прототип этой команды выглядит следующим образом:

A=sparse(rows,cols,values); 

, например A=sparse([1;2],[1,3],[10,5]) является матрица, которая A(1,1)=10 и A(2,3)=5 и другие элементы равны нулю:

A=sparse([1;2],[1,3],[10,5]); 
>> full(A) 

ans = 

    10  0  0 
    0  0  5 

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

A = sparse([edges(:,1); edges(:,2)],[edges(:,2); edges(:,1)],[ones(n,1); ones(n,1)]); 

полной команды преобразовать разреженную матрицу плотных один.

+0

Спасибо за ваш ответ .. объясните, пожалуйста, о строке 'A = разреженный ([edge (:, 1); edge (:, 2)], [edge (:, 2); edge (:, 1)], [ones (n, 1); ones (n, 1)]); 'что есть' [ones (n, 1); (n, 1)])? –

+0

@Shokouh Dareshiri, я отредактировал ответ, и я объяснил это. –

+0

Merc .. Большое спасибо .. Было так полезно :-) –

2

Итак, вы в основном хотите создать матрицу смежности из списка смежности краев? Количество ваших ребер (т.е. вашего FID столбца) не имеет значения, поэтому я предполагаю, что ваш ввод данные формы

edges = [1 2 
     1 4 
     2 3 
     2 4] 

Теперь первый столбец ребер строки вашей матрицы смежности и второй является столбцы (или наоборот, это не имеет значения, так как ваша матрица симметрична)

Самым простым решением является использование линейного индекса, который вы получили бы через sub2ind функции:

adj = inf(size(edges,2)); 
idx = sub2ind(size(adj),edges(:,1), edges(:,2)) 
adj(idx) = 1; 

Я подозреваю, ваш edges матрица уже будет симметричным, но если это не так, то просто использовать

edges_sym = [edges; fliplr(edges)] 

вместо edges

+0

Спасибо за ваш ответ :-) –

1

Вы можете использовать accumarray:

edges1 = accumarray([startpoint endpoint]),1); 
edges2 = edges1.'; % transpose your matrix, to obtain both edges 
edges = edges1+edges2; 
edges(edges==0)=inf; 

accumarray собирает все точки с общими индексами, вставляет значение 1 по этим показателям. edges1 - это транспонирование edges2, поэтому транспонируйте, затем добавьте два вместе. Найдите все индексы, на которых находится матрица 0, затем заполните эти значения inf.

Альтернатива:

edges= [1 2; 
    3 4; 
    3 1 
    2 3]; 
matrix = accumarray([edges;fliplr(edges)],1,[],[],inf); 

fliplr переворачивает Ваша матрица слева направо, чтобы получить все нужные комбинации индексов. Затем используйте accumarray, чтобы установить 1 во всех точках, указанных edges, и положить inf в других местах.

Если вы уверены, что ваша матрица симметрична, не используйте fliplr, если вы уверены, что ваша матрица не является симметричным, используйте fliplr и если вы не уверены, что использование этого:

matrix = accumarray([edges;fliplr(edges)],1,[],@mean,inf); 

где @mean гарантирует, что в любом случае установить двойные записи на 1. Для взвешенных кромок делаем следующее, где weights представляет собой массив Nx1, содержащий вес и N - это количество ребер.

matrix = accumarray([edges;fliplr(edges)],weights,[],@mean,inf); 
+0

Спасибо за ваш ответ :-) –

+1

Нет проблем. Ответ Ali Mirzaei, вероятно, является самым быстрым из этих трех решений для вашей проблемы, хотя я бы хотел упомянуть о универсальности «аккумулирования» для использования других функций, кроме встроенной 'sum' функции' sparse', если вы когда-нибудь нуждаетесь в этом;). Это не намерение украсть принятие, которое принадлежит быстрому решению Али! – Adriaan

+0

если я хочу весить края вместо 1, то что мне делать? –

Смежные вопросы