Một phiên bản tối ưu hóa của vấn đề Hadamard


11

Đầu tiên, một số định nghĩa.

Một Hadamard ma trận là một ma trận vuông có mục hoặc là +1 hoặc -1 và có hàng là trực giao lẫn nhau. Các Hadamard phỏng đoán đề xuất rằng một ma trận Hadamard trật tự 4k tồn tại cho mọi số nguyên k tích cực.

Một ma trận circulant là một loại đặc biệt của ma trận trong đó mỗi vector hàng là xoay một yếu tố với thân nhân quyền vector hàng trước. Đó là ma trận được xác định bởi hàng đầu tiên của nó.

Được biết , ngoại trừ ma trận 4 x 4, không có ma trận Hadamard tuần hoàn .

Một ma trận có m hàng và n> = m cột là tuần hoàn một phần , nếu đó là hàng m đầu tiên của một số ma trận tuần hoàn.

Nhiệm vụ

Đối với mỗi số nguyên n chẵn bắt đầu từ 2, xuất kích thước của ma trận tuần hoàn một phần lớn nhất với + -1 mục và n cột có thuộc tính rằng tất cả các hàng của nó là trực giao lẫn nhau.

Ghi bàn

Điểm của bạn là cao nhất nsao cho tất cả k <= n, không ai khác đã đăng một câu trả lời đúng cao hơn bạn. Rõ ràng nếu bạn có tất cả các câu trả lời tối ưu thì bạn sẽ nhận được điểm cho bài cao nhất nbạn đăng. Tuy nhiên, ngay cả khi câu trả lời của bạn không phải là tối ưu, bạn vẫn có thể đạt được điểm nếu không ai khác có thể đánh bại nó.

Ngôn ngữ và thư viện

Bạn có thể sử dụng bất kỳ ngôn ngữ và thư viện có sẵn mà bạn thích. Nếu khả thi, sẽ tốt khi có thể chạy mã của bạn, vì vậy vui lòng bao gồm một lời giải thích đầy đủ về cách chạy / biên dịch mã của bạn trong Linux nếu có thể.

Mục hàng đầu

  • 64 bởi Mitch Schwartz trong Python

Câu trả lời:


7

Con trăn 2

Bảng lên đến n = 64, được xác minh tối ưu với lực lượng vũ phu lên đến 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

nơi 0đại diện -1. Nếu nkhông chia hết cho 4 thì m = 1là tối ưu. Được tạo bằng mã này (hoặc các biến thể nhỏ của nó) nhưng với nhiều thử nghiệm hơn cho cao hơn 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:]

Cách tiếp cận là tìm kiếm ngẫu nhiên đơn giản với leo đồi, tận dụng một mô hình được chú ý cho nhỏ n. Mô hình là để tối ưu m, nửa sau của hàng đầu tiên thường có khoảng cách chỉnh sửa nhỏ so với phủ định (bitwise) của nửa đầu. Các kết quả cho mã trên là tốt cho nhỏ nnhưng bắt đầu xấu đi không lâu sau khi lực lượng vũ phu trở nên không khả thi; Tôi sẽ rất vui khi thấy một cách tiếp cận tốt hơn.

Một số quan sát:

  • Khi nlà số lẻ, m = 1là tối ưu vì số lẻ và số âm không thể cộng thành 0. (Trực giao có nghĩa là sản phẩm chấm bằng không.)
  • Khi nào n = 4k + 2, m = 1là tối ưu bởi vì để m >= 2chúng ta cần có chính xác các n/2đảo ngược ký hiệu {(a1,a2), (a2,a3), ... (a{n-1},an), (an,a1)}và một số lượng đảo ngược ký hiệu lẻ sẽ ngụ ý a1 = -a1.
  • Sản phẩm chấm của hai hàng ijtrong một ma trận tuần hoàn được xác định bởi abs(i-j). Ví dụ, nếu row1 . row2 = 0sau đó row4 . row5 = 0. Điều này là do các cặp phần tử cho sản phẩm chấm giống nhau, chỉ được xoay.
  • Do đó, để kiểm tra tính trực giao lẫn nhau, chúng ta chỉ cần kiểm tra các hàng liên tiếp so với hàng đầu tiên.
  • Nếu chúng ta biểu diễn một hàng dưới dạng một chuỗi nhị phân 0thay cho -1, chúng ta có thể kiểm tra tính trực giao của hai hàng bằng cách lấy bitwise xor và so sánh số đếm với n/2.
  • Chúng ta có thể tùy ý sửa hai phần tử đầu tiên của hàng đầu tiên, bởi vì (1) Việc phủ định ma trận không ảnh hưởng đến việc các sản phẩm chấm có bằng 0 hay không và (2) Chúng ta biết rằng phải có ít nhất hai phần tử liền kề có cùng dấu và hai các phần tử liền kề với dấu hiệu khác nhau, vì vậy chúng ta có thể xoay để đặt cặp mong muốn ở đầu.
  • Một giải pháp (n0, m0)sẽ tự động đưa ra các giải pháp (k * n0, m0)cho tùy ý k > 1, bằng cách (lặp đi lặp lại) nối hàng đầu tiên với chính nó. Một hậu quả là chúng ta có thể dễ dàng đạt được m = 4bất kỳ số nchia nào cho 4.

Đó là điều tự nhiên khi phỏng đoán n/2là giới hạn trên chặt chẽ mkhi nào n > 4, nhưng tôi không biết điều đó sẽ được chứng minh như thế nào.


Điều rất thú vị là không có giải pháp nào với 16 hàng và 32 cột. Bạn có biết tại sao không?

@Lembik Nếu tôi có một ý tưởng, tôi sẽ viết nó trong câu trả lời.
Mitch Schwartz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.