Vì vậy, rõ ràng, P = NP [đã đóng]


111

SAT là vấn đề xác định xem một biểu thức boolean có thể được thực hiện đúng hay không. Ví dụ: (A) có thể được thực hiện bằng cách đặt A = TRUE, nhưng (A &&! A) không bao giờ có thể đúng. Vấn đề này được biết là NP-đầy đủ. Xem sự hài lòng của Boolean .

Nhiệm vụ của bạn là viết một chương trình cho SAT thực hiện trong thời gian đa thức, nhưng có thể không giải quyết được tất cả các trường hợp.

Đối với một số ví dụ, lý do nó không thực sự đa thức có thể là do:

  1. Có một trường hợp cạnh không rõ ràng nhưng có thời gian chạy kém
  2. Thuật toán thực sự không giải quyết được vấn đề trong một số trường hợp không mong muốn
  3. Một số tính năng của ngôn ngữ lập trình bạn đang sử dụng thực sự có thời gian chạy dài hơn bạn mong đợi một cách hợp lý
  4. Mã của bạn thực sự làm một cái gì đó hoàn toàn khác với những gì nó trông giống như nó đang làm

Bạn có thể sử dụng bất kỳ ngôn ngữ lập trình (hoặc kết hợp các ngôn ngữ) bạn muốn. Bạn không cần cung cấp bằng chứng chính thức về độ phức tạp của thuật toán, nhưng ít nhất bạn nên đưa ra lời giải thích.

Các tiêu chí chính để đánh giá phải là mức độ thuyết phục của mã.

Đây là một cuộc thi phổ biến, vì vậy câu trả lời được đánh giá cao nhất trong một tuần sẽ chiến thắng.


11
Sẽ tốt hơn nếu bạn hạn chế miền vấn đề, nếu không, bạn sẽ gọi đám mây không chắc chắn xung quanh những gì "nổi tiếng". Tại sao không chọn một vấn đề NP-hard duy nhất và tập trung vào đó? Điều đó có lợi thế là để các vấn đề khác như vậy mở ra cho các câu hỏi trong tương lai dọc theo cùng một dòng. Một số câu hỏi hẹp có thể cung cấp nhiều niềm vui và giải trí liên tục cho trang web hơn là một câu hỏi rộng.
Jonathan Van Matre 17/03/2016

9
@ gnasher729: Tôi có trình biên dịch C # để giải quyết vấn đề SAT; Tôi coi đó là một thành tích hợp lý thú vị.
Eric Lippert

9
Sẽ rất vui nếu ai đó vô tình giải SAT trong thời gian đa thức ở đây.
Turion

5
@Turion nhiều thập kỷ nghiên cứu, hàng triệu phần thưởng và giải thưởng và tất cả những người phụ nữ và danh tiếng có thể có - nhưng động lực thực sự để giải quyết P = NP sẽ kết thúc là thử thách PCG này.
NothingsImpossible

3
Tôi đang bỏ phiếu để đóng câu hỏi này ngoài chủ đề vì những thách thức ngầm không còn được chào đón trên trang web này. meta.codegolf.stackexchange.com/a/8326/20469
mèo

Câu trả lời:


236

C #

Nhiệm vụ của bạn là viết một chương trình cho SAT dường như thực hiện trong thời gian đa thức.

"Xuất hiện" là không cần thiết. Tôi có thể viết một chương trình thực sự thực hiện trong thời gian đa thức để giải các bài toán SAT. Điều này khá đơn giản trong thực tế.

TIỀN THƯỞNG MEGA: Nếu bạn viết một bộ giải SAT thực sự thực hiện trong thời gian đa thức, bạn sẽ nhận được một triệu đô la! Nhưng dù sao hãy sử dụng thẻ spoiler, để người khác có thể tự hỏi về nó.

Tuyệt vời. Xin vui lòng gửi cho tôi hàng triệu đô la. Nghiêm túc mà nói, tôi có một chương trình ngay tại đây sẽ giải quyết SAT với thời gian chạy đa thức.

