Tấn công Collatz!


8

Thử thách này dựa trên một số phát hiện mới liên quan đến phỏng đoán Collatz và được thiết kế phần nào theo tinh thần của một dự án polymath hợp tác . Việc giải các phỏng đoán đầy đủ được các chuyên gia lý thuyết toán / số coi là cực kỳ khó khăn hoặc có thể là không thể, nhưng nhiệm vụ đơn giản này hoàn toàn có thể thực hiện được và có nhiều ví dụ về mã mẫu. Trong trường hợp tốt nhất, những hiểu biết lý thuyết mới có thể được đưa vào vấn đề dựa trên các mục nhập / sự khéo léo / sáng tạo của thí sinh.

Phát hiện mới như sau: Hãy tưởng tượng một chuỗi các số nguyên liền kề [ n1 ... n2 ] nói tổng m . Gán các số nguyên này cho một cấu trúc danh sách. Bây giờ một phiên bản tổng quát của phỏng đoán Collatz có thể tiến hành như sau. Lặp lại một trong các số nguyên m (hoặc ít hơn) trong danh sách tiếp theo dựa trên một số tiêu chí / thuật toán lựa chọn. Xóa số nguyên đó khỏi danh sách nếu nó đạt 1. Rõ ràng phỏng đoán Collatz tương đương với việc xác định liệu quá trình này luôn thành công cho tất cả các lựa chọn của n1, n2 .

Đây là xoắn, một ràng buộc bổ sung. Ở mỗi bước, thêm m lặp hiện tại trong danh sách với nhau. Sau đó xem xét hàm f (i) trong đó i là số lần lặp và f (i) là tổng số lần lặp hiện tại trong danh sách. Tìm kiếm f (i) với một thuộc tính "đẹp" cụ thể.

Toàn bộ / khái niệm tổng thể là tốt hơn / tài liệu kỹ lưỡng hơn ở đây (với nhiều ví dụ trong ruby). Phát hiện là các chiến lược / thuật toán / thuật toán khá đơn giản dẫn đến " tồn tại một cách đơn điệu" f (i) và nhiều ví dụ được đưa ra trên trang đó. Đây là một ví dụ về đầu ra đồ họa (được vẽ thông qua gnuplot):

Vì vậy, đây là thách thức: Sử dụng các biến thể trên các ví dụ hiện có hoặc ý tưởng hoàn toàn mới để xây dựng thuật toán lựa chọn dẫn đến f (i) "càng gần giảm đơn điệu càng tốt". Những người tham gia nên bao gồm một biểu đồ của f (i) trong bài nộp của họ. Các cử tri có thể bỏ phiếu dựa trên biểu đồ đó & các ý tưởng thuật toán trong mã.

Cuộc thi sẽ chỉ dựa trên n1 = 200 / n2 = 400 thông số! (tương tự trên trang mẫu.) Nhưng hy vọng các thí sinh sẽ khám phá các khu vực khác và cũng cố gắng khái quát các thuật toán của họ.

Lưu ý, một chiến thuật có thể rất hữu ích ở đây là thuật toán loại gốc hoặc thuật toán di truyền.

Có thể thảo luận tất cả điều này hơn nữa trong trò chuyện cho những người tham gia quan tâm.

Đối với một số ref, một thử thách Collegolf codatz khác: Phỏng đoán Collatz (bởi Doorknob )


5
Viết hoa xin vui lòng!
TheDoctor

1
Tại sao mọi người bỏ phiếu đóng cửa? Thật tuyệt khi có những câu hỏi không rập khuôn! Tôi vấn đề quá nhiều suy nghĩ / đọc liên quan đến việc hiểu câu hỏi?!
Mậu

2
lặp ở đây có nghĩa là "tiến tới 'lần lặp tiếp theo" trong chuỗi Collatz cho số nguyên đó "
vzn

1
Có vẻ như ví dụ bạn đã đăng sẽ khó đánh bại ... :)
apnorton

1
@vzn Tôi không thể hứa nộp bài bất cứ lúc nào sớm, vì tôi sẽ đi nghỉ vào cuối tuần này sau khi kết thúc giờ học, và mọi thứ đang rất sôi nổi. Tuy nhiên, tôi chắc chắn sẽ thử nghiệm điều này - sau tất cả, đây là một cách tiếp cận mới lạ cho một vấn đề tôi thấy rất hấp dẫn. :)
apnorton

Câu trả lời:


4

Tôi đã viết một số mã trong Python 2 để chạy các thuật toán cho thử thách này:

import matplotlib.pyplot as plt

def iterate(n):
    return n*3+1 if n%2 else n/2
def g(a):
    ##CODE GOES HERE
    return [True]*len(a)
n1=input()
n2=input()
a=range(n1,n2+1)
x=[]
y=[]
i=0
while any(j>1 for j in a):
    y.append(sum(a))
    x.append(i)
    i+=1
    b=g(a)
    for j in range(len(a)):
        if b[j]:
            a[j]=iterate(a[j])
plt.plot(x,y)
plt.show()

g(x) lấy danh sách các giá trị và trả về một danh sách các bool cho dù mỗi cái nên được thay đổi.

