Sayı tabanlı sistemlere dayalı algoritmalar? [kapalı]


88

Son zamanlarda fark ettim ki, kısmen veya tamamen sayıların yaratıcı temellerde akıllıca kullanımına dayanan birçok algoritma var. Örneğin:

  • Binom yığınları ikili sayılara dayanır ve daha karmaşık çarpık ikili yığınlar, çarpık ikili sayılara dayanır.
  • Sözlüksel olarak sıralı permütasyonlar oluşturmak için bazı algoritmalar faktöradik sayı sistemine dayanmaktadır.
  • Denemeler, uygun bir taban için her seferinde dizenin bir basamağına bakan ağaçlar olarak düşünülebilir.
  • Huffman kodlama ağaçları, ağaçtaki her kenarın bazı ikili gösterimlerde bir sıfırı veya birini kodlamasına sahip olacak şekilde tasarlanmıştır.
  • Fibonacci kodlaması, Fibonacci aramasında ve belirli tipteki logaritmaları tersine çevirmek için kullanılır.

Sorum şu: Akıllı bir sayı sistemini sezgilerinin veya kanıtlarının önemli bir adımı olarak kullanan başka hangi algoritmalar var? . Konuyla ilgili bir konuşma yapmayı düşünüyorum, bu yüzden ne kadar çok örnek almam gerekiyorsa o kadar iyi.


5
Ben de soruyu beğendim ama 'doğru' cevabı nasıl seçersiniz? Bu topluluk wiki olmalı mı?
vlad

14
Bu topluluk wiki olmalı
BlueRaja - Danny Pflughoeft

18
@close voter: SO'da algoritmalarla ilgili bir soru konu dışı ise, burada neyin konu olduğunu bilmiyorum. CSS hakkında aptal acemi soruları? "regex plzz hazırlayabilir miyim"? "e-posta kodu 4 mi hoemwok"?
MAK

2
Otostopçunun Galaksi Rehberi: Yaşama, Evrene ve Her Şeye Cevap Nedir? Derin Düşüncenin cevabı: 42. Şu soruyu bulmak için makine olarak Dünya: 9 x 6 nedir? ve bu yüzden her şey bu kadar berbat. Bir tişört üzerinde görülüyor: 9 (taban 13) x 6 (taban 13) = 42 (taban 13). QED.
Chris Walton

"Sezgilerinin veya kanıtlarının anahtar adımı olarak akıllı bir sayı sistemini kullanan başka hangi algoritmalar var?" Stack Overflow bir Öneri Motoru , her şeyin listesi veya bir bağlantı grubu değildir . Kesinlikle, pratik programlama sorularını çözmek için algoritmalar. Akıllı algoritmalar için takas odaları, hayır. Eğer isterlerse Mathematics'in metasına sormak isteyebilirsiniz.

Yanıtlar:


39

Chris Okasaki, Purely Functional Data Structures adlı kitabında "Sayısal Gösterimler" i tartışan çok iyi bir bölüme sahiptir : esasen, bir sayının bazı temsillerini alın ve onu bir veri yapısına dönüştürün. Bir lezzet katmak için işte o bölümün bölümleri:

  1. Konumsal Sayı Sistemleri
  2. İkili Sayılar (İkili Rastgele Erişim Listeleri, Zeroless Gösterimleri, Tembel Gösterimler, Segmentli Gösterimler)
  3. Eğik İkili Sayılar (Eğik İkili Rasgele Erişim Listeleri, Eğriltme Binom Yığınları)
  4. Üçlü ve Kuaterner Sayılar

Damıtılmış en iyi numaralardan bazıları:

  • Yoğun ve seyrek arasında ayrım yapınSayıların gösterimleri (genellikle bunu matrislerde veya grafiklerde görürsünüz, ancak sayılar için de geçerlidir!)
  • Fazlalık sayı sistemleri (bir sayının birden fazla temsiline sahip sistemler) kullanışlıdır.
  • İlk basamağı sıfır olmayacak şekilde düzenlerseniz veya sıfır olmayan bir gösterim kullanırsanız, veri yapısının başını almak verimli olabilir.
  • Veri yapısını segmentlere ayırarak ( listenin sonunu almaktan) ve (listeye dahil ederek) ardışık ödünç almaktan kaçının

