根据matlab中数组中行之间存在的公共值排列行

时间:2016-12-30 18:09:04

标签: arrays matlab scripting

我有一个包含3列的800行数组。我想以这样的方式安排它:第一行之后的行包含至少2个公共值作为第一行和下一行之后的那一行还包含至少2个公共值作为第二行。 例; row 1 = 2 4 5公共行= row 30 = 2 5 13 所以第一次安排;

 2  4  5
 2  5 13 

下一行将是新行2的共同行 示例row 4= 13 45 5 因此现在安排;

2   4   5
2   5   13
13  45  5    

    etc

目前,我有这个代码将这些共同组合在一起,然后一个接一个地显示它们。这个问题是该数组包含多个通用性。例如,第1行可能有2行具有公共值,此代码将所有这些行合并为一个数组,并对第二行执行相同操作..我怎样才能使代码完成我在第一段中解释的代码;

这是代码;

% Data
A = connections;
% Engine
[m, n] = size(A);
groups =[];

ng = 0;
for k=1:m-1
    u = unique(A(k,:)); % representation of kth row
    [in, J] = ismember(A(k:end,:),u);
    l = m-k+1;
    r = repmat((1:l).', n, 1);
    c = accumarray([r(in) J(in)],1,[l n]); % count
    c = bsxfun(@min,c,c(1,:)); % clip
    rows = sum(c,2)>=2; % check if at least 2 elements are common
    rows(1) = false;
    if any(rows)
        ng = ng+1;
        rows(1) = true;
        groups = (k-1) + find(rows);

    end
end

请注意,只有当groups是一个单元格数组时,才能添加下面代码的其余部分,bt它已被更改为如上所述的普通数组..所以为了测试代码,有无需添加以下代码。

% Remove the tail
groups(ng+1:end) = [];
% Display
for k=1:1:length(groups)
    gk = groups{k};
    for r = gk'
     fprintf('%d %d %d %d\n', r, A(r,:));        

    end
end

1 个答案:

答案 0 :(得分:0)

这是Hamiltonian path problemHamiltonian path可追踪路径是一个只访问每个顶点一次的路径。这里有800个顶点(行),每个顶点都有一个或多个邻居。邻域的条件是具有与其他顶点共同的2个或更多个值的顶点。 解决问题你应该创建一个与图结构相对应的邻接矩阵,然后在图上找到哈密顿路径。

这是一种创建邻接矩阵的方法:

[ m n] = size(A);
%generate all 2 element subsets of the set [1 2 3 ] to check if a row
% has two elemnts common with other row
x = nchoosek(1:n,2);
%generate indices for generating two element rows
col = repmat(x,m,1);
M = (1:m).';
row = kron(M,ones(size(x)));
IDX = sub2ind([m n] ,row, col);
%convert A with [m , 3] to a [(m * 3), 2)]matrix 
% then sort each row to be comparable with other rows
B=sort(A(IDX),2);
%indices of rows that have two common elements is found
[~,I,II] = unique(B,'rows', 'first');
convert index of the [(m * 3), 2)]matrix to [m , 3] matrix
I = uint32(I-1) / n + 1;
%create adjacency matrix
adjacency= sparse(I(II(:)), M(II(:)),1,m,m);
%make the matrix symmetric
adjacency = adjacency | adjacency.';
% a vertex can not be neighbor of itself
adjacency(speye(m))=false;

您应该实现自己的汉密尔顿路径算法版本或在网络中查找 然而,哈密顿路径问题可以通过向图中添加一个顶点并使所有其他顶点与它相邻来转换为travelling salesman problem的特殊形式。

因此应对邻接矩阵应用一些更改:

adjacency = [adjacency; ones(1,m)];
adjacency = [adjacency, ones(n+1,1)];
adjacency (end) = 0;

Mathworks中,您可以找到一个示例,说明如何使用binary integer programming来解决旅行商问题。然而,所提供的方法似乎并不简单。所以你可能找到了另一个或实现自己的。