Điều đó bao gồm điều đầu tiên tôi đã thử, là dòng ngay sau bình luận, đó là lặp lại tất cả các giá trị trong danh sách. Tôi hiểu rồi:

Cố gắng 1

Nó trông không đơn điệu, vì vậy tôi đã thử lặp lại các giá trị sẽ làm giảm tổng, nếu có, lặp lại các giá trị sẽ tăng ít nhất:

l=len(a)
n=[iterate(i) for i in a]
less=[n[i]<a[i] for i in range(l)]
if any(less):
    return less
m=[n[i]-a[i] for i in range(l)]
return [m[i]==min(m) for i in range(l)]

Thật không may, điều đó không chấm dứt (ít nhất là cho n1=200, n2=400). Tôi đã cố gắng theo dõi các giá trị tôi đã thấy trước đây bằng cách khởi tạo c=set():

l=len(a)
n=[iterate(i) for i in a]
less=[n[i]<a[i] for i in range(l)]
if any(less):
    return less
m={i:n[i]-a[i] for i in range(l)}
r=[i for i in m if m[i]==min(m.values())]
while all([a[i] in c for i in r]) and m != {}:
    m={i:m[i] for i in m if a[i] not in c}
    r+=[i for i in m.keys() if m[i]==min(m.values())]
for i in r:
    c.add(a[i])
return [i in r for i in range(l)]

Điều đó cũng không chấm dứt.

Tôi chưa thử bất cứ điều gì khác, nhưng nếu tôi có ý tưởng mới, tôi sẽ đăng chúng ở đây.


+1 thx cho sự quan tâm của bạn và làm sống lại thử thách. Điều này không tốt cho hiệu suất nhưng dù sao bạn cũng được chấp nhận, cử chỉ nhỏ của tôi về thx :) ... những người khác cũng quan tâm, vui lòng trò chuyện về nó hoặc mời tôi trò chuyện để thảo luận thêm
vzn

2

Con trăn 3

Ý tưởng chính của tôi là thêm từng số thứ tự chuỗi Collatz vào f(i)hàm theo cách nó giảm thiểu tổng số tăng f(i). Hàm kết quả không giảm nghiêm ngặt nhưng nó có cấu trúc đẹp (theo ý kiến ​​của tôi :)). Biểu đồ thứ hai được tạo ra với khoảng thời gian dài hơn f(i)và chức năng trừng phạt hơi khác nhau. Mã trên Gist.

Collatz1 Collatz2

Khi sử dụng quy tắc (3 * n + 1) / 2 thay vì 3 * n + 1, thuật toán tạo ra một đơn điệu hoàn toàn f(i)! Tôi chắc chắn rằng sửa đổi này có thể làm cho đồ thị của vzn mượt mà hơn rất nhiều. Biểu đồ thứ hai được tạo ra với khoảng thời gian dài hơn cho f(i). Mã trên Gist.

Collatz3 Collatz4

Cả hai kết quả là tương tự cho [n,2*n]phạm vi lớn hơn .


Thứ hai là tiểu thuyết / tuyệt vời, tốt nhất bên ngoài mục cho đến nay! một sự giảm hoàn toàn đơn điệu là một cái gì đó giống như một bước đột phá! nếu bạn có thể cho thấy nó hoạt động trên các vòng lặp bắt đầu ngày càng lớn hơn theo "cách tương tự", thì đó là một ứng cử viên chiến lược bằng chứng thực tế ...!
vzn

@vzn Với một số sửa đổi hoàn toàn đơn điệu fdường như có thể đạt được. Ngay cả khi thuật toán hiện tại của tôi thất bại, vẫn có không gian đáng kể để cải thiện. Tôi sẽ để nó chạy và xem nếu nó thất bại trong một số n(hơn 200). Sự đơn điệu nghiêm ngặt mạnh mẽ hơn với phỏng đoán Collatz vì vậy tôi có thể chuyển qua điều đó ngay bây giờ. :) Các chức năng của bạn có hoạt động tốt với quy tắc (3n + 1) / 2 không? Tại sao bạn không sử dụng nó?
ngẫu nhiên

@vzn Rất nhiều ý tưởng ... Nhược điểm chính là xkcd có liên quan :). Sự giảm đơn điệu dường như giữ. Một [1,n]phạm vi có thể thú vị hơn bởi vì chúng ta cũng có thể hỏi (nếu sự đơn điệu giữ) liệu chúng ta có thể tạo một [1,n+1]bằng cách không sửa đổi [1,n]một phạm vi và thêm n+1chuỗi vào nó.
ngẫu nhiên

rất tốt để xem một số cảm hứng chia sẻ! một chiến lược bằng chứng có thể hoạt động theo cách nào đó, ví dụ như trong các "khối" có kích thước không đổi. từ các thí nghiệm trên pg được trích dẫn, các chiến lược khác nhau có xu hướng "phá vỡ" cho n lớn hơn . mô tả chi tiết hơn về thuật toán của bạn bằng từ ngữ sẽ là tuyệt vời.
vzn

fyi chuyển cái này cho ruby ​​và thực hiện một số thí nghiệm cơ bản, biểu đồ kết quả ở đây . mã dường như có một số phụ thuộc nhỏ vào chủ nghĩa không điều kiện trong loại nhưng có thể không cho n lớn hơn.
vzn
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.