İşte o bölümün referans listesi de:

  • Guibas, McCreight, Plass ve Roberts: Doğrusal listeler için yeni bir temsil.
  • Myers: Uygulamalı bir rastgele erişim yığını
  • Carlsson, Munro, Poblete: Sabit ekleme süresine sahip örtük bir iki terimli kuyruk.
  • Kaplan, Tarjan: Özyinelemeli yavaşlama yoluyla katenasyon içeren tamamen işlevsel listeler.

2
+1 Okasaki'nin kitabının bir kopyasına sahibim ... Bu bölümleri sevdim ve kısmen bu soruyu sormamın nedeni (önyüklemeli çarpık iki terimli yığınlar gerçekten harika!) Yine de baştan sona okumadım belki yapmalıyım. Ayrıca bu referanslara da bir göz atacağım; harika görünüyorlar.
templatetypedef

Okasaky'nin tezinin tamamı çevrimiçi olarak mevcuttur: cs.cmu.edu/~rwh/theses/okasaki.pdf
Gigi

20

"Üçlü sayılar, bir Sierpinski Üçgeni veya bir Cantor seti gibi kendine benzer yapıları rahatlıkla iletmek için kullanılabilir." kaynak

"Dördüncül sayılar, 2B Hilbert eğrilerinin temsilinde kullanılır." kaynak

"Dörtlü-hayali sayı sistemi ilk kez 1955 yılında Donald Knuth tarafından bir lise bilim yetenek araştırmasına sunulmak üzere önerildi. Bu, temel olarak hayali 2i sayısını kullanan standart olmayan bir konumsal sayı sistemidir. her karmaşık sayıyı yalnızca 0, 1, 2 ve 3 rakamlarını kullanarak temsil etmek için. " kaynak

"Roma rakamları biquinary bir sistemdir." kaynak

"Senaryanın asal sayılar çalışmasında yararlı olduğu düşünülebilir, çünkü altıda ifade edildiğinde, 2 ve 3 dışındaki tüm asalların son hane olarak 1 veya 5'i vardır." kaynak

"Sexagesimal (60 tabanı), tabanı altmış olan bir sayı sistemidir. MÖ 3. binyılda antik Sümerlerden ortaya çıkmıştır, eski Babillilere aktarılmıştır ve hala - değiştirilmiş bir biçimde - ölçüm için kullanılmaktadır. zaman, açılar ve açılar olan coğrafi koordinatlar. " kaynak

vb...

Bu liste iyi bir başlangıç ​​noktasıdır.


6
Bunların hiçbiri algoritmalarla ilgili değil ..
BlueRaja - Danny Pflughoeft

11
Elbette öyleler. Üçlü olarak bir Sierpinski Üçgeni üçgeni inşa etmek veya coğrafi koordinatları altmışlık olarak hesaplamak. Roma rakamlarını ondalık sayıya dönüştürmek için bir algoritmaya ne dersiniz? Altıncı sisteme dayalı asal sayı bulma algoritmalarına ne dersiniz?
Benjamin

9

Geçen gün sorunuzu okudum ve bugün bir sorunla karşılaştım: Bir kümenin tüm bölümlemelerini nasıl oluşturabilirim? Aklıma gelen ve kullandığım çözüm (belki de sorunuzu okurken) şuydu:

(P) bölümlerine ihtiyacım olan (n) elemanlı bir küme için, taban (p) 'deki tüm (n) basamak sayılarını sayın.

Her sayı bir bölümlemeye karşılık gelir. Her rakam kümedeki bir öğeye karşılık gelir ve rakamın değeri size öğeyi hangi bölüme koyacağınızı söyler.

Şaşırtıcı değil ama güzel. Tamamlandı, fazlalığa neden olmaz ve keyfi temeller kullanır. Kullandığınız taban, belirli bölümleme sorununa bağlıdır.


3
Bunun templatetypedef'in gönderisinden tamamen çalındığını düşünüyorum, bilinçaltımda sıkışıp kalmış olmalı. Sadece ikiliden daha fazla bazdan bahsettiği için bıraktım.
Ben Horner

2
Bu, en fazla p bölümlü tüm bölümleri oluşturur ve fazlalıkları vardır. Nasıl 111222farklıdır 222111?
Null Set

7

Son zamanlarda, 0 ile 2 n - 1 arasındaki sayıların ikili gösterimlerine dayanan sözlüksel sırayla alt kümeler oluşturmak için harika bir algoritma ile karşılaştım. Küme için hangi öğelerin seçilmesi gerektiğini belirlemek ve yerel olarak yeniden düzenlemek için sayıların bitlerini kullanır sözlüksel sıraya sokmak için oluşturulan kümeler. Merak ediyorsanız, buraya yazılan bir yazı var .

Ayrıca, birçok algoritma (Ford-Fulkerson maksimum akış algoritmasının zayıf polinom versiyonu gibi), kaba bir yaklaşımı aşamalı olarak tam bir çözüme dönüştürmek için giriş problemindeki sayıların ikili gösterimini kullanan ölçeklendirmeye dayanmaktadır.


2
Bu, alt kümeler oluşturmanın en basit yoludur :)
st0le

Bu, kombinatoryal kavramlarda saymanın en basit yolu.
Saeed Amiri

@ st0le- Bunun standart sürümden biraz daha zor olduğunu düşünüyorum çünkü bu listeler bitler ve küme dahil etme arasındaki bire bir eşlemeden aldığınız normal sıralama yerine sözlüksel sıraya göre ayarlanıyor.
templatetypedef


6

Matris çarpımını hızlandırmak için çift tabanlı sistemler hakkında belli belirsiz bir şeyler hatırlıyorum.

