Beal'ın 1.000.000 $ 'ını alalım


17

Beal's Conjecture'in bunu kanıtlarsanız / onaylamazsanız bir milyon dolarlık ödülü vardır.

A ^ x + B ^ y = C ^ zA, B, C, x, y ve z'nin x, y, z> 2 ile pozitif tamsayılar olması durumunda, A, B ve C'nin ortak bir ana faktöre sahip olduğunu belirtir .

Zor olan, bunu çürütmek için bir karşı örnek arayan bir program yazmaktır!

kurallar

  • Beal's Conjecture'in karşı örneğini arayan bir program yazın
  • Kapsamlı bir arama yapabilir (yani, bu forma uyan tüm olası sayı kombinasyonları) veya bazı optimizasyonları kullanabilirsiniz (örneğin, A ve B simetriktir).
  • Rasgele kesinlikli tamsayılar kullanmalısınız.

notlar

  • Bu bir popülerlik yarışması, yaratıcı olun!
  • Hız gerekli değildir, ancak daha ilginç hale getirir. Optimize!
  • Ayrıca en kısa kodu da görmekle ilgileniyorum. Benden +1 alacaksın!
  • Kazanan programı, erişebileceğim bir süper bilgisayarda çalıştıracağım!
  • Bu varsayım doğru kabul edilir, ancak bu deneyemeyeceğimiz anlamına gelmez!
  • Google'dan Peter Norvig de bu sorunu denedi. Sayfasını rehberlik olarak kullanabilirsiniz . Örnek olarak kullanabileceğiniz kısa bir Python programı var.
  • Başka bir adam (Google'da da çalışır) Norvig'in yaklaşımında büyük ölçüde iyileşti, sayfası (kaynak kodlu) burada bulunabilir .
  • Bununla ilgili iki yıl öncesine ait SO sorum da faydalı olabilir: Belirli bir aralıktaki tüm A ^ x öğelerini tamamlayın .

1
Süper bilgisayar? Şimdi bu harika. Parayı bölme şansı var mı?
Aprıʇǝɥʇuʎs

@Synthetica Bu varsayım zaten çok, çok, çok büyük sayılarla test edilmiştir, bu yüzden bu çoğunlukla eğlenmek içindir. Ama elbette parayı bölebiliriz :)
Austin Henley

2
"Ya sonsuza kadar devam etmeli ya da sınırlı bir üst sınırlamaya izin vermeli (ne kadar büyük olursa olsun)." ... hangi alternatiflerin aksine?
undergroundmonorail

@undergroundmonorail Sadece küçük sayılar için çalışıyor.
Austin Henley

2
Küçük sayılar sınırlı bir üst sınırdır.
undergroundmonorail

Yanıtlar:


4

Zavallı tembelim (cinas amaçlı), ama neden olmasın ... kuralları yerine getiriyor gibi görünüyor.

Haskell, 204

import Control.Monad
import Control.Monad.Omega
main=print.filter(\[(a,x),(b,y),(c,z)] 
 ->and$(a^x+b^y==c^z):zipWith(((>1).).gcd)[a,b,c][b,c,a])
 .runOmega$mapM(\_->liftM2(,)(each[1..])$each[3..])"123"

Bu , counterexample özelliğini karşılayan tüm kombinasyonları 1 yazdırır . Köşegenleştirme için kontrol-monad-omega paketini kullandım ℕ 6'yı ... kütüphane hile sayılabilir. Ama birisinin daha sonra tüm bu şeylerin dile yerleştirildiği (ya da değil mi?) Bir APL cevabı göndereceğini görmek, bu konuda çok fazla vermiyorum ...

Tabii ki, program gerçekten bir karşı örnek vermeyi beklemek için çok yavaş (naif tükenme ve bağlantılı listeler), ancak Haskell aslında iyi bir performans elde edebilir.


1 Tüpleri liste biçiminde, yani bir satırda yazdırdığı için, terminalinizin arabelleğe almasını kapatmanız gerekir veya bir sonuç geldiğinde görmezsiniz. Alternatif olarak,print ile mapM_ printher sonucundan sonra bir yeni satır olsun, hat tamponlu bir terminalin yıkanması.

