따라서 P = NP [닫힘]


111

SAT는 부울 식을 적용 할 수 있는지 여부를 결정하는 문제입니다. 예를 들어, A = TRUE를 설정하여 (A)를 적용 할 수 있지만 (A &&! A)는 절대 적용 할 수 없습니다. 이 문제는 NP- 완전한 것으로 알려져 있습니다. 부울 만족도를 참조하십시오 .

당신의 임무는 다항식 시간에 실행하지만 모든 경우를 해결하지 못할 수있는 SAT를위한 프로그램을 작성하는 것입니다.

일부 예에서 실제로 다항식 이 아닌 이유는 다음과 같습니다.

  1. 명확하지 않지만 런타임이 나쁜 경우가 있습니다.
  2. 알고리즘은 실제로 예기치 않은 경우 문제를 해결하지 못합니다.
  3. 사용중인 프로그래밍 언어의 일부 기능은 실제로 예상보다 더 긴 런타임을 갖습니다.
  4. 실제로 코드는 실제 동작과 완전히 다른 것을 수행합니다.

원하는 프로그래밍 언어 (또는 언어 조합)를 사용할 수 있습니다. 알고리즘의 복잡성을 공식적으로 증명할 필요는 없지만 최소한 설명을 제공해야합니다.

판단의 기본 기준은 코드의 확신을 높이는 것입니다.

이것은 인기 경연 대회이므로 일주일 만에 가장 높은 등급의 답변이 이깁니다.


11
문제 영역 제한하면 더 잘 될 것입니다 . 그렇지 않으면 "잘 알려진"영역에 대해 불확실성의 구름을 불러옵니다. 하나의 NP-hard 문제를 골라 그 문제에 집중하지 않겠습니까? 그것은 다른 문제들을 같은 줄을 따라 미래의 질문에 공개하는 이점이 있습니다. 몇 가지 좁은 질문은 하나의 광범위한 질문보다 훨씬 더 지속적인 즐거움과 오락을 사이트에 제공 할 수 있습니다.
Jonathan Van Matre

9
@ gnasher729 : SAT 문제를 해결하기 위해 C # 컴파일러 가 있습니다. 나는 그것이 합리적으로 흥미로운 업적이라고 생각합니다.
Eric Lippert

9
누군가가 실수로 다항식 시간에 SAT를 풀면 재미있을 것입니다.
Turion

5
@Turion 수십 년의 연구, 수백만의 보상 및 상금 및 모든 여성과 명성이 가질 수는 있지만 P = NP를 해결하기위한 진정한 동기는 결국 PCG 도전 과제가 될 것입니다.
NothingsImossible

3
이 사이트에서는 미숙 한 도전이 더 이상 환영받지 않기 때문에이 질문을 주 제외로 마무리하려고합니다. meta.codegolf.stackexchange.com/a/8326/20469
cat

답변:


236

씨#

당신의 임무는 다항식 시간에 실행되는 것처럼 보이는 SAT를위한 프로그램을 작성하는 것입니다.

"표시"는 필요하지 않습니다. SAT 문제를 해결하기 위해 다항식으로 실제로 실행되는 프로그램을 작성할 수 있습니다. 실제로 이것은 매우 간단합니다.

MEGA BONUS : 실제로 다항식 시간에 실행되는 SAT 솔버를 작성하면 백만 달러를받습니다! 어쨌든 다른 사람들이 궁금해 할 수 있도록 스포일러 태그를 사용하십시오.

대박. 백만 달러를 보내주세요. 진지하게, 나는 여기에 다항식 런타임으로 SAT를 해결할 프로그램이 있습니다.

SAT 문제에 대한 변형을 해결하겠다고 말하면서 시작하겠습니다. 3-SAT 문제의 고유 한 솔루션보여주는 프로그램을 작성하는 방법을 보여 드리겠습니다 . 각 부울 변수의 평가는 솔버가 작동 하도록 고유 해야합니다.

우리는 몇 가지 간단한 도우미 메서드와 형식을 선언하여 시작합니다.

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) { }

이제 해결하기 위해 3-SAT 문제를 선택해 봅시다. 의 말을하자

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

좀 더 괄호로 묶어 봅시다.

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

우리는 이것을 다음과 같이 인코딩합니다 :

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))))))));
}

그리고 프로그램을 실행할 때 충분히, 우리는 다항식 시간에 3-SAT에 대한 솔루션을 얻습니다. 실제로 런타임은 문제의 크기선형입니다 !

x1: false
x2: true
x3: false

