Hadamard sorununun optimizasyon versiyonu


11

İlk olarak, bazı tanımlar.

Bir Hadamard matris Girişleri ya olan bir kare matris olan +1 veya -1 olan ve satırlar karşılıklı olarak ortogonaldir. Hadamard varsayım için 4k bir Hadamard matrisi, her bir pozitif tam sayı k var olduğunu önerir.

Bir sirkülasyon matrisi , her sıra vektörünün bir önceki satır vektörüne göre bir eleman sağa döndürüldüğü özel bir matris türüdür. Yani matris ilk satırı ile tanımlanır.

Edilir bilinen 4'e 4 matrisleri haricinde vardır ki hiçbir circulant Hadamard matrisleri .

M sıralı ve n> = m sütunlu bir matris, bazı dolaşım matrisinin ilk m sırası ise , kısmi dolaşımdır .

Görev

2'den başlayan her çift n tamsayısı için, en büyük kısmi sirkülasyon matrisinin büyüklüğünü + -1 girişleri ve tüm satırlarının karşılıklı olarak dik olması özelliğine sahip n sütun ile çıktılayın.

Puan

Puanınız en yüksek nolandır ki k <= n, hiç kimse sizden daha yüksek bir doğru cevap göndermemiştir. Açıkçası tüm optimum cevaplarınız varsa, o zaman en yüksek gönderdiğiniz puan için alacaksınız n. Ancak, cevabınız optimum olmasa bile, başka hiç kimse onu yenemezse skoru yine de alabilirsiniz.

Diller ve kütüphaneler

İstediğiniz dil ve kitaplıkları kullanabilirsiniz. Mümkün olduğunda, kodunuzu çalıştırabilmeniz iyi olur, bu nedenle mümkünse kodunuzu Linux'ta nasıl çalıştıracağınız / derleyeceğinize ilişkin tam bir açıklama ekleyin.

Öncü girişler

  • 64 Python'da Mitch Schwartz tarafından

Yanıtlar:


7

Python 2

Tabloya kadar n = 64, kaba kuvvet ile optimal doğrulanmış n = 32:

 4  4 0001
 8  4 00010001
12  6 000001010011
16  8 0000010011101011
20 10 00010001011110011010
24 12 000101001000111110110111
28 14 0001011000010011101011111011
32 14 00001101000111011101101011110010
36 18 001000101001000111110011010110111000
40 20 0010101110001101101111110100011100100100
44 18 00010000011100100011110110110101011101101111
48 24 001011011001010111111001110000100110101000000110
52 26 0011010111000100111011011111001010001110100001001000
56 28 00100111111101010110001100001101100000001010100111001011
60 30 000001101101100011100101011101111110010010111100011010100010
64 32 0001100011110101111111010010011011100111000010101000001011011001

nerede 0temsil eder -1. Eğer n4 ile bölünebilir değildir o zaman m = 1en uygunudur. Bu kod (veya kodun küçük varyasyonları) kullanılarak oluşturuldu ancak daha yüksek deneme sürümleriyle daha fazla deneme yapıldı n:

from random import *

seed(10)

trials=10000

def calcm(x,n):
    m=1
    y=x
    while 1:
        y=((y&1)<<(n-1))|(y>>1)
        if bin(x^y).count('1')!=n/2:
            return m
        m+=1

def hillclimb(x,n,ns):
    bestm=calcm(x,n)

    while 1:
        cands=[]

        for pos in ns:
            xx=x^(1<<pos)
            m=calcm(xx,n)

            if m>bestm:
                bestm=m
                cands=[xx]
            elif cands and m==bestm:
                cands+=[xx]

        if not cands:
            break

        x=choice(cands)

    return x,bestm