Hãy để tôi bắt đầu bằng cách nói rằng tôi sẽ giải quyết một biến thể của vấn đề SAT. Tôi sẽ trình bày cách viết một chương trình thể hiện giải pháp duy nhất cho bất kỳ vấn đề 3-SAT nào . Việc định giá từng biến Boolean phải là duy nhất để bộ giải của tôi hoạt động.

Chúng tôi bắt đầu bằng cách khai báo một vài phương thức và kiểu trợ giúp đơn giản:

class MainClass
{
    class T { }
    class F { }
    delegate void DT(T t);
    delegate void DF(F f);
    static void M(string name, DT dt)
    {
        System.Console.WriteLine(name + ": true");
        dt(new T());
    }
    static void M(string name, DF df)
    {
        System.Console.WriteLine(name + ": false");
        df(new F());
    }
    static T Or(T a1, T a2, T a3) { return new T(); }
    static T Or(T a1, T a2, F a3) { return new T(); }
    static T Or(T a1, F a2, T a3) { return new T(); }
    static T Or(T a1, F a2, F a3) { return new T(); }
    static T Or(F a1, T a2, T a3) { return new T(); }
    static T Or(F a1, T a2, F a3) { return new T(); }
    static T Or(F a1, F a2, T a3) { return new T(); }
    static F Or(F a1, F a2, F a3) { return new F(); }
    static T And(T a1, T a2) { return new T(); }
    static F And(T a1, F a2) { return new F(); }
    static F And(F a1, T a2) { return new F(); }
    static F And(F a1, F a2) { return new F(); }
    static F Not(T a) { return new F(); }
    static T Not(F a) { return new T(); }
    static void MustBeT(T t) { }

Bây giờ hãy chọn một bài toán 3-SAT để giải. Hãy cùng nói nào

(!x3) & 
(!x1) & 
(x1 | x2 | x1) & 
(x2 | x3 | x2)

Hãy ngoặc đơn hơn một chút.

(!x3) & (
    (!x1) & (
        (x1 | x2 | x1) & 
        (x2 | x3 | x2)))

Chúng tôi mã hóa như thế này:

static void Main()
{
    M("x1", x1 => M("x2", x2 => M("x3", x3 => MustBeT(
      And(
        Not(x3),
        And(
          Not(x1),
          And(
            Or(x1, x2, x1),
            Or(x2, x3, x2))))))));
}

Và chắc chắn khi chúng tôi chạy chương trình, chúng tôi có được giải pháp cho 3-SAT trong thời gian đa thức. Trong thực tế thời gian chạy là tuyến tính trong kích thước của vấn đề !

x1: false
x2: true
x3: false

Bạn nói thời gian chạy đa thức . Bạn không nói gì về thời gian biên dịch đa thức . Chương trình này buộc trình biên dịch C # thử tất cả các kết hợp loại có thể cho x1, x2 và x3 và chọn một trình kết hợp duy nhất không có lỗi loại. Trình biên dịch thực hiện tất cả các công việc, vì vậy thời gian chạy không phải làm. Lần đầu tiên tôi trưng bày công nghệ thú vị này trên blog của mình vào năm 2007: http://bloss.msdn.com/b/ericlippert/archive/2007/03/11/lambda-expressions-vs-anonymous-methods-part-five.aspx Lưu ý tất nhiên ví dụ này cho thấy độ phân giải quá tải trong C # ít nhất là NP-HARD. Cho dù đó là NP-HARD hay thực sự không thể giải quyết được phụ thuộc vào một số chi tiết tinh tế nhất định trong cách thức chuyển đổi loại hoạt động với sự hiện diện của chống chỉ định chung, nhưng đó là một chủ đề cho một ngày khác.


95
Bạn sẽ phải liên hệ với viện toán học đất sét để kiếm được hàng triệu đô la. Nhưng tôi không chắc họ sẽ hài lòng .
Jonathan Pullano 17/03/2016

15
Tất nhiên bất kỳ vấn đề SAT nào cũng có thể được chuyển thành vấn đề 3-SAT tương đương, vì vậy hạn chế này chỉ là một sự bất tiện. Vấn đề khó chịu hơn với "giải pháp" của tôi là nó đòi hỏi vấn đề phải có một giải pháp duy nhất . Nếu không có giải pháp hoặc nhiều hơn một giải pháp thì trình biên dịch sẽ báo lỗi.
Eric Lippert

11
@EricLippert yêu cầu duy nhất là ok. Bạn luôn có thể giảm SAT thành Unique-SAT (SAT nhưng giả sử các đầu vào có 0 hoặc 1 bài tập) bằng cách sử dụng giảm ngẫu nhiên thời gian đa thức. Từ khóa: Bổ đề cô lập, định lý Valiant-Vazirani.
Diego de Estrada

44
"Nghiêm túc mà nói, tôi có một chương trình ngay tại đây sẽ giải quyết SAT với thời gian chạy đa thức." - tôi cũng vậy, nhưng tiếc là nó không vừa trong hộp bình luận này.
CompuChip

11
@Kobi: Vâng, đó là trò đùa.
Eric Lippert

166

Đa ngôn ngữ (1 byte)

Chương trình sau đây, hợp lệ trong nhiều ngôn ngữ, chủ yếu là chức năng và bí truyền, sẽ đưa ra câu trả lời chính xác cho một số lượng lớn các vấn đề SAT và có độ phức tạp không đổi (!!!):

0

Thật ngạc nhiên, chương trình tiếp theo sẽ đưa ra câu trả lời chính xác cho tất cả các vấn đề còn lại, và có cùng độ phức tạp. Vì vậy, bạn chỉ cần chọn đúng chương trình và bạn sẽ có câu trả lời đúng trong mọi trường hợp!

1

6
Thật đáng kinh ngạc. Tôi đã có một tiếng cười tốt.
Karl Damgaard Asmussen

2
Hoàn toàn f ****** rực rỡ!
Con chó màu xanh

78
Hừm. Bây giờ thì dễ rồi. Tất cả những gì tôi cần làm là viết một chương trình sẽ chọn đúng chương trình!
Cruncher

Đúng ! :-)
Mậu