Program, değişiklik sınamak için each[3..]için each[2..], o zaman sadece olmayan tüm aralarında asal Pisagor küpe olarak sonuç alırsınız.


2

C #, döngü yok

Tamam, bu bağlantılardan birkaçını kaçırdım, ama dürüst olmak gerekirse biraz sıkıcıydılar. Karma tablolar ve ne ile cehennem optimize etmek ilgilenmiyorum. Neden ihtiyacım var? Kahrolasý bir süper bilgisayarýn var!

Cehennem, döngülerle uğraşmak bile istemiyorum! Bu çözüm döngüsüz kuralı izleyecektir .

Yazmak üzere olduğum kodun iyi bir kod veya gerçek hayatta yazacağım kod türü olmadığını lütfen unutmayın (herhangi bir muhtemel işveren bunu okumak için). Bu kod, kısalığı ve bir anlatıda çalışma yeteneğini vurgular ve uygun sözleşmeleri, ritüelleri ve döngüler vb.

Neden bahsettiğimi göstermek için, denklemin işlenenlerini saklamak için genel alanlara sahip şok edici bir sınıfla başlayacağız:

class BealOperands
{
    public BigInteger A, B, C, x, y, z;
}

Tamam, muhtemelen en zor olan şeyle başlayacağız. Bu işlenenlerin her birleşimi için izin vermenin bir yolunu bulmamız gerekiyor. Kuşkusuz her permütasyonu kontrol etmekten daha etkili bir şekilde yapmanın yolları var, ama onları anlamaktan rahatsız edilemem. Neden yapayım? Lanet olası bir süper bilgisayarımız var!

İşte bulduğum algoritma. İnanılmaz derecede verimsiz ve aynı işlenenleri tekrar tekrar geçiyor, ama kimin umurunda? Süper bilgisayar!

  • Altı işlenene bir taban-2 numarası olarak davranın ve her kombinasyondan geçirin.
  • Altı işlenene bir baz-3 numarası olarak davranın ve her kombinasyona izin verin.
  • Altı işlenene bir taban-4 numarası olarak davranın ve her kombinasyondan geçirin.
  • (...)

Bütün bunlar ilmeksiz nasıl yapılır? Kolay! Sadece IEnumerableve IEnumeratorpermütasyonları dışarı pompalamak için ilişkili bir uygulamak . Daha sonra sorgulamak için LINQ kullanacağız.

class BealOperandGenerator : IEnumerable<BealOperands>
{
    // Implementation of IEnumerable<> and IEnumerable -- basically boilerplate to get to BealOperandGeneratorEnumerator.
    public IEnumerator<BealOperands> GetEnumerator() { return new BealOperandGeneratorEnumerator(); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

class BealOperandGeneratorEnumerator : IEnumerator<BealOperands>
{
    public BealOperandGeneratorEnumerator() { Reset(); }

    private BealOperands operands;
    private BigInteger @base;

    public void Reset()
    {
        // A is set to 0, which is "before" its minimum value, because IEnumerators are supposed to
        // point to their first element *after* the first call to MoveNext().
        // All other operands are set to their minimum values.
        operands = new BealOperands { A = 0, B = 1, C = 1, x = 3, y = 3, z = 3 };
        @base = 2;
    }

    public BealOperands Current
    {
        get 
        {
            // We need to return a copy, since we'll be manipulating our internal one.
            return new BealOperands { 
                A = operands.A, B = operands.B, C = operands.C, 
                x = operands.x, y = operands.y, z = operands.z };
        }
    }

    public bool MoveNext()
    {
        // Increment the lowest "digit" and "carry" as necessary.
        operands.A++;
        if (operands.A - 1 >= @base)
        {
            operands.A = 1; operands.B++;
            if (operands.B - 1 >= @base)
            {
                operands.B = 1; operands.C++;
                if (operands.C - 1 >= @base)
                {
                    operands.C = 1; operands.x++;
                    if (operands.x - 3 >= @base)
                    {
                        operands.x = 3; operands.y++;
                        if (operands.y - 3 >= @base)
                        {
                            operands.y = 3; operands.z++;
                            if (operands.z - 3 >= @base)
                            {
                                operands.z = 3; @base++;
                            }
                        }
                    }
                }
            }
        }
        // There will always be more elements in this sequence.
        return true;
    }

    // More boilerplate
    object System.Collections.IEnumerator.Current { get { return Current; } }
    public void Dispose() { }
}

Şimdi işteyiz! Yapmamız gereken tek şey BealOperandGeneratorBeal's Conjecture'in bir örneğini sıralamak ve bunun bir örneğini bulmak.

Bir sonraki büyük sorunumuz, a'nın BigIntegergücüne yükseltmek için yerleşik bir yol olmadığıdır BigInteger. Bir BigInteger.Pow(BigInteger value, int exponent), ve başka bir modulo sonsuzun gücüne BigInteger.ModPow(BigInteger value, BigInteger exponent, BigInteger modulus)yükseltmek için bir yöntem yoktur .BigIntegerBigInteger

Ne parlak bir çivi! Bizim IEnumerable/ IEnumeratorçekiç ile çözülmesi için yapılmış gibi görünüyor !

class BigIntegerPowerEnumerable : IEnumerable<Tuple<BigInteger, BigInteger>>
{
    public BigIntegerPowerEnumerable(BigInteger @base, BigInteger exponent) { this.@base = @base; this.exponent = exponent; } 
    BigInteger @base, exponent;

    public IEnumerator<Tuple<BigInteger, BigInteger>> GetEnumerator() { return new BigIntegerPowerEnumerator(@base, exponent); }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); }
}

