matlabadjacency-matrixclique-problem

reordering the symmetric adjacency matrix including +1 and -1 elements to get cliques


I have a symmetric adjacency matrix with zero value on its diagonal. now i am looking for reordering method to show community which divides the matrix in two cliques with +1 and -1 values respectively. it would be appreciated if someone could help me in this regards.

for instance: matrix(10,10)

  0     1    -1     1     1    -1     1     1    -1    -1
  1     0    -1     1     1    -1     1    -1    -1    -1
 -1    -1     0    -1    -1     1     1     1     1    -1
  1     1    -1     0     1    -1     1    -1    -1    -1
  1     1    -1     1     0    -1     1     1    -1    -1
 -1    -1     1    -1    -1     0    -1     1     1     1
  1     1     1     1     1    -1     0     1     1     1
  1    -1     1    -1     1     1     1     0    -1    -1
 -1    -1     1    -1    -1     1     1    -1     0     1
 -1    -1    -1    -1    -1     1     1    -1     1     0

output must be :

  1     1     1     1     1    -1    -1    -1    -1    -1
  1     1     1     1     1    -1    -1    -1    -1    -1
  1     1     1     1     1     1    -1    -1    -1    -1
  1     1     1     1     1    -1    -1    -1    -1    -1
  1     1     1     1     1    -1    -1    -1    -1    -1
 -1    -1    -1    -1    -1     1     1     1     1     1
 -1    -1    -1    -1    -1     1     1     1     1     1
 -1    -1    -1    -1    -1     1     1     1     1     1
 -1    -1    -1    -1    -1     1     1     1     1     1
 -1    -1    -1    -1    -1     1     1     1     1     1

zero entries can be considered as 1


Solution

  • Because of the example, I'm not certain how to deal with most cases, so I guessed.

    a = round(3*rand(10) - 1.5);
    a(logical(eye(size(a)))) = 0;
    b = cliques(a);
    

    This maintains the symmetry requirement and only needs to break from the "wings" of -1's when there is one remaining after all the other filters (i.e. if the number of -1's is odd then to maintain symmetry an element must go on the diagonal).

    function b = cliques(a)
        a(a == 0) = 1;
        n = sum(a(:) == -1);
    
        s = floor(sqrt(n/2));
    
        b = ones(size(a));
        b(end - s + 1:end, 1:s) = -1;
        b(1:s, end - s + 1:end) = -1;
    
        n = n - 2*s^2;
    
        bands = floor(n/4);
        b(s+1, end - bands + 1:end) = -1;
        b(end - bands + 1:end, s+1) = -1;
    
        b(end - s, 1:bands) = -1;
        b(1:bands, end - s) = -1;
    
        n = n - 4*bands;
    
        dots = floor(n/2);
        if dots
            b(end - s, s + 1) = -1;
            b(s + 1, end - s) = -1;
        end
    
        n = n - 2*dots;
    
        if n
            b(1,1) = -1;
        end
    
        contourf(b, 'LevelList', [-1,1]);
        set(gca,'Ydir','reverse')
    
        sum(a(:)) == sum(b(:))
    end