6
Gợi nhớ về xkcd.com/221 .
msh210

34

JavaScript

Bằng cách sử dụng phép lặp không xác định, SAT có thể được giải trong thời gian đa thức!

function isSatisfiable(bools, expr) {
    function verify() {
        var values = {};
        for(var i = 0; i < bools.length; i++) {
            values[bools[i]] = nonDeterministicValue();
        }
        with(values) {
            return eval(expr);
        }
    }
    function nonDeterministicValue() {
        return Math.random() < 0.5 ? !0 : !1;
    }

    for(var i = 0; i < 1000; i++) {
        if(verify(bools, expr)) return true;
    }
    return false;
}

Ví dụ sử dụng:

isSatisfiable(["a", "b"], "a && !a || b && !b") //returns 'false'

Thuật toán này chỉ kiểm tra công thức boolean đã cho một nghìn lần với các đầu vào ngẫu nhiên. Hầu như luôn luôn hoạt động cho các đầu vào nhỏ, nhưng ít đáng tin cậy hơn khi có nhiều biến được đưa vào.

Nhân tiện, tôi tự hào rằng tôi đã có cơ hội sử dụng hai trong số các tính năng được sử dụng nhiều nhất của JavaScript ngay cạnh nhau: evalwith.


4
Đây thực sự là một phương pháp thử nghiệm được thiết lập tốt. Thư viện QuickCheck của Haskell bắt đầu tất cả những niềm vui, tôi tin. Nó đã được áp dụng lại trong nhiều ngôn ngữ.
John Tyree

4
Tôi nghĩ cần lưu ý rằng, chương trình này ít có khả năng trả về câu trả lời đúng, biểu thức sat càng lớn. Các 1000trong vòng lặp for bằng cách nào đó nên quy mô với kích thước đầu vào (một số đa thức phi-O (1) mở rộng quy mô).
Cruncher