class BigIntegerPowerEnumerator : IEnumerator<Tuple<BigInteger, BigInteger>>
{
    public BigIntegerPowerEnumerator(BigInteger @base, BigInteger exponent) 
    {
        originalBase = @base; 
        originalExponent = exponent;
        Reset(); 
    }

    BigInteger originalBase, currentBase, originalExponent, currentExponent;
    bool finished;

    public void Reset()
    {
        // IEnumerable.Reset() is a silly method. You're required to implement it when you implement IEnumerable,
        // but it isn't used by foreach or LINQ or anything. If you want to re-enumerate the enumerable, just get
        // a brand new enumerator.
        // In this case it gets in the way. The only reason I'm storing the original values is so I can implement 
        // this useless method properly. I supposed I could just throw a NotImplementedException or something, 
        // but it's done now.
        currentBase = originalBase;
        currentExponent = originalExponent;
        finished = false;
    }

    public bool MoveNext()
    {
        if (finished) return false;

        if (currentExponent <= Int32.MaxValue)
        {
            currentBase = BigInteger.Pow(currentBase, (Int32)currentExponent);
            currentExponent = 1;
            finished = true;
        }
        else
        {
            currentBase = BigInteger.Pow(currentBase, Int32.MaxValue);
            currentExponent -= Int32.MaxValue;
        }
        return true;
    }

    public Tuple<BigInteger, BigInteger> Current
    {
        get { return new Tuple<BigInteger, BigInteger>(currentBase, currentExponent); }
    }

    object System.Collections.IEnumerator.Current { get { return Current; } }
    public void Dispose() { }
}

static class BigIntegerPowExtension
{
    public static BigInteger Pow(this BigInteger @base, BigInteger exponent)
    {
        return new BigIntegerPowerEnumerable(@base, exponent).Last().Item1;
    }
}

Şimdi Pow, a üzerinde çağrılabilecek bir uzantı yöntemimiz var BigIntegerveBigInteger üssü alan ve bir modül almayan .

Tamam, geri dönelim. Belirli bir BealOperandsşeyin Beal Konjonktürünün bir örneği olup olmadığını nasıl anlayabiliriz ? İki şeyin doğru olması gerekir:

  • İşlenenler, sayfanın üst kısmında bu formüle takıldığında gerçek bir denklem oluşturmalıdır.
  • A, B ve C'nin ortak bir ana faktörü OLMAMALIDIR (yani GCD'si 1'dir).

İlk durumu kontrol etmek için ihtiyacımız olan şey bizde. Ve ikinci koşulu kontrol etmek göründüğünden çok daha kolay çıkıyor. bunu döngüler olmadan uygulamaya çalışmanın tüm kabusu rahatça kaldırmamızı sağlayan BigIntegergüzel bir GreatestCommonDivisoryöntem sağlar.

