Python Mükemmel sayı algoritması

Herkese selam. Sizlere matematiğin yazılımda ne işe yaradığına dair mükemmel bir örnek göstermek istiyorum. Maalesef forumda hala matematiği sadece okullarda görülen soyut bir kavram olarak gören birçok kişi var, daha da üzücü olan şey ise yazılım ve matematik arasındaki güçlü ilişkinin bilinmemesi. Her neyse, konuya geçelim.

Mükemmel sayı, kendisi dışındaki bölenlerinin toplamı kendisine eşit olan sayılara denir. Örneğin 6 mükemmel sayıdır. 6'nın kendisi dışındaki bölenleri {1, 2, 3}'tür ve 1 + 2 + 3 yine 6'ya eşit olur.

Python ile mükemmel sayı bulan bir program yazmaya kalktığımızda aklımıza ilk gelen şu tür bir kod olur:
Python:
def perfectNum(number):
    Sum = 0
    for i in range(1, number):
        if number % i == 0:
            Sum += i

    if Sum == number:
        return True
    return False

lim = int(input("Enter the limit: "))
perfectNums = []

for j in range(1, lim):
    if (perfectNum(j)):
        perfectNums.append(j)

print(*perfectNums)

Kodu kısaca açıklamak gerekirse, 1'den sayının kendisine kadar olan tüm sayıları döngüye alıp tam bölenleri topluyor. Eğer toplam, sayının kendisine eşitse True döndürüyor. İlk bakışta gayet temiz ve optimal bir kod gibi gözükse de birazcık matematik yardımı ile bu kodu delicesine hızlandırabiliriz. Meraklısına, bu kodun Büyük O Notasyonu, O[n] olarak geçiyor. Yeni yazacağımız kod ise O[sqrt n].

Önce optimize edilmiş yeni kodu göstereyim:
Python:
import math

def perfectNum(num):
    Sum = 1
    for i in range(2, math.ceil(num**0.5)):
        if (num % i == 0):
            Sum += i
            Sum += num // i

    return Sum == num and num != 1

lim = int(input("Enter The Max Limit: "))
perfectNums = []

for k in range(1, lim):
    perfectNum(k)
    if perfectNum(k) == True:
        perfectNums.append(k)

print(*perfectNums)

Gördüğünüz üzere for döngüsünün sınırları 2 ve karekök(sayı) şeklinde değişti. Son yazdığımız kod 1000 sınır değeri için 6.6, 10000 sınır değeri için 36 kat daha hızlı çalışıyor!

Peki bahsettiğim matematiksel yardım ne alaka? Forumda Latex desteği olmadığı için biraz zor anlatacağım ama deneyeyim. Bir sayının karekökü, küçükten büyüğe sıralanmış bölenlerinin tam ortasına denk geliyor. Bunu daha da detaylandırmaya gerek olduğunu düşünmüyorum çünkü zaten karekökün kendisiyle çarpımı içerideki sayıya eşit olacak, böylece en ortada olması gayet doğal. Peki kodumuzda bunu nasıl kullandık? Eğer sayının kareköküne kadar olan bölenlerini bulursak, diğer bölenleri döngüye ihtiyaç olmadan bulabiliyoruz. Örneğin 24 sayısı için, kareköküne 4.89 dersek, ona en yakın iki böleni 4 ve 6'nın çarpımı 24 ediyor. Yani 4'ü bilirsek 24/4 yaparak 6'ya ulaşabiliyoruz.

Bölenler ->
ezgif-frame-069.jpg


Sayının karekökü ve bölenler ->
ezgif-frame-070.jpg


Yani sayının karekökünü bildiğimiz için büyük bir işlem yükünden kurtulmuş olduk, böylece kodumuzu optimize ettik. İlgilenen varsa aşağıya kendi çektiğim videoyu (İngilizce) bırakıyorum, oradan daha ayrıntılı izleyebilirsiniz. Forumda yazılım için matematik gereksiz düşüncesine sahip arkadaşlara ise bu rehberimsi yazıyı gönderebilirsiniz. Hepinize iyi sosyaller.

Bu içeriği görüntülemek için üçüncü taraf çerezlerini yerleştirmek için izninize ihtiyacımız olacak.
Daha detaylı bilgi için, çerezler sayfamıza bakınız.
 
Son düzenleme:
Merhabalar, mükemmel sayılar hakkında internette biraz araştırma yaptım. "Mersenne asalları" adı verilmiş asal sayılar ile mükemmel sayılar arasındaki ilişki üzerine bir teori var. (2 üzeri n(-1)) sayısı eğer asal ise Mersenne asalı şeklinde tanımlanıyor. (n sayısının da asal olması gerekiyor, yani (2 üzeri 4)-1 i hesaplamamıza bile gerek yok çünkü 4 asal değil)
Mesela 2 üzeri 2 = 4, 4-1=3.
2 üzeri 3 = 8, 8-1 = 7 vb.

Bunun kuralı için Lucas Lehmer testi diye bir şey var, özellikle büyük sayılar için bir sayının Mersenne asalı olup olmadığını ispatlamak için vb. Mesela (2 üzeri 11)-1 = 2047 yapıyor ama bu sayı asal bir sayı değil imiş (23*89) yani her (2 üzeri n)-1 Mersenne asalı olacak durumu yok.

