씨#
당신의 임무는 다항식 시간에 실행되는 것처럼 보이는 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인지 실제로 결정할 수 없는지 일반적인 반동이 존재하는 경우 유형 변환이 작동하는 방식에 대한 미묘한 세부 사항에 따라 다르지만 이는 또 다른 날의 주제입니다.