Bu yüzden BealOperandsa'nın karşı örnek olup olmadığını kontrol etmek için bir yöntem yazmaya hazırız . İşte gidiyor ...

static class BealOperandsExtensions
{
    public static bool IsBealsConjectureCounterExample(this BealOperands o)
    {
        // If the equation isn't even true, we don't have a counter example unfortunately
        if (o.A.Pow(o.x) + o.B.Pow(o.y) != o.C.Pow(o.z))
        {
            return false;
        }

        // We have a counterexample if A, B and C are coprime
        return BigInteger.GreatestCommonDivisor(o.A, o.B) == 1 &&
               BigInteger.GreatestCommonDivisor(o.A, o.C) == 1 &&
               BigInteger.GreatestCommonDivisor(o.B, o.C) == 1;
    }
}

Ve son olarak, bu oldukça kaygan Mainyöntemle hepsini bir araya getirebiliriz :

static class Program
{
    static void Main()
    {
        var bealOperandGenerator = new BealOperandGenerator();
        if (bealOperandGenerator.Any(o => o.IsBealsConjectureCounterExample()))
        {
            Console.WriteLine("IN YOUR FACE, BEAL!");
        }
    }
}

2

C ^ Z <= 1.0E27 olan karşı örnekler yoktur.

Şubat 2019 itibariyle “X” ve / veya “Y” üsünün> = 5 olması gerektiği varsayımıyla C ^ Z <= 1.0E29'a bakıyorum.

Bu programın mevcut sürümü (“X” ve / veya “Y”> = 5), C ^ Z <= 1.0E15 için tüm çözümleri bulmak üzere AMD 2920X'te 1 saniyeden az sürer. (Ancak tüm gcd (A, B, C)> = 2'dir)

Ayrıntılar http://www.durangobill.com/BealsConjecture.html

Geçerli kodu (“C” ve OpenMP kullanır) bu sınırların ötesinde değiştirebilirim ama çalıştırmak için 128GB'dan fazla RAM'e ihtiyaç duyacağım. (Yüzlerce CPU da yardımcı olacaktır. Binlerce CPU daha da iyi olurdu.) (Böyle bir şeye ücretsiz erişiminiz varsa, lütfen benimle iletişime geçin.)

E-posta adresim http://www.durangobill.com adresindeki ana sayfamda


1
Eğer bunu bazı kodlarla karşılaştırabilirseniz, bu geçerli bir cevap olabilir, aksi takdirde muhtemelen soruya yorum yapmak için en uygunudur. Ancak bu konuda yaptığınız çalışmalar her iki şekilde de etkileyicidir.
Οurous

Birçok üniversitenin yüksek performanslı kümeleri vardır. Birine ulaştıysanız, size erişim izni verebilirler. Sadece rölantide çok fazla küme gördüm!
Austin Henley

1

Beal'ın arama programının 2. varyasyonu tamamlandı. Sonuçlar:

1) Karşı örnek yok CZ<1026. İçin tüm genel çözümlerin tam listesibirX+BY=CZ üslerden en az biriyle (X,Y)> =4http://www.durangobill.com/BealXgt3e27.txt adresinde görülebilir

2) En azından üslerin (X,Y) olmalıdır > =5ile karşı örnek yok CZ<1028. İçin tüm genel çözümlerin tam listesibirX+BY=CZ üslerden en az biriyle (X,Y)> =5ve C ^ Z <1.0E29 şu adreste görülebilir: http://www.durangobill.com/BealXgt4e29.txt

Ayrıntılar: http://www.durangobill.com/BealsConjecture.html

Sonraki iki soru :: 1) Bir süper bilgisayar aramayı genişletebilir mi? 2) Bir süper bilgisayar aramayı uzatabilirse, pratik olur mu?

1) Yukarıdaki aramalardan herhangi birini 1.0E30'a genişletmek için, çekirdekler 300GB'ı paylaşamadığı sürece çekirdek başına 300GB RAM gerekir. 1.0E30'un ötesindeki üstel güçteki her ilave artış için, gerekli RAM miktarı en az 2.2 faktör artar.