Bazı Mersenne asalları ile mükemmel sayılarla arasında da şöyle bir ilişki mevcut,
Mesela (2 üzeri 3)-1 = 7 diye bir Mersenne asal sayısı var. Bu 2^3 olduğu için 3. derece Mersenne asalı diyebiliriz.
Öklid-Euler teoremine göre (2^(p-1))(2P-1) kuralı mevcut imiş.
Yani P=3 için (2 üzeri (3-1)) (2.3-1) = (2 üzeri 2)(7) = 28 yapıyor, bu da bir mükemmel sayı. Yine şu wiki maddesi incelenebilir Mersenne asalları ile mükemmel sayılar arasındaki ilişki incelenebilir.

Çok uzatmayayım, bu teoriler ışığında internette şöyle bir python kodu mevcut, mükemmel sayıları bulmak için Mersenne asallarından yararlanıyor.


Yazılımla matematik arasındaki ilişki eğer böyle biraz daha kurcaladığınızda çok daha derine gidebiliyor yani. Kıyaslama yapabilmek için başlığın ilk mesajındaki python kodunu Online Python Compiler (Interpreter) gibi bir online compilerda, sayıya 1000000 vererek çalıştırın mesela (yanlış anlaşılmasın, kesinlikle koda laf etmiyorum), başka bir sekmede de link olarak attığım kodu çalıştırın, bu matematik teorisinden yararlanan kodun ne derece farklı olduğunu göreceksiniz. Yani yazılım ile matematiğin ilişkisi ne kadar derinleşirse ortaya da o kadar acayip şeyler çıkıyor diye özetlemek isterim.

İyi forumlar.
 
Merhabalar, mükemmel sayılar hakkında internette biraz araştırma yaptım. "Mersenne asalları" adı verilmiş asal sayılar ile mükemmel sayılar arasındaki ilişki üzerine bir teori var. (2 üzeri n(-1)) sayısı eğer asal ise Mersenne asalı şeklinde tanımlanıyor. (n sayısının da asal olması gerekiyor, yani (2 üzeri 4)-1 i hesaplamamıza bile gerek yok çünkü 4 asal değil)
Mesela 2 üzeri 2 = 4, 4-1=3.
2 üzeri 3 = 8, 8-1 = 7 vb.

Bunun kuralı için Lucas Lehmer testi diye bir şey var, özellikle büyük sayılar için bir sayının Mersenne asalı olup olmadığını ispatlamak için vb. Mesela (2 üzeri 11)-1 = 2047 yapıyor ama bu sayı asal bir sayı değil imiş (23*89) yani her (2 üzeri n)-1 Mersenne asalı olacak durumu yok.

Bazı Mersenne asalları ile mükemmel sayılarla arasında da şöyle bir ilişki mevcut,
Mesela (2 üzeri 3)-1 = 7 diye bir Mersenne asal sayısı var. Bu 2^3 olduğu için 3. derece Mersenne asalı diyebiliriz.
Öklid-Euler teoremine göre (2^(p-1))(2P-1) kuralı mevcut imiş.
Yani P=3 için (2 üzeri (3-1)) (2.3-1) = (2 üzeri 2)(7) = 28 yapıyor, bu da bir mükemmel sayı. Yine şu wiki maddesi incelenebilir Mersenne asalları ile mükemmel sayılar arasındaki ilişki incelenebilir.

Çok uzatmayayım, bu teoriler ışığında internette şöyle bir python kodu mevcut, mükemmel sayıları bulmak için Mersenne asallarından yararlanıyor.


Yazılımla matematik arasındaki ilişki eğer böyle biraz daha kurcaladığınızda çok daha derine gidebiliyor yani. Kıyaslama yapabilmek için başlığın ilk mesajındaki python kodunu Online Python Compiler (Interpreter) gibi bir online compilerda, sayıya 1000000 vererek çalıştırın mesela (yanlış anlaşılmasın, kesinlikle koda laf etmiyorum), başka bir sekmede de link olarak attığım kodu çalıştırın, bu matematik teorisinden yararlanan kodun ne derece farklı olduğunu göreceksiniz. Yani yazılım ile matematiğin ilişkisi ne kadar derinleşirse ortaya da o kadar acayip şeyler çıkıyor diye özetlemek isterim.

İyi forumlar.
Attığınız kodu inceleyeceğim, matematiksel derinliği arttıkça konunun ilginçliği de arttı. Teşekkürler!
 
Matematiğim pek yok Python kursu alacağım ne kadar zorlanırım.
Programlama dili öğrenirken matematiğin çok bir kullanım alanı yok. Zaten matematikle yazılımın ilişkisini anlayamayanlar genelde programlamayı, programlama dillerinden ibaret görenler oluyor. Python öğrenmek için kurs almaya ihtiyacınız yok bu arada, bir sürü bedava kaynak var. Tek bir hocayı takip etmeyin bir sürü yerden okuyup öğrenin.
 

Geri
Yukarı