2
@Cruncher Để chính xác hơn, số lượng biến càng lớn thì càng ít có khả năng trả về câu trả lời đúng. (ví dụ: một biểu thức rất dài với một biến duy nhất sẽ luôn trả về câu trả lời đúng)
Peter Olson

2
@TimSeguine Tôi thừa nhận rằng việc tôi sử dụng từ "không điều kiện" trong bối cảnh này là không rõ ràng, giống như tuyên bố rằng SAT có thể được giải quyết trong thời gian đa thức. Tôi biết điều đó không đúng, nó chỉ là một phần của trò chơi lừa dối.
Peter Olson

4
@PaulDraper và sau đó gọi họ sử dụng! Tôi đã có một tiếng cười vui vẻ!
Rob

32

Toán học + Máy tính lượng tử

Bạn có thể không biết rằng Mathicala đi kèm với máy tính lượng tử trên tàu

Needs["Quantum`Computing`"];

Truyền thông lượng tử lượng tử mã hóa một vấn đề cần giải quyết ở Hamilton (toán tử năng lượng) theo cách mà trạng thái năng lượng tối thiểu của nó ("trạng thái cơ bản") thể hiện giải pháp. Do đó, sự tiến hóa đáng tin cậy của một hệ lượng tử đến trạng thái cơ bản của Hamilton và phép đo tiếp theo đưa ra giải pháp cho vấn đề.

Chúng tôi định nghĩa một subhamiltonian tương ứng với ||các phần của biểu thức, với sự kết hợp thích hợp của các toán tử Pauli cho các biến và phủ định của nó

nhập mô tả hình ảnh ở đây

Nơi để biểu hiện như thế này

expr = (! x3) && (! x1) && (x1 || x2 || x1) && (x2 || x3 || x2);

đối số sẽ giống như

{{{1, x3}}, {{1, x1}}, {{0, x1}, {0, x2}, {0, x1}}, {{0, x2}, {0, x3}, {0, x2}}}

Đây là mã để xây dựng đối số như vậy từ biểu thức bool:

arg = expr /. {And -> List, Or -> List, x_Symbol :> {0, x}, 
    Not[x_Symbol] :> {1, x}};