def approx(n):
    if n<10: return brute(n)

    bestm=1
    bestx=0

    for trial in xrange(1,trials+1):
        if not trial&16383:
            print bestm,bin((1<<n)|bestx)[3:]

        if not trial&1:
            x=randint(0,(1<<(n/2-2))-1)
            x=(x<<(n/2)) | (((1<<(n/2))-1)^x)
            ns=range(n/2-2)

            if not trial&7:
                adj=randint(1,5)
                x^=((1<<adj)-1)<<randint(0,n/2-adj)
        else:
            x=randint(0,(1<<(n-2))-1)
            ns=range(n-2)

        x,m=hillclimb(x,n,ns)

        if m>bestm:
            bestm=m
            bestx=x

    return bestm,bestx

def brute(n):
    bestm=1
    bestx=0

    for x in xrange(1<<(n-2)):
        m=calcm(x,n)
        if m>bestm:
            bestm=m
            bestx=x

    return bestm,bestx

for n in xrange(4,101,4):
    m,x=approx(n)
    print n,m,bin((1<<n)|x)[3:]

Yaklaşım, küçükler için fark edilen bir desenden yararlanarak, tepeye tırmanma ile basit rastgele aramadır n. Desen, optimal için m, ilk sıranın ikinci yarısının, genellikle ilk yarının (bitsel) negatifinden küçük düzenleme mesafesine sahip olmasıdır. Yukarıdaki kodun sonuçları küçükler için iyidir, nancak kaba kuvvet uygulanamaz hale geldikten kısa bir süre sonra bozulmaya başlar; Daha iyi bir yaklaşım görmekten mutlu olurum.

Bazı gözlemler:

  • Ne zaman ngarip, m = 1birler ve negatif olanların bir tek sayı sıfıra kadar ekleyin çünkü en uygunudur. (Ortogonal nokta ürününün sıfır olduğu anlamına gelir.)
  • Ne zaman n = 4k + 2, m = 1en uygunudur, çünkü m >= 2bizim için tam olarak n/2ters kayıt yapmamız gerekir {(a1,a2), (a2,a3), ... (a{n-1},an), (an,a1)}ve tek sayıda ters kayıt yapılması gerekir a1 = -a1.
  • İki sıralı ive jbir sirkülasyon matrisindeki nokta çarpımı ile belirlenir abs(i-j). Örneğin, eğer row1 . row2 = 0öyleyse row4 . row5 = 0. Bunun nedeni, nokta ürününün eleman çiftlerinin aynı, sadece döndürülmüş olmasıdır.
  • Sonuç olarak, karşılıklı dikliği kontrol etmek için, sadece ilk satıra göre ardışık satırları kontrol etmemiz gerekir.
  • Biz bir ikili dizi olarak bir satır temsil ederse 0yerine -1, biz bitsel xor alıp birlikte popcount karşılaştırarak iki satır ortogonalliğini kontrol edebilirsiniz n/2.
  • İlk sıranın ilk iki öğesini keyfi olarak düzeltebiliriz, çünkü (1) Bir matrisi olumsuzlamak nokta ürünlerinin sıfıra eşit olup olmadığını etkilemez ve (2) Aynı işaret ve iki bitişik en az iki bitişik öğe olması gerektiğini biliyoruz. farklı işaretli bitişik elemanlar, böylece istenen çifti başında yerleştirmek için döndürebiliriz.
  • Bir çözüm , ilk satırı kendine (tekrar tekrar) birleştirerek keyfi (n0, m0)olarak otomatik olarak çözümler verecektir . Bunun bir sonucu, 4 ile bölünebilir herhangi bir şey için kolayca elde edebiliriz .(k * n0, m0)k > 1m = 4n

Ne zaman n/2için sıkı bir üst sınır olduğu varsayımı doğaldır , ancak bunun nasıl kanıtlanacağını bilmiyorum.mn > 4


16 sıra ve 32 sütun ile bir çözüm olmaması çok ilginç. neden olduğu hakkında bir fikrin var mı?

@Lembik Bir fikrim olsaydı, cevaba yazardım.
Mitch Schwartz
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.