napisałem algorytm wyszukujący liczby zaprzyjaźnione w C. Jednak dla np. 10000000 wykonuje obliczenia w czasie 107s. Czy można bardziej zoptymalizować algorytm by wykonywał się szybciej oraz czy funkcję wyszukujące dzielniki poprawnie napisałem?
Tzn. liczysz sobie raz te 107 sekund, a następnie wynik zaszywasz w kodzie programu (dostęp w czasie stałym). Tych liczb jest mało. Tak się bardzo często robi z różnymi magicznymi liczbami pierwszymi w STL-u.
Nie rozumiem czemu odpada. Moim zdaniem jest to prosta obserwacja tego, że zbiór liczb spełniających warunki jest rzadki, a do tego jego rozwiązanie jest klasy NP-Hard. W celu optymalizacji stosujemy prosty hard-kod, bądź ujmując profesjonalnie metodę słownikowania.
Jedyna optymalizacja jaką widzę, to zmniejszenie liczby if-ów przy drugim odwołaniu do funkcji suma dzielników. Po jedno razowym jej przejściu
for(i=2; i<=where; i++)
if(liczba%i == 0)
jak już raz przejdziesz tego if-a, to możesz zapamiętywać w jakimś zbiorze, które liczby go spełniły i wtedy przy kolejnych wywołania po prostu pominąć (wykonać tylko dla liczb ze zbioru). Ale ponieważ wywołania są tylko 2 to może przyśpieszy sekundę, czy dwie.
Liczby zaprzyjaźnione to para różnych liczb naturalnych, takich że suma dzielników każdej z tych liczb równa się drugiej (nie uwzględniając tych dwóch liczb jako dzielników).
Pierwszą parą takich liczb, która została podana już przez Pitagorasa, jest para liczb 220 i 284, ponieważ:
Dzięki enedil za propozycję, ale pamięć dynamiczna tutaj się nie sprawdzi bo nie wiem jaką liczbę wprowadzi na wejściu prowadzący (a będzie duża ). Faktem jest to, że tylko raz odwołujesz się do funkcji sumaDzielnkow() co wpływa bardzo na szybkość.
Nie dokońca rozumiem jak może to pomóc, ale dla liczb względznie pierwszych, funkcja ta jest łączna multiplikatywnie, czyli sumaDzielnkow(a*b) = sumaDzielnkow(a) * sumaDzielnkow(b).
Funkcja sumaDzielników jest nadal do kitu ;) Skoro masz tablice dlaczego nie liczysz sumy dzielników przy użyciu mnożeń tylko reszty z dzielenia? Raz że złożoność zamiast n*logn masz n^2, dwa, że wykorzystujesz dzielenia co zajmuje od 20 do 80 cykli procesora(zamiast 4). Poza tym zapotrzebowanie na RAM w stylu Chrome, bo dla zakresu 1mld liczb wyniesie aż 4-8GB. Ale w tej sprawie nie mam koncepcji.
Na moim kompie wykonanie tej niby lepszej wersji zajmuje aż 650s (Pentium M ULV 1.1GHz) myśle że można by to zbić do 200s (u Ciebie do 10-20s).
Taka optymalizacja to żadna optymalizacja, nie o to mi chodziło, okej za póxno na poprawki. Ale dlaczego temat do zamkniecia? Jesteś pewny zaliczenia? Jako jedyny miałeś i bedziesz mieć takie zadanie? Na temat problemu nie można dalej prowadzić dyskusji? Optymalizacje sprawdze we własnym zakresie, w swoim czasie dla własnej ciekawości skoro temat chcesz zamykać.
3.13 Zabrania się umieszczania próśb w celu odrobienia pracy domowej, zleceń (np. zrobienie strony WWW, napisanie kodu, i.t.p.), zaliczeń etc. jak i podawania rozwiązań w organizowanych quizach.