SORU
20 Ocak 2009, Salı


Yerinde Taban Sıralama

Bu uzun bir metin. Benimle ayı lütfen. Aşağı haşlanmış, soru şu:Yok yerinde taban sıralama algoritması uygulanabilir?


Ön

Çok sayıda varküçük sabit uzunluktasadece harfleri kullanan dizeleri“”, “C”, “G” ve “” sıralamak istiyorum (Evet, Bunu tahmin ettik: DNA). T

Şu anda STL tüm ortak uygulamaları introsort kullanan std::sort kullanıyorum. Bu oldukça iyi çalışıyor. Ancak, radix sort benim sorunum mükemmel ayarlanmış ve çalışmalıdır uygun olduğuna ikna oldumçokpratik yaptıkça daha iyi.

Ayrıntılar

Çok naif bir uygulama ile bu varsayımı test ettim ve nispeten küçük giriş (10.000 sipariş üzerine) bu gerçek (en azından iki kat daha hızlı). Sorunun boyutu daha büyük olduğunda ancak, abysmally ( . zamanı düşürür ^em>N

Nedeni belli: taban sıralama gerektirir tüm verileri (saf benim uygulama içinde birden fazla aslında) kopyalama. Bu tabii ki performans öldüren benim ana belleğe ~ 4 GiB koydum anlamına gelir. Eğer sorun bu yana bu kadar bellek kullanımı Gücüm yetmez mi, gelmedi bile boyutları aslında çok daha büyük olur.

Durumlarda Kullanın

İdeal olarak, bu algoritma gerekir işi ile herhangi bir dize uzunluğu 2 ila 100, DNA gibi DNA5 (izin veren ek bir joker karakter “N”), hatta DNA ile IUPAC ambiguity codes (çıkan 16 farklı değerler). Ancak, bütün bu durumlarda karşılanamayacak farkındayım, ben herhangi bir hız ile gelişme mutlu oldum. Kodu göndermek için algoritma dinamik olarak karar verebilir.

Araştırma

Ne yazık ki, Wikipedia article on radix sort bir işe yaramaz. -Değişken bir bölümüne tam bir saçmalık. NIST-DADS section on radix sort sonraki yok. Umut verici görünen bir kağıt Efficient Adaptive In-Place Radix Sorting adında bir kız vardı algoritma“”. MSI Ne yazık ki, bu kağıt da hayal kırıklığı yaratıyor.

Özellikle şu şey var.

İlk olarak, algoritma birkaç hata içerir ve bir sürü açıklanamayan bırakır. Özellikle, özyineleme çağrısı ayrıntı değil (ben sadece mevcut veya shift ve maske değerlerini hesaplamak için bazı işaretçi artırır azaltır varsayalım). Ayrıca, tanımlar vermeden işlevleri dest_group dest_address kullanır. Bu verimli (O, O(1); En az dest_address önemsiz değil) nasıl görmek için başarısız.

Son ama en az değil, algoritma giriş dizisi içindeki elemanları ile bir dizi dizinleri takas-yer-lik edilmektedir. Bu tabii ki sadece nümerik diziler üzerinde çalışır. Dizeleri kullanmak istiyorum. Tabii ki, sadece güçlü yazarak vida ve bellek benim muhabbette bu dizin depolama tahammül varsayarak devam edebilirim. Ama bu sadece belleğin 32 bit (32 bit tamsayı varsayarak) içine iplerimi sıkabilirim olarak çalışır. O sadece 16 karakter (hadi 16 >o an için görmezden geliyor günlük(5,000,000)).

Yazarlar biri tarafından başka bir kağıt hiç doğru bir açıklama verir, ama düz olan alt-lineer yanlış olarak kırsal alanlarda çalışan çalışma zamanı verir.

Özetlemek gerekirseÇalışan bir referans uygulama veya en azından DNA dizeleri çalışır-taban tür bir çalışma iyi bir yalancı/bir açıklama bulma herhangi bir umut var mı?

CEVAP
20 Ocak 2009, Salı


Burada DNA MSD sayı tabanı bir nevi basit bir uygulama. Bu en çok kullandığım ve bu nedenle aptalca hatalar yapma ihtimali en az olan Ben bu dili çünkü D yazılmış, ancak kolayca başka bir dile çevrilmiş olabilir. Yerinde ama 2 * seq gerektirir.uzunluğu dizi geçer.

void radixSort(string[] seqs, size_t base = 0) {
    if(seqs.length == 0)
        return;

    size_t TPos = seqs.length, APos = 0;
    size_t i = 0;
    while(i < TPos) {
        if(seqs[i][base] == 'A') {
             swap(seqs[i], seqs[APos  ]);
             i  ;
        }
        else if(seqs[i][base] == 'T') {
            swap(seqs[i], seqs[--TPos]);
        } else i  ;
    }

    i = APos;
    size_t CPos = APos;
    while(i < TPos) {
        if(seqs[i][base] == 'C') {
            swap(seqs[i], seqs[CPos  ]);
        }
        i  ;
    }
    if(base < seqs[0].length - 1) {
        radixSort(seqs[0..APos], base   1);
        radixSort(seqs[APos..CPos], base   1);
        radixSort(seqs[CPos..TPos], base   1);
        radixSort(seqs[TPos..seqs.length], base   1);
   }
}

Belli ki, bu tür genel olarak DNA, özgüdür, ama hızlı olmalı.

Edit: bu kod gerçekten çalışıp çalışmadığını merak ettim,/kendi biyoenformatik benim kod çalıştırmak için beklerken o debug test ettim. Şimdi yukarıdaki sürüm aslında test edilmiş ve çalışır. 5 üslerinin 10 milyon dizileri için her yaklaşık 3 kat daha optimize edilmiş bir introsort.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • chrmoe

    chrmoe

    7 Kasım 2006
  • The Slow Mo Guys

    The Slow Mo

    15 AĞUSTOS 2010
  • Troy Hunt

    Troy Hunt

    29 EYLÜL 2011