당신은 다항식 런타임을 말했다 . 다항식 컴파일 시간 에 대해서는 아무 말도하지 않았습니다 . 이 프로그램은 C # 컴파일러가 x1, x2 및 x3에 대해 가능한 모든 유형 조합을 시도하고 유형 오류가없는 고유 한 유형 조합을 선택하도록합니다. 컴파일러는 모든 작업을 수행하므로 런타임이 필요하지 않습니다. 내가 처음 2007 년에 내 블로그에 흥미로운 techinque을 전시 : http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx 주 물론이 예는 C #의 과부하 해상도가 적어도 NP-HARD임을 보여줍니다. 그것이 NP-HARD인지 실제로 결정할 수 없는지 일반적인 반동이 존재하는 경우 유형 변환이 작동하는 방식에 대한 미묘한 세부 사항에 따라 다르지만 이는 또 다른 날의 주제입니다.


95
백만 달러에 대해서는 점토 수학 연구소에 연락해야합니다. 그러나 나는 그들이 만족할 것이라고 확신하지 못한다 .
Jonathan Pullano

15
물론 모든 SAT 문제는 동등한 3-SAT 문제로 변환 될 수 있으므로이 제한은 단지 불편합니다. 내 "솔루션"에 대한 더 심각한 문제는 문제에 고유 한 솔루션 이 필요하다는 것입니다. 솔루션이 없거나 둘 이상의 솔루션 인 경우 컴파일러에서 오류가 발생합니다.
Eric Lippert

11
@EricLippert 고유성 요구 사항은 괜찮습니다. 다항식 시간 랜덤 감소를 사용하여 항상 SAT를 Unique-SAT (SAT이지만 입력에 0 또는 1 할당이 있다고 가정)로 줄일 수 있습니다. 키워드 : 격리 Lemma, Valiant-Vazirani 정리.
Diego de Estrada

44
"정말로, 다항식 런타임으로 SAT를 해결하는 프로그램이 있습니다." -나도 불행히도이 의견 상자에 맞지 않습니다.
CompuChip

11
@ Kobi : 네, 농담입니다.
Eric Lippert

166

다국어 (1 바이트)

대부분의 기능적이고 난해한 많은 언어로 유효한 다음 프로그램은 많은 SAT 문제에 대한 정답을 제공하고 지속적으로 복잡합니다 (!!!) :

0

놀랍게도, 다음 프로그램은 남아있는 모든 문제에 대한 정답을 제공 할 것이며 동일한 복잡성을가집니다. 따라서 올바른 프로그램을 선택하기 만하면 모든 경우에 정답이됩니다!

1

6
이것은 놀랍다. 나는 나 자신에게 좋은 웃음을 가지고 있었다.
Karl Damgaard Asmussen

2
절대적으로 f ****** 훌륭합니다!
The Blue Dog

78
흠. 지금은 쉽습니다. 내가해야 할 일은 올바른 프로그램을 선택할 수있는 프로그램을 작성하는 것입니다!
Cruncher

정확하게! :-)
Mau

6
xkcd.com/221을 연상시키는 .
msh210

34

자바 스크립트

반복 된 비결정론을 사용하여 다항식 시간에 SAT를 해결할 수 있습니다!

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;
}

사용법 예 :

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

이 알고리즘은 임의의 입력으로 주어진 부울 수식을 천 번 확인합니다. 거의 항상 작은 입력에 대해 작동하지만 더 많은 변수가 도입되면 안정성이 떨어집니다.

그런데, 나는 바로 옆에 서로 자바 스크립트의 가장 과소 기능 두 가지를 활용할 수있는 기회를 가지고 있음을 자랑스럽게 생각합니다 : evalwith.


4
이것은 실제로 잘 확립 된 테스트 방법입니다. Haskell의 QuickCheck 라이브러리는 모든 재미를 시작했습니다. 그 이후 많은 언어로 다시 구현되었습니다.
John Tyree

4
나는이 프로그램이 정답을 반환 할 가능성이 적고, sat 표현이 클수록 유의해야한다고 생각합니다. 1000에 든 입력 크기 (어떤 다항식이 아닌 O (1) 스케일링)으로 확장한다 for 루프.
Cruncher

2
@Cruncher보다 정확하게, 변수의 수가 많을수록 정답을 반환 할 가능성이 줄어 듭니다. (예 : 단일 변수를 가진 매우 긴 표현식은 거의 항상 정답을 반환합니다)
Peter Olson

2
@TimSeguine 저는이 맥락에서 "비결정론 적"이라는 단어를 사용하는 것이 SAT가 다항식 시간에 해결 될 수 있다는 주장과 마찬가지로 최선의 모호함을 인정합니다. 나는 그것이 옳지 않다는 것을 알고 있습니다. 그것은기만 게임의 일부일뿐입니다.
피터 올슨