2) üssünde 1.0E30 ve ötesindeki her bir artan artış için gereken işlem gücü miktarı, kombine CPU süresini yaklaşık 3.8 ile çarpar. 1.0E29'a yapılan arama 12 çekirdek kullanılarak 2 hafta sürdü. Süper bilgisayar süresi genellikle “serbest” değildir ve karşı örneklerin olması ihtimali çok azdır.

Kodun durangobill.com/BealE29code.txt adresindeki verimliliğine yönelik bir kılavuz olarak, 12 çekirdeğin her biri iç döngü için saniyede ortalama 220 milyon döngü yinelemesi yaptı. (Ortalama 2 haftalık çalışma içindir.) (RAM belleğimin sahip olduğumun ötesinde bir artış, bu ortalama hızı 2 katına kadar artıracaktır.)

Bir süper bilgisayara erişimi olduğundan ve ben bilmediğim için Austin'in 1) ve 2) cevaplarına izin vereceğim. (Hem 1) hem de 2) herhangi bir uzak şansla "git" ise, büyük süper bilgisayar kümeleri için çok iş parçacıklı talimatlara aşina olmadığım uyarı ile "C" kodunu sağlayabilirim.)


Soruyu üçe yaymak yerine lütfen sadece bir cevap kullanabilir misiniz? Önceki cevaplarınızı düzenleyebileceğinizi biliyorsunuz, değil mi?
Jo King

Karşı bir örnek bulduğunuz için teşekkür ederim ve daha sonra yazdırmayın ... Ayrıca bu çok kodlu golf değil ...
Axman6

0

Sığdırmak için 2 yorumda koymak zorunda kaldı.

Ana diziler aşağıdaki gibi tahsis edilir:

SortHeads = calloc(PRIME1+1, 8);
X2YmodPrime1 = calloc(ARRAYSIZE+1, 4);
X2YmodPrime2 = calloc(ARRAYSIZE+1, 4);
Base = calloc(ARRAYSIZE+1, 4);
Power = malloc(ARRAYSIZE+1);

(Bu diziler için 128 GB RAM'e ihtiyacınız olacak)

ile:

#define PRIME1 2147483647LLU
#define PRIME2 2147483629LLU
#define ARRAYSIZE 4700000000LL

“Base” aslında 33 bite ( cbrt(1.0E29)) ihtiyaç duyar - ekstra bit “Power” ile doldurulur (sadece 7 bite ihtiyaç duyar.)

Diziler, bir karma tablosuna benzer şekilde çalışır. Ancak, PRIME1'e göre sıralandıkları ve yalnızca arama tabloları olarak kullanıldıkları için bunlara erişmek için bağlantılı listelere ihtiyacınız yoktur. Sonuç olarak, bir denemenin A ^ X + B ^ Y = herhangi bir C ^ Z olup olmadığını görmek için çok hızlı bir doğrusal zaman aramasıdır.

Bu nedenle, en içteki döngüdeki ifadeler sadece iki döngü derinliğindedir.

“Pragma” ifadeleri kullanılan çoklu işlem çekirdeği sayısını kontrol eder (bu örnekte 12) - hepsi dizilerin tek kopyasına erişebilir.

İşte “ana” kod (“C” de)


Yorum kutusu sadece 600 karakter kullanmama izin verecek ve kod için 3.000+ gerekir. (? Herhangi bir öneriniz) (Ben burada yazılan olamazsa ben web sayfasında kod gönderebilir.)
Bill Butler

Buraya “ana” “C” kodunu koydum. durangobill.com/BealE29code.txt Başka bir şey yoksa, “C” de çoklu iş parçacığının işlenmesi için “nasıl yapılır” örneğidir.
Bill Butler

1
Siteye hoş geldiniz. Yorum kutuları 600 karakterle sınırlı olsa da cevabınız değil. Kodunuzu cevabınıza kolayca sığdırmanız gerekir. Eğer yorumları kesmeye çalışmıyorsanız. Ayrıca kod bloklarını kullanmak için cevabınızı yeniden biçimlendirdim. Bunlar benim yaptığım gibi 4 boşlukla yapılabilir. Kodunuzu cevabınıza taşıdığınızda, bir kod bloğuna koymanız gerekir, aksi takdirde tamamen okunamaz olacaktır.
Post Rock Garf Hunter
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.