If[Depth[arg] == 3, arg = {arg}];
arg = If[Depth[#] == 2, {#}, #] & /@ arg

Bây giờ chúng tôi xây dựng một Hamiltonian đầy đủ, tóm tắt các subhamiltonian (tổng kết tương ứng với &&các phần của biểu thức)

H = h /@ arg /. List -> Plus;

Và tìm trạng thái năng lượng thấp nhất

QuantumEigensystemForm[H, -1]

nhập mô tả hình ảnh ở đây

Nếu chúng ta có một giá trị riêng bằng 0, thì hàm riêng là giải pháp

expr /. {x1 -> False, x2 -> True, x3 -> False}
> True

Thật không may, trang web chính thức cho tiện ích bổ sung "Điện toán lượng tử" không hoạt động và tôi không thể tìm thấy nơi để tải xuống, tôi vẫn cài đặt nó trên máy tính của mình. Bổ trợ cũng có một giải pháp được ghi lại cho vấn đề SAT, dựa vào đó tôi dựa vào mã của mình.


19
Tôi không biết làm thế nào câu trả lời này hoạt động. +1
Jonathan Pullano

5
@XiaogeSu "Đương nhiên".
swish

3
@XiaogeSu Sự tiến hóa được xác định bởi người Hamilton, và tự nhiên nó phát triển đến mức năng lượng thấp nhất. Vì vậy, biết phổ, chúng ta có thể giả định rằng hệ thống sẽ kết thúc ở trạng thái cơ bản.
swish

3
@XiaogeSu để đi đến trạng thái cơ bản, người ta cũng cần phải có sự tương tác với môi trường làm suy yếu các trạng thái cao hơn, bạn đã đúng. Ý tưởng ở đây là sự tương tác này rất nhỏ, "đáng tin cậy".
Turion

3
fyi tính toán QM điện toán có rất nhiều điểm tương đồng với ủ mô phỏng cổ điển . hiện được thực hiện bởi Dwave . nó tương tự như một hệ thống nhiệt độ / năng lượng "làm mát" "tìm / lắng" trong cực tiểu địa phương .
vzn

27

Ba cách tiếp cận ở đây, tất cả đều liên quan đến việc giảm SAT thành lingua franca hình học 2D của nó: câu đố logic phi hình. Các ô trong câu đố logic tương ứng với các biến SAT, các ràng buộc đối với các mệnh đề.

Để được giải thích đầy đủ (và để vui lòng xem lại mã của tôi về các lỗi!) Tôi đã đăng một số thông tin chi tiết về các mẫu trong không gian giải pháp không biểu đồ. Xem https://codereview.stackexchange.com/questions/43770/nonogram-puheads-solution-space. Việc liệt kê> 4 tỷ giải pháp câu đố và mã hóa chúng để phù hợp với một bảng chân lý cho thấy các mô hình fractal - tự tương tự và đặc biệt là tự ái. Sự dư thừa affine này thể hiện cấu trúc trong vấn đề, có thể khai thác để giảm các tài nguyên tính toán cần thiết để tạo ra các giải pháp. Nó cũng cho thấy sự cần thiết cho phản hồi hỗn loạn trong bất kỳ thuật toán thành công nào. Có khả năng giải thích trong hành vi chuyển pha trong đó các trường hợp "dễ" là những trường hợp nằm dọc theo cấu trúc thô, trong khi các trường hợp "cứng" đòi hỏi lặp lại thành chi tiết tốt, khá ẩn so với các heuristic thông thường. Nếu bạn muốn phóng to vào góc của hình ảnh vô tận này (tất cả <= phiên bản câu đố 4 x 4 được mã hóa), hãy xem http://re-curse.github.io/visualizing-intractability/nonograms_zoom/nonograms.html

Phương pháp 1. Ngoại suy bóng không gian giải pháp phi hình ảnh bằng cách sử dụng bản đồ hỗn loạn và học máy (nghĩ rằng các chức năng phù hợp tương tự như các chức năng tạo Tập hợp Mandelbrot).

http://i.stack.imgur.com/X7SbP.png

Dưới đây là một bằng chứng trực quan của cảm ứng. Nếu bạn có thể quét bốn hình ảnh này từ trái sang phải và nghĩ rằng bạn có ý tưởng tốt để tạo ra hình ảnh thứ 5 ... 6 ... vv, thì tôi đã lập trình cho bạn như là một tiên tri NP của tôi cho vấn đề quyết định của giải pháp phi hình sự tồn tại Hãy bước ra để nhận giải thưởng của bạn là siêu máy tính mạnh nhất thế giới. Tôi sẽ cung cấp cho bạn các nhóm điện mỗi giờ và sau đó trong khi thế giới cảm ơn bạn vì những đóng góp tính toán của bạn.

Phương pháp 2. Sử dụng Biến đổi Fourier trên phiên bản hình ảnh boolean của đầu vào. FFT cung cấp thông tin toàn cầu về tần suất và vị trí trong một thể hiện. Mặc dù phần cường độ phải giống nhau giữa cặp đầu vào, thông tin pha của chúng hoàn toàn khác nhau - chứa thông tin định hướng về phép chiếu giải pháp dọc theo một trục cụ thể. Nếu bạn đủ thông minh, bạn có thể tái tạo lại hình ảnh pha của giải pháp thông qua sự chồng chất đặc biệt của hình ảnh pha đầu vào. Sau đó nghịch đảo biến đổi pha và cường độ chung trở lại miền thời gian của giải pháp.

Phương pháp này có thể giải thích gì? Có nhiều hoán vị của các hình ảnh boolean với phần đệm linh hoạt giữa các lần chạy liền kề. Điều này cho phép ánh xạ giữa đầu vào -> giải pháp đảm bảo tính đa bội trong khi vẫn giữ lại thuộc tính của FFT đối với ánh xạ hai chiều, duy nhất giữa miền thời gian <-> (tần số, pha). Điều đó cũng có nghĩa là không có thứ gọi là "không có giải pháp." Những gì nó sẽ nói là trong một trường hợp liên tục, có những giải pháp thang độ xám mà bạn không xem xét khi nhìn vào hình ảnh hai góc của giải câu đố phi chữ truyền thống.

Tại sao bạn không làm điều đó? Đó là một cách khủng khiếp để thực sự tính toán, vì các FFT trong thế giới dấu phẩy động ngày nay sẽ rất thiếu chính xác với các trường hợp lớn. Độ chính xác là một vấn đề lớn và việc tái tạo hình ảnh từ cường độ và hình ảnh pha được lượng tử hóa thường tạo ra các giải pháp rất gần đúng, mặc dù có thể không trực quan cho ngưỡng mắt của con người. Cũng rất khó để đến với doanh nghiệp chồng chất này, vì loại chức năng thực sự làm nó hiện chưa được biết. Nó sẽ là một sơ đồ trung bình đơn giản? Có lẽ là không, và không có phương pháp tìm kiếm cụ thể để tìm thấy nó ngoại trừ trực giác.

Phương pháp 3. Tìm quy tắc automata di động (trong số ~ 4 tỷ bảng quy tắc có thể có cho quy tắc 2 trạng thái von Neumann) để giải quyết một phiên bản đối xứng của câu đố không hình. Bạn sử dụng nhúng trực tiếp vấn đề vào các ô, hiển thị ở đây. Bảo tồn, không đối xứng

Đây có lẽ là phương pháp thanh lịch nhất, về mặt đơn giản và hiệu ứng tốt cho tương lai của máy tính. Sự tồn tại của quy tắc này không được chứng minh, nhưng tôi có linh cảm nó tồn tại. Đây là lý do tại sao:

Nonograms yêu cầu rất nhiều phản hồi hỗn loạn trong thuật toán để được giải quyết chính xác. Điều này được thiết lập bởi mã lực lượng vũ phu được liên kết đến trên Xem lại mã. CA chỉ là về ngôn ngữ có khả năng nhất để lập trình phản hồi hỗn loạn.

Nó có vẻ đúng, trực quan. Quy tắc sẽ phát triển thông qua việc nhúng, đưa thông tin theo chiều ngang và chiều dọc, can thiệp, sau đó ổn định thành một giải pháp bảo tồn số lượng ô đặt. Tuyến đường di chuyển này đi theo con đường (ngược) mà bạn thường nghĩ đến khi chiếu bóng của một đối tượng vật lý vào cấu hình ban đầu. Nonograms xuất phát từ một trường hợp đặc biệt của chụp cắt lớp rời rạc, vì vậy hãy tưởng tượng ngồi đồng thời trong hai máy quét CT góc mèo .. đây là cách tia X sẽ chiếu vào để tạo ra hình ảnh y tế. Tất nhiên, có những vấn đề về ranh giới - các cạnh của vũ trụ CA không thể tiếp tục đưa thông tin vượt quá giới hạn, trừ khi bạn cho phép một vũ trụ hình xuyến. Điều này cũng đưa ra câu đố như một vấn đề giá trị biên định kỳ.

Nó giải thích nhiều giải pháp là trạng thái nhất thời trong hiệu ứng dao động liên tục giữa các đầu ra hoán đổi làm đầu vào và ngược lại. Nó giải thích các trường hợp không có giải pháp như các cấu hình ban đầu không bảo tồn số lượng ô được đặt. Tùy thuộc vào kết quả thực tế của việc tìm ra quy tắc như vậy, nó thậm chí có thể xấp xỉ các trường hợp không thể giải quyết được với một giải pháp chặt chẽ trong đó các trạng thái tế bào được bảo tồn.


2
+1 vì đã để tôi nói "tại sao tôi không nghĩ về điều đó?" : P
Navin

Bạn là Stephen Wolfram và tôi yêu cầu năm bảng của tôi!
Quuxplusone

4
Câu trả lời này thực sự xứng đáng nhận được nhiều tín dụng hơn, vì đó là nỗ lực tốt nhất để thực hiện một chương trình thuyết phục . Chương trinh hay.
Jonathan Pullano

10

C ++

Đây là một giải pháp được đảm bảo để chạy trong thời gian đa thức: nó chạy ở O(n^k)đâu nlà số lượng booleans và klà hằng số bạn chọn.

Đó là chính xác về mặt heurist, mà tôi tin là CS-speak vì "nó cho câu trả lời chính xác hầu hết thời gian, với một chút may mắn" (và trong trường hợp này, một giá trị lớn phù hợp k- chỉnh sửa nó thực sự xảy ra với tôi rằng đối với bất kỳ cố định nào nbạn có thể đặt knhư vậy n^k > 2^n- đó có phải là gian lận không?).

#include <iostream>  
#include <cstdlib>   
#include <time.h>    
#include <cmath>     
#include <vector>    

using std::cout;     
using std::endl;     
typedef std::vector<bool> zork;

// INPUT HERE:

const int n = 3; // Number of bits
const int k = 4; // Runtime order O(n^k)

bool input_expression(const zork& x)
{
  return 
  (!x[2]) && (
    (!x[0]) && (
      (x[0] || x[1] || x[0]) &&
      (x[1] || x[2] || x[1])));
}

// MAGIC HAPPENS BELOW:    

 void whatever_you_do(const zork& minefield)
;void always_bring_a_towel(int value, zork* minefield);

int main()
{
  const int forty_two = (int)pow(2, n) + 1;
  int edition = (int)pow(n, k);
  srand(time(6["times7"]));

  zork dont_panic(n);
  while(--edition)
  {
    int sperm_whale = rand() % forty_two;
    always_bring_a_towel(sperm_whale, &dont_panic);

    if(input_expression(dont_panic))
    {
      cout << "Satisfiable: " << endl;
      whatever_you_do(dont_panic);
      return 0;
    }
  }

  cout << "Not satisfiable?" << endl;
  return 0;
}
void always_bring_a_towel(int value, zork* minefield)
{
  for(int j = 0; j < n; ++j, value >>= 1)
  {
    (*minefield)[j] = (value & 1);
  }
}

void whatever_you_do(const zork& minefield)
{
  for(int j = 0; j < n; ++j) 
  {
    cout << (char)('A' + j) << " = " << minefield[j] << endl;
  }
}

Câu trả lời tốt. Tôi sẽ đặt lời giải thích trong một thẻ spoiler để mọi người có thể nhìn chằm chằm vào nó và gãi đầu một chút.
Jonathan Pullano

Cảm ơn lời đề nghị @JonathanPullano, tôi đã thêm thẻ spoiler và làm xáo trộn mã một chút.
CompuChip

Nhân tiện, tôi chỉ mới phát hiện ra bitfield, có lẽ tôi sẽ thích điều đó hơn std::vector.
CompuChip

3
+1 cho các tham chiếu obfuscation và hitchhiker sáng tạo
Blake Miller

2
Có tất nhiên đó là gian lận, nếu k phụ thuộc vào n thì đó không phải là một hằng số :-)
RemcoGerlich

3

bề mặt 3d ruby ​​/ gnuplot

(ooh cạnh tranh gay gắt!) ... dù sao ... là một bức tranh đáng giá ngàn lời nói? đây là 3 ô bề mặt riêng biệt được tạo ra trong gnuplot của điểm chuyển tiếp SAT. các trục (x, y) là mệnh đề & số lượng biến và chiều cao z là tổng số # của các cuộc gọi đệ quy trong bộ giải. mã viết bằng ruby. nó lấy mẫu 10,10 điểm tại 100 mẫu mỗi mẫu. nó thể hiện / sử dụng các nguyên tắc thống kê cơ bản và là mô phỏng Monte Carlo .

về cơ bản, thuật toán davis putnam chạy trên các trường hợp ngẫu nhiên được tạo ở định dạng DIMACS. đây là loại tập thể dục mà lý tưởng sẽ được thực hiện trong lớp học CS trên toàn thế giới vì vậy sinh viên có thể tìm hiểu những điều cơ bản nhưng hầu như không được dạy đặc biệt ở tất cả ... có lẽ một số lý do tại sao có rất nhiều giả P = NP chứng minh ? thậm chí không có một bài viết hay trên wikipedia mô tả hiện tượng điểm chuyển tiếp (có ai thực hiện không?) là một chủ đề rất nổi bật trong vật lý thống kê & cũng là chìa khóa trong CS. [a] [b] có nhiều bài báo về CS về điểm chuyển tiếp tuy nhiên rất ít dường như hiển thị các lô bề mặt! (thay vào đó thường hiển thị các lát 2d.)

sự gia tăng theo cấp số nhân trong thời gian chạy được thể hiện rõ ràng trong âm mưu thứ 1 . yên xe chạy qua giữa ô thứ 1 là điểm chuyển tiếp. 2 nd và 3 thứ lô hiển thị quá trình chuyển đổi satisfiable%.

[a] hành vi chuyển pha trong CS ppt Toby Walsh
[b] xác suất theo kinh nghiệm của tcs.se
[c] những khoảnh khắc tuyệt vời trong toán học thực nghiệm / toán học / (T) CS / SAT , blog TMachine

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

P =? NP QED!

#!/usr/bin/ruby1.8

def makeformula(clauses)
    (1..clauses).map \
    {
            vars2 = $vars.dup
            (1..3).map { vars2.delete_at(rand(vars2.size)) * [-1, 1][rand(2)] }.sort_by { |x| x.abs }
    }

end

def solve(vars, formula, assign)

    $counter += 1
    vars2 = []
    formula.each { |x| vars2 |= x.map { |y| y.abs } }
    vars &= vars2

    return [false] if (vars.empty?)
    v = vars.shift
    [v, -v].each \
    {
            |v2|
            f2 = formula.map { |x| x.dup }
            f2.delete_if \
            {
                    |x|
                    x.delete(-v2)
                    return [false] if (x.empty?)
                    x.member?(v2)
            }
            return [true, assign + [v2]] if (f2.empty?)
            soln = solve(vars.dup, f2, assign + [v2])
            return soln if (soln[0])
    }
    return [false]
end

def solve2(formula)
    $counter = 0
    soln = solve($vars.dup, formula, [])
    return [$counter, {false => 0, true => 1}[soln[0]]]
end


c1 = 10
c2 = 100
nlo, nhi = [3, 10]
mlo, mhi = [1, 50]
c1.times \
{
    |n|
    c1.times \
    {
            |m|
            p1 = nlo + n.to_f / c1 * (nhi - nlo)
            p2 = mlo + m.to_f / c1 * (mhi - mlo)
            $vars = (1..p1.to_i).to_a
            z1 = 0
            z2 = 0
            c2.times \
            {
                    f = makeformula(p2.to_i)
                    x = solve2(f.dup)
                    z1 += x[0]
                    z2 += x[1]
            }
#           p([p1, p2, z1.to_f / c2, z2.to_f / c2]) # raw
#           p(z1.to_f / c2)                         # fig1
#           p(0.5 - (z2.to_f / c2 - 0.5).abs)       # fig2
            p(z2.to_f / c2)                         # fig3
    }
    puts
}

2
Tôi rất vui vì bạn đã đóng góp câu trả lời này. Trong bất kỳ bằng chứng thành công nào của P so với NP (một trong hai cách), đó là một trong nhiều yêu cầu đối với sức mạnh dự đoán. Cảm ơn đã chỉ ra tầm quan trọng của nó. :)

nhiều suy nghĩ hơn về P vs NP , nhiều lượt giới thiệu hàng đầu / được thu thập, v.v.
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.