4
@PaulDraper를 사용한 다음 미사용이라고합니다! 나는 좋은 웃음을 가지고 있었다!
Rob

32

Mathematica + 양자 컴퓨팅

Mathematica는 양자 컴퓨터와 함께 제공됩니다.

Needs["Quantum`Computing`"];

양자 단열 컴퓨팅은 최소 에너지 상태 ( "접지 상태")가 솔루션을 나타내는 방식으로 해밀턴 (에너지 운영자)에서 해결해야 할 문제를 인코딩합니다. 따라서 해밀턴의 지상 상태로 양자 시스템의 단열 진화와 후속 측정은 문제에 대한 해결책을 제공합니다.

우리는 ||변수와 그 부정에 대한 Pauli 연산자의 적절한 조합으로 표현의 일부에 해당하는 하하 무 토니아를 정의합니다.

여기에 이미지 설명을 입력하십시오

이런 식으로 어디에서

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

인수는 다음과 같아야합니다

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

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

이제 우리는 해밀턴을 요약하여 완전한 해밀턴 인을 구성합니다 (요약 &&은 표현의 일부에 해당합니다)

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

그리고 가장 낮은 에너지 상태를 찾으십시오

QuantumEigensystemForm[H, -1]

여기에 이미지 설명을 입력하십시오

고유 값이 0이면 고유 벡터가 솔루션입니다.

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

불행히도 "Quantum Computing"부가 기능의 공식 사이트가 활성화되어 있지 않으며 다운로드 할 장소를 찾을 수 없습니다. 아직 컴퓨터에 설치되어있었습니다. 추가 기능에는 코드를 기반으로 한 SAT 문제에 대한 문서화 된 솔루션이 있습니다.


19
나는이 답변이 어떻게 작동하는지 전혀 모른다. +1
Jonathan Pullano 2014 년

5
@XiaogeSu "자연스럽게".
swish

3
@XiaogeSu 진화는 Hamiltonian에 의해 결정되며 자연스럽게 가장 낮은 에너지로 진화합니다. 따라서 스펙트럼을 알면 시스템이 접지 상태가된다고 가정 할 수 있습니다.
Swish

3
@XiaogeSu는 지상 상태로 가기 위해서는 더 높은 상태를 흥분시키는 환경과의 상호 작용이 필요합니다. 여기서의 상호 작용은이 상호 작용이 매우 작고 "지방 질적"이라는 것입니다.
Turion

3
참고 단열 QM 컴퓨팅 은 고전적인 시뮬레이션 어닐링 과 많은 유사성을 가지고 있습니다. 이제 Dwave에 의해 구현 됩니다 . 는 "냉각"온도 / 에너지 시스템에서의 유사한 "발견은 / 정착" 극소값 .
vzn

27

여기에 세 가지 접근 방식은 모두 SAT를 2D 기하학적 링구아 프랑카 (노노 그램 논리 퍼즐)로 축소하는 것입니다. 논리 퍼즐의 셀은 SAT 변수, 절에 대한 제약 조건에 해당합니다.

전체 설명 (및 버그에 대한 내 코드를 검토하십시오!)을 위해 이미 nonogram 솔루션 공간 내의 패턴에 대한 통찰력을 게시했습니다. https://codereview.stackexchange.com/questions/43770/nonogram-puzzle-solution-space를 참조 하십시오. 40 억 개 이상의 퍼즐 솔루션을 열거하고이를 진리표에 맞게 인코딩하면 프랙탈 패턴 (자기 유사성, 특히 자기 친 화성)이 표시됩니다. 이 affine-redundancy는 문제를 해결하는 데 필요한 계산 리소스를 줄이기 위해 이용할 수있는 문제 내의 구조를 보여줍니다. 또한 성공적인 알고리즘 내에서 혼란스러운 피드백이 필요하다는 것을 보여줍니다. "쉬운"인스턴스가 거친 구조를 따르는 인스턴스 인 위상 전이 동작에는 설명력이 있지만, "하드"인스턴스는 일반적인 휴리스틱에서 숨겨져있는 세부적인 부분까지 추가 반복이 필요합니다. 이 무한 이미지의 모서리를 확대하려면 (모든 <= 4x4 퍼즐 인스턴스 인코딩) http://re-curse.github.io/visualizing-intractability/nonograms_zoom/nonograms.html을 참조하십시오.

방법 1. 카오스 맵과 머신 러닝 (만델 브로트 세트를 생성하는 것과 유사한 피팅 기능을 고려)을 사용하여 노노 그램 솔루션 공간 그림자를 추정합니다.

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