Çift tabanlı sistem, bir numara için iki taban kullanan yedekli bir sistemdir.

 n = Sum(i=1 --> l){ c_i * 2^{a_i} * 3 ^ {b_i}, where c in {-1,1}

Fazlalık, bir sayının birçok şekilde belirtilebileceği anlamına gelir.

Vassil Dimitrov, Todor Cooklev'in "Matris Polinomunun Hesaplanması için Hibrit Algoritma" adlı makalesine bakabilirsiniz.

Elimden gelen en iyi kısa özeti vermeye çalışıyorum.

Matris polinomunu hesaplamaya çalışıyorlardı G(N,A) = I + A + ... + A^{N-1}.

Supoosing N bileşiktir G(N,A) = G(J,A) * G(K, A^J), eğer J = 2 için başvurursak, şunu elde ederiz:

         / (I + A) * G(K, A^2)        , if N = 2K
G(N,A) = |
         \ I + (A + A^2) * G(K, A^2)  , if N = 2K + 1

Ayrıca,

         / (I + A + A^2) * G(K, A^3)           , if N = 3K
G(N,A) = | I + (A + A^2 + A^3) * G(K, A^3)     , if N = 3K + 1
         \ I + A * (A + A^2 + A^3) * G(K, A^3) , if N = 3K + 2

Bu denklemlerden bazılarının ilk sistemde hızlı ve bazılarının ikinci sistemde daha iyi olduğu "aşikar" olduğu için (şaka yollu) - bu nedenle bunlardan en iyisini seçmek iyi bir fikirdir N. Ancak bu, hem 2 hem de 3 için hızlı modulo işlemi gerektirir. İşte çift tabanın neden devreye girdiği - temelde modulo işlemini her ikisi için hızlı bir şekilde yapabilirsiniz ve size birleşik bir sistem sağlar:

         / (I + A + A^2) * G(K, A^3)       , if N = 0 or 3 mod 6
G(N,A) = | I + (A + A^2 + A^3) * G(K, A^3) , if N = 1 or 4 mod 6
         | (I + A) * G(3K + 1, A^2)        , if N = 2 mod 6
         \ I + (A + A^2) * G(3K + 2, A^2)  , if N = 5 mod 6

Bu alanda uzman olmadığım için daha iyi açıklama için makaleye bakın.



5

Burada, "sahte para" sorununu çözmek için üçlü sayıları kullanma hakkında güzel bir gönderi var (burada, mümkün olduğunca az kez bir terazi kullanarak, normal bir çantada tek bir sahte madeni para tespit etmeniz gerekir)


Bu harika bir gönderiydi ve bunu "Sayı Sistemleriyle Eğlence" adlı bir konuşmada kullandım. Gönderiğin için çok teşekkürler!
templatetypedef

hoş geldiniz, kullanabildiğinize sevindim!
Martin DeMello

5

Hashing dizgileri (örneğin Rabin-Karp algoritmasında) dizeyi genellikle n basamaktan oluşan bir taban-b sayısı olarak değerlendirir (burada n, dizenin uzunluğudur ve b, yeterince büyük olan bazı seçilmiş temeldir). Örneğin, "ABCD" dizesi şu şekilde karma hale getirilebilir:

'A'*b^3+'B'*b^2+'C'*b^1+'D'*b^0

ASCII değerlerini karakterlerin yerine koymak ve b'yi 256 olarak almak,

65*256^3+66*256^2+67*256^1+68*256^0

Bununla birlikte, çoğu pratik uygulamada, elde edilen değer, sonucu yeterince küçük tutmak için makul boyutta bir sayı olarak modulo alınır.



4

İçinde Hackers Delight (her programcı gözlerimde bilmeli bir kitap) unusal üsleri hakkında tam bir bölüm vardır gibi -2 üs olarak (yea, sağ negatif bazlar) veya -1 + i (i olarak hayali birim sqrt (-1)) olarak taban. Ayrıca, en iyi temelin ne olduğunu iyi hesapladım (donanım tasarımı açısından, onu okumak istemeyenler için: Denklemin çözümü e, yani 2 veya 3 ile gidebilirsiniz, 3 biraz daha iyi olurdu (faktör 2) 'den 1.056 kat daha iyi - ancak teknik olarak daha pratiktir).

Aklıma gelen diğer şeyler gri sayaç (bu sistemde sadece 1 bitlik değişiklikleri saydığınızda, bu özelliği genellikle metastabilite sorunlarını azaltmak için donanım tasarımında kullanırsınız) veya daha önce bahsedilen Huffmann kodlamasının genelleştirilmesi - aritmetik kodlama.


3

Kriptografi, tamsayı halkalarından (modüler aritmatik) ve ayrıca işlemleri sezgisel olarak tamsayı katsayılı polinomların davranış biçimine dayanan sonlu alanlardan kapsamlı bir şekilde yararlanır.



1

Harika soru. Liste gerçekten uzun. Zamanı söyleme, karışık bazların basit bir örneğidir (günler | saat | dakika | saniye | am / pm)

Bunu duymakla ilgileniyorsanız, bir meta-temel numaralandırma n-tuple çerçevesi oluşturdum. Baz numaralandırma sistemleri için çok tatlı sözdizimsel bir şeker. Henüz yayınlanmadı. Kullanıcı adıma e-posta gönder (gmail'de).


1
Ve herhangi bir takvim sistemi - Maya, Ay, Babil .... ve 1971 öncesi İngiliz para birimi (LSD). Dediğiniz gibi liste uzayıp gidiyor.
Chris Walton

1

2 tabanını kullanan favorilerimden biri Aritmetik Kodlama . Alışılmadık bir durumdur çünkü algoritmanın hartı ikili olarak 0 ile 1 arasındaki sayıların temsillerini kullanır.


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.