2015-05-29 21 views
6

Bitişik matrisinin bağlı bileşenlerini bir araya getirmek için bir yeniden sıralama tekniği arıyorum. Örneğin, mavi ve yeşil olmak üzere iki grupla bir örnek oluşturdum. Başlangıçta '1'in girdileri matrisin satır ve sütunlarına dağıtılır. Satırları ve sütunları yeniden sıralayarak, tüm '1''ler matrisin iki bitişik bölümünde yer alabilir ve mavi ve yeşil bileşenleri daha açık bir şekilde ortaya koyar.Kesişmeleri açığa çıkarmak için bitişik matrisin satır ve sütunlarını sıralama

Illustration

bu yeniden sıralama tekniği ne denir hatırlayamıyorum. Bitişik matris, klik, sıralama ve yeniden sıralama gibi birçok kombinasyon için aradım.

buldum yakın hit

  1. symrcm yakın köşegen elemanları taşır, ancak gruplar yapmaz bulunmaktadır. tamamen boş satırlar ve sütunlar

kaldırarak odaklanır

  • Is there a way to reorder the rows and columns of matrix to create a dense corner, in R? Ben daha etkili google ya da bir Matlab fonksiyonunun yönde bana gelin, böylece bu tekniğin genel adı verin ya.

  • cevap

    2

    Size doğrudan sonuç vermesi gereken daha iyi bir alternatif olup olmadığını bilmiyorum, ancak burada amacınıza hizmet edebilecek bir yaklaşım var.

    Kişisel giriş:

    >> A 
    
    A = 
    
    0  1  1  0  1 
    1  0  0  1  0 
    0  1  1  0  1 
    1  0  0  1  0 
    0  1  1  0  1 
    

    Yöntem 1

    Kolon Maske (maskCol) sırasıyla Sıra Maske (maskRow) birinci satırı ve ilk sütunu almak.

    olan değer maskesi al hem birinci satırda olanlar ve birinci sütun

    maskRow = A(:,1)==1; 
    maskCol = A(1,:)~=1; 
    

    satırları yeniden düzenleme (Sıra maskeye göre)

    out = [A(maskRow,:);A(~maskRow,:)]; 
    
    içerir

    Böyle bir şey verir:

    out = 
    
    1  1  0  0  0 
    1  1  0  0  0 
    0  0  1  1  1 
    0  0  1  1  1 
    0  0  1  1  1 
    

    sadece bir kontrol endeksleri olup: (kolon-maske göre)

    out = 
    
    1  0  0  1  0 
    1  0  0  1  0 
    0  1  1  0  1 
    0  1  1  0  1 
    0  1  1  0  1 
    

    yeniden düzenlenmesi sütun

    out = [out(:,maskCol),out(:,~maskCol)] 
    

    istenen sonuçları verir onlar olması gerekiyor ya da karşılık gelen yeniden düzenlenmiş endeksleri istiyorsanız;)

    Yeniden düzenlenmesi önce:

    idx = reshape(1:25,5,[]) 
    
    idx = 
    
    1  6 11 16 21 
    2  7 12 17 22 
    3  8 13 18 23 
    4  9 14 19 24 
    5 10 15 20 25 
    

    önce yaptığımız (aynı işlemi) yeniden düzenlenmesi sonra

    outidx = [idx(maskRow,:);idx(~maskRow,:)]; 
    outidx = [outidx(:,maskCol),outidx(:,~maskCol)] 
    

    Çıktı:

    outidx = 
    
    2 17  7 12 22 
    4 19  9 14 24 
    1 16  6 11 21 
    3 18  8 13 23 
    5 20 10 15 25 
    

    : önceden matris bilmiyorsanız

    Yöntem 2

    Jenerik durumda için, burada kullanılan maskRow ve maskCol

    Mantık bulmak için prosedürdür

    1. İlk sırayı al. Sütun maskesi olarak düşünün (maskCol).

    2. 2. sıradan sonuncu satır için, aşağıdaki işlem tekrarlanır.

    3. Geçerli satırı maskCol ile karşılaştırın. herhangi bir değer maskCol ile eşleşirse

    4. ardından elemanı bilge mantıksal OR bulmak ve yeni maskCol

    5. Tekrarla olarak son satırın kadar bu süreci güncelleyin.

    6. Sütun yineleme yerine kullanılırken, maskRow bulmak için aynı işlem yerine.

    Kodu: Burada

    %// If you have a square matrix, you can combine both these loops into a single loop. 
    maskCol = A(1,:); 
    for ii = 2:size(A,1) 
        if sum(A(ii,:) & maskCol)>0 
         maskCol = maskCol | A(ii,:); 
        end 
    end 
    
    maskCol = ~maskCol; 
    
    maskRow = A(:,1); 
    for ii = 2:size(A,2) 
        if sum(A(:,ii) & maskRow)>0 
         maskRow = maskRow | A(:,ii); 
        end 
    end 
    

    denemek için bir örnek: Takip prosedürü tekrarlayın Sonra

    %// Here I removed some 'ones' from first, last rows and columns. 
    %// Compare it with the original example. 
    A = [0  0  1  0  1 
        0  0  0  1  0 
        0  1  1  0  0 
        1  0  0  1  0 
        0  1  0  0  1]; 
    

    önce:

    out = [A(maskRow,:);A(~maskRow,:)];  %// same code used 
    out = [out(:,maskCol),out(:,~maskCol)]; %// same code used 
    
    0 İşte

    sonucudur:

    >> out 
    
    out = 
    
    0  1  0  0  0 
    1  1  0  0  0 
    0  0  0  1  1 
    0  0  1  1  0 
    0  0  1  0  1 
    

    Not: Bu yaklaşım vakaların çoğu için çalışabilir ancak yine de bazı nadir durumlarda başarısız olabilir.

    %// this works well. 
    A = [0  0  1  0  1 0 
        1  0  0  1  0 0 
        0  1  0  0  0 1 
        1  0  0  1  0 0 
        0  0  1  0  1 0 
        0  1  0  0  1 1]; 
    
    %// This may not 
    %// Second col, last row changed to zero from one 
    A = [0  0  1  0  1 0 
        1  0  0  1  0 0 
        0  1  0  0  0 1 
        1  0  0  1  0 0 
        0  0  1  0  1 0 
        0  0  0  0  1 1]; 
    

    Neden başarısız oluyor: İşte

    , bir örnektir?

    biz 3 satıra taşıdığınızda her satır ile döngü (sütun maskesi bulmak için), eg, cols hiçbiri (maskCol akım) ilk satırı eşleşecek gibi. Böylece 3. sıra (2. element) tarafından taşınan tek bilgi kaybolur.

    Nadiren bu durum olabilir, çünkü diğer satırlar hala aynı bilgileri içerebilir. İlk örneğe bakın. Ayrıca üçüncü sıradaki elemanların hiçbiri 1. sıra ile eşleşmez, ancak son sırada aynı bilgi (2. elementte 1) olduğu için doğru sonuçlar vermiştir. Sadece nadir durumlarda, buna benzer olabilir. Yine de bu dezavantajı bilmek güzel.

    Yöntem 3

    Bu, bir kaba kuvvet alternatiftir. Bir önceki davanın başarısız olabileceğini düşünüyorsanız uygulanabilir. Burada, maskCol numaralı güncellemeyle bir önceki kodu (satır ve sütun maskesi bulma sayısını) çalıştırmak için while loop kullanıyoruz, böylece doğru maskeyi buluyoruz.

    Prosedür:

    Önceki örnek, (önceki yöntemi başarısız olduğu) alınır ve kaba kuvvet olmadan ve while-loop

    olmadan çalıştırılır

    maskCol = A(1,:); 
    count = 1; 
    while(count<3) 
        for ii = 2:size(A,1) 
         if sum(A(ii,:) & maskCol)>0 
          maskCol = maskCol | A(ii,:); 
         end 
        end 
        count = count+1; 
    end 
    
    :

    >> out 
    
    out = 
    
    1  0  1  0  0  0 
    1  0  1  0  0  0 
    0  0  0  1  1  0 
    0  1  0  0  0  1 
    0  0  0  1  1  0 
    0  0  0  0  1  1 
    

    döngü sırasında Kaba Kuvvet ile:

    >> out 
    
    out = 
    
    1  1  0  0  0  0 
    1  1  0  0  0  0 
    0  0  0  1  1  0 
    0  0  1  0  0  1 
    0  0  0  1  1  0 
    0  0  0  0  1  1 
    

    doğru sonuçlar farklı olabilir elde etmek için gerekli olan yineleme sayısı. Ama iyi bir numaraya sahip olmak güvenlidir.

    İyi Şanslar!

    +0

    Bu, verdiğim örnek için çalışıyor, ancak daha genel bir örnek için çalışıyor mu? Örneğinizde, ilk satırda veya sütunda bulunan satırları ve sütunları ararsınız. İstenilen matrisin yapısını önceden bilmediysem, bu nasıl çalışırdı? – Cecilia

    +0

    @Cecilia genel durum için güncellendi .. belirli bir desen için hemen hemen tüm durumlarda çalışmalıdır (yeşil olanlar tarafından işgal edilen satırlar ve cols mavi olanlar tarafından işgal edilmemelidir). Bunun işe yaramadığı özel bir örneğiniz varsa, soruyu söz konusu örnekle güncelleyin ve bana bildirin. :) –