다음은 유도에 대한 시각적 증거입니다. 당신이 왼쪽에서 오른쪽으로 네 가지 이미지를 스캔하고 생각할 수있는 경우 등 이미지를, 나는 그냥 프로그래밍 한 누락 된 5 ... 6 ... 생성하는 것은 좋은 생각이 당신을 노노 그램 솔루션의 의사 결정 문제에 대한 내 NP 오라클로를 존재. 당신의 상을 세계에서 가장 강력한 슈퍼 컴퓨터라고 주장하십시오. 나는 때때로 당신에게 전기의 충격을 줄 것이다. 그리고 세계는 당신의 계산 기여에 대해 감사한다.

방법 2. 부울 이미지 버전의 입력에서 푸리에 변환을 사용합니다. FFT는 인스턴스 내 빈도 및 위치에 대한 글로벌 정보를 제공합니다. 크기 부분은 입력 쌍간에 유사해야하지만 위상 정보는 완전히 다릅니다. 특정 축을 따라 솔루션 투영에 대한 방향 정보가 포함되어 있습니다. 당신이 충분히 영리하다면 입력 위상 이미지의 특별한 중첩을 통해 솔루션 의 위상 이미지를 재구성 할 수 있습니다. 그런 다음 위상과 공통 크기를 솔루션의 시간 영역으로 역변환합니다.

이 방법은 무엇을 설명 할 수 있습니까? 연속 런 사이에 유연한 패딩을 사용하여 부울 이미지의 순열이 많이 있습니다. 이를 통해 다중도를 고려한 입력-> 솔루션 간 매핑을 허용하면서도 시간 도메인 <-> (주파수, 위상) 간 양방향 고유 매핑의 FFT 속성을 유지할 수 있습니다. 또한 "솔루션 없음"과 같은 것은 없다는 것을 의미합니다. 연속적인 경우, 기존의 비 모노그램 퍼즐 해결의 2 단계 이미지를 볼 때 고려하지 않는 그레이 스케일 솔루션이 있습니다.

왜 안하지? 오늘날 부동 소수점 세계의 FFT는 큰 인스턴스에서는 매우 부정확하므로 실제로 계산하는 것은 끔찍한 방법입니다. 정밀도는 큰 문제이며, 양자화 된 크기 및 위상 이미지로부터 이미지를 재구성하는 것은 육안으로 볼 수는 없지만 시각적으로 매우 근사한 솔루션을 만듭니다 . 실제로이 기능을 수행하는 기능의 유형은 현재 알려지지 않았기 때문에이 중첩 비즈니스를 생각해 내기가 매우 어렵습니다. 간단한 평균 구성표입니까? 아마도 아닐 수도 있고 직감을 제외하고 특정 검색 방법을 찾을 수 없습니다.

방법 3. 노노 그램 퍼즐의 대칭 버전을 해결하는 셀룰러 오토마타 규칙 (von Neumann 2- 상태 규칙에 대해 ~ 40 억 개의 규칙 테이블 중에서)을 찾습니다. 여기에 표시된대로 문제를 셀에 직접 포함시킵니다. 보수적이고 대칭적인 노노 그램

이것은 미래의 컴퓨팅에 대한 단순성과 좋은 효과면에서 가장 우아한 방법 일 것입니다. 이 규칙의 존재는 입증되지 않았지만 나는 그 직감이 있습니다. 이유는 다음과 같습니다.

노노 그램은 알고리즘에서 정확하게 해결하기 위해 많은 혼란스러운 피드백이 필요합니다. 이것은 코드 검토에 연결된 무차별 대입 코드에 의해 확립됩니다. CA는 혼란스러운 피드백을 프로그래밍 할 수있는 가장 유능한 언어입니다.

그것은 보이는 시각적으로 오른쪽. 이 규칙은 임베딩을 통해 발전하고 정보를 수평 및 수직으로 전파하고 간섭 한 다음 설정된 셀 수를 보존 한 솔루션으로 안정화합니다. 이 전파 경로는 실제 객체의 그림자를 원래 구성으로 투사 할 때 일반적으로 생각하는 경로 (뒤로)를 따릅니다. Nonograms는 이산 단층 촬영의 특별한 경우에서 파생되므로 두 개의 키티 코너 CT 스캐너에 동시에 앉아 있다고 상상해보십시오. 이것이 X-ray가 의료 이미지를 생성하도록 전파되는 방법입니다. 물론 경계 문제가 있습니다. 토 로이드 형 유니버스를 허용하지 않으면 CA 유니버스의 가장자리에서 정보를 계속해서 제한을 넘어 전파 할 수 없습니다. 또한 퍼즐을 주기적 경계 값 문제로 만듭니다.

스와핑 출력 사이의 연속적인 발진 효과에서 여러 솔루션을 과도 상태로 설명합니다. 세트 셀 수를 보존하지 않는 원래 구성으로 솔루션이없는 인스턴스에 대해 설명합니다. 이러한 규칙을 찾은 실제 결과에 따라 셀 상태 보존 되는 밀접한 솔루션으로 해결할 수없는 인스턴스와 비슷할 수도 있습니다 .


2
말하는 저를 떠나 하나는 "왜하지 않았다 나는 그 생각?" : P
Navin

당신은 Stephen Wolfram이고 5 파운드를 청구합니다!
Quuxplusone

4
이 답변은 설득력있는 프로그램 을 만들기위한 최선의 시도이므로 더 많은 크레딧을받을 가치가 있습니다 . 좋은 쇼.
Jonathan Pullano

10

C ++

다항식 시간으로 실행되는 솔루션은 다음과 같습니다. 부울 수는 O(n^k)어디 에서 실행되며 선택하는 상수입니다.nk

그것은이 경우, 내가 CS 발언은 "이 행운의 비트와 함께, 정답 대부분의 시간을 제공합니다"를 믿고있는, 경험적으로 올바른 (그리고,의 적절하게 큰 값 k- 편집은 실제로 나에게 발생 어떤 고정을 위해 n당신이 설정할 수 k있도록 n^k > 2^n? - 그 부정 행위입니다).

#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;
  }
}

좋은 대답입니다. 설명을 스포일러 태그에 넣어 사람들이 쳐다보고 머리를 약간 긁을 수 있습니다.
Jonathan Pullano

@JonathanPullano 제안에 감사드립니다. 스포일러 태그를 추가하고 코드를 약간 난독 화했습니다.
CompuChip

그건 그렇고, 나는 단지에 대해 알아 냈습니다 bitfield. 어쩌면 나는 그 이상을 선호했을 것입니다 std::vector.
CompuChip

3
창조적 난독 화와 히치하이커의 언급에 +1
Blake Miller

2
예 k는 N에 의존하는 경우가 일정한 :-)의 많은 아니라, 속임수 물론
RemcoGerlich

3

루비 / gnuplot 3d 표면

(어머니 경쟁!) ... 어쨌든 ... 천 단어의 그림입니까? 이들은 SAT 전 이점의 gnuplot에서 만들어진 3 개의 개별 표면 플롯입니다. (x, y) 축은 절 및 변수 수이고 z 높이는 솔버에서 재귀 호출의 총 수입니다. 루비로 작성된 코드. 100 샘플마다 10x10 포인트를 샘플링합니다. 통계의 기본 원리를 설명 / 사용 하며 Monte Carlo 시뮬레이션 입니다.

기본적으로 DIMACS 형식으로 생성 된 임의 인스턴스에서 실행 되는 davis putnam 알고리즘입니다. 이것은 전 세계 CS 수업에서 이상적으로 수행 될 수있는 유형의 운동으로 학생들이 기초를 배울 수는 있지만 거의 구체적으로 가르쳐지지는 않습니다. 어쩌면 많은 가짜 P? = NP 증거 가있는 이유가있을 수 있습니다 . 통계 물리학에서 매우 중요한 주제이며 CS에서도 핵심적인 전환점 현상 (모든 응시자?)을 설명하는 유용한 Wikipedia 기사는 없습니다. [a] [b] CS에는 전환점 이 많은 논문 이 있습니다. 그러나 표면 플롯을 보여주는 사람은 거의 없습니다! (대신 일반적으로 2D 슬라이스를 표시합니다.)

런타임의 기하 급수적 인 증가는 1 플롯 에서 분명하게 나타납니다 . 첫 번째 플롯 의 중간을 통과하는 안장 은 전 이점입니다. 두 번째 및 세 번째 도표는 만족스러운 % 전환을 나타냅니다.

[a] CS ppt Toby Walsh 에서의 위상 전이 거동
[b] k-SAT 만족도의 경험적 확률 tcs.se
[c] 경험적 / 실험적 수학 / (T) CS / SAT , TMachine 블로그 에서의 중대한 순간

여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오 여기에 이미지 설명을 입력하십시오

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
이 답변에 도움을 주셔서 감사합니다. P 대 NP의 성공적인 증거 (둘 중 어느 쪽이든)는 예측력에 대한 많은 요구 사항 중 하나입니다. 중요성을 지적 해 주셔서 감사합니다. :)

에 대한 자세한 담고 NP 대 P , 많은 최고 / 수집 심판 등
vzn
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.