So obviously, P = NP

111

50

SAT is the problem of determining whether a boolean expression can be made true. For example, (A) can be made true by setting A=TRUE, but (A && !A) can never be true. This problem is known to be NP-complete. See Boolean Satisfiability.

Your task is to write a program for SAT that executes in polynomial time, but may not solve all cases.

For some examples, the reason it is not really polynomial could be because:

  1. There is an edge case that is not obvious but has a poor runtime
  2. The algorithm actually fails to solve the problem in some unexpected case
  3. Some feature of the programming language you are using actually has a longer runtime than you would reasonably expect it to have
  4. Your code actually does something totally different from what it looks like it's doing

You may use any programming language (or combination of languages) you wish. You do not need to provide a formal proof of your algorithm's complexity, but you should at least provide an explanation.

The primary criteria for judging should be how convincing the code is.

This is a popularity contest, so the highest rated answer in a week wins.

Jonathan Pullano

Posted 2014-03-17T16:09:07.423

Reputation: 1 233

Question was closed 2016-04-15T17:15:36.413

3

I'm voting to close this question as off-topic because underhanded challenges are no longer welcome on this site. http://meta.codegolf.stackexchange.com/a/8326/20469

– cat – 2016-04-15T14:19:14.050

This question hits more than one closure criterion. Too broad: a problem which solves any problem in P meets the criteria. Too subjective and/or unclear: "appears to execute in polynomial time" is open to all kinds of interpretations. – Peter Taylor – 2014-03-17T16:21:20.760

Would it be better if we restrict problem choices to well-known NP problems, and remove the twist? I think appears to execute in polynomial time is what gives people flexibility for the popularity contest. – Jonathan Pullano – 2014-03-17T16:25:07.927

11It would be better if you restrict the problem domain, otherwise you invoke the cloud of uncertainty around what is "well-known". Why not pick a single NP-hard problem and focus on that? That has the advantage of leaving other such problems open to future questions along the same line. Several narrow questions can provide far more ongoing delight and entertainment to the site than one broad one. – Jonathan Van Matre – 2014-03-17T16:38:05.433

Fair enough. I'll edit shortly. – Jonathan Pullano – 2014-03-17T16:44:50.713

1Can't add comments yet... Eric Lippert's "solution" is of course a sleight of hand. The C# language requires the compiler to do all the work. So given a 3SAT problem, you can ask the C# compiler to solve it, which will take exponential time. With that done, the C# compiler generates a program that solves one instance of 3SAT in linear time. Now since the solution of any instance of any NP complete problem is either YES or NO, that's not really much of an achievement. – gnasher729 – 2014-03-18T08:57:11.240

9@gnasher729: I got the C# compiler to solve a SAT problem; I consider that to be a reasonably interesting achievement. – Eric Lippert – 2014-03-18T22:07:15.337

9It would be fun if someone accidentally solves SAT in polynomial time here. – Turion – 2014-03-19T16:06:27.907

please tag this code trolling – Tim Seguine – 2014-03-19T16:39:54.220

@Turion: S/He'd be recruited to the Laundry. – Peter - Reinstate Monica – 2014-03-20T11:43:46.967

fyi further inquiry there are P vs NP tags on cs.se & tcs.se. see also how not to solve P=?NP cs.se and math monster/many P vs NP refs/stackexchange questions

– vzn – 2014-03-21T20:19:18.883

5@Turion decades of Research, millions in rewards and prizes and all the women and fame one could have - but the real motivation for solving P=NP will end up being this PCG challenge. – NothingsImpossible – 2014-03-22T00:20:37.373

Not thinking about the problem can sometimes make it easier. – Turion – 2014-03-22T01:06:58.803

@TimSeguine ...why? – Doorknob – 2014-03-23T22:22:35.160

Warhing: Do not do this in PHP. Everything is true if the PHP gods want it to be. – Tortoise – 2014-03-24T01:55:52.353

@NothingsImpossible: Women? Really? – SamB – 2014-03-24T17:57:32.880

Answers

235

C#

Your task is to write a program for SAT that appears to execute in polynomial time.

"Appears" is unnecessary. I can write a program that really does execute in polynomial time to solve SAT problems. This is quite straightforward in fact.

MEGA BONUS: If you write a SAT-solver that actually executes in polynomial time, you get a million dollars! But please use a spoiler tag anyway, so others can wonder about it.

Awesome. Please send me the million bucks. Seriously, I have a program right here that will solve SAT with polynomial runtime.

Let me start by stating that I'm going to solve a variation on the SAT problem. I'm going to demonstrate how to write a program that exhibits the unique solution of any 3-SAT problem. The valuation of each Boolean variable has to be unique for my solver to work.

We begin by declaring a few simple helper methods and types:

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

Now let's pick a 3-SAT problem to solve. Let's say

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

Let's parenthesize that a bit more.

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

We encode that like this:

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

And sure enough when we run the program, we get a solution to 3-SAT in polynomial time. In fact the runtime is linear in the size of the problem!

x1: false
x2: true
x3: false

You said polynomial runtime. You said nothing about polynomial compile time. This program forces the C# compiler to try all possible type combinations for x1, x2 and x3, and choose the unique one that exhibits no type errors. The compiler does all the work, so the runtime doesn't have to. I first exhibited this interesting techinque on my blog in 2007: http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx Note that of course this example shows that overload resolution in C# is at least NP-HARD. Whether it is NP-HARD or actually undecidable depends on certain subtle details in how type convertibility works in the presence of generic contravariance, but that's a subject for another day.

Eric Lippert

Posted 2014-03-17T16:09:07.423

Reputation: 2 805

95You'll have to contact the clay mathematics institute for your million bucks. But I am not sure they will be satisfied. – Jonathan Pullano – 2014-03-17T20:01:29.337

6This is absolutely amazing. Good job. – aebabis – 2014-03-17T20:34:44.137

I think it's worth mentioning that this approach specifically solves 3-SAT, and can at best be generalized to solve K-SAT, for some finite K. However, afaict you cannot generalize this approach to solve general SAT, at least in a staticly typed language like C#. – Jonathan Pullano – 2014-03-17T21:20:11.350

2@EricLippert: Actually, by nesting Or clauses (since Or(x,y,z) == Or(x,Or(y,z))), you can make the clauses arbitrarily long. Therefore, it is possible to solve SAT problems directly using the current framework. – nneonneo – 2014-03-17T22:44:13.510

@mneonneo: Arbitrarily long is not infinitely long. I could nest the clauses 1,000,000 times, but that would not allow me to solve 1,000,001-SAT, without writing a new program and recompiling. If I don't know the size of the input beforehand, this is not feasable. – Jonathan Pullano – 2014-03-17T22:59:14.493

15Of course any SAT problem can be transformed into an equivalent 3-SAT problem, so this restriction is merely an inconvenience. The more vexing issue with my "solution" is that it requires that the problem have a unique solution. If there is no solution or more than one solution then the compiler gives an error. – Eric Lippert – 2014-03-17T23:04:53.477

1@JonathanPullano I believe everything above 1,000,000 can be considered an edge case and unexpected input, according to 1. and 2. in the question. – Petr – 2014-03-17T23:41:56.183

@Petr: I agree with you. I just to inform the readers and perhaps encourage someone to try something new. – Jonathan Pullano – 2014-03-17T23:49:16.857

11@EricLippert the uniqueness requirement is ok. You can always reduce SAT to Unique-SAT (SAT but assuming the inputs have 0 or 1 assignments) using a polynomial time randomized reduction. Keywords: Isolation Lemma, Valiant-Vazirani theorem. – didest – 2014-03-18T00:02:38.177

Amazing write up: http://andysresearch.blogspot.com.ar/2007/06/paths-to-discovery-valiant-vazirani.html

– didest – 2014-03-18T00:08:21.323

1@JonathanPullano: Nesting Ors gives you a way to encode arbitrary SAT problems in a manner consistent with the helper types already defined (this is distinct from converting SAT->3SAT because you encode the boolean logic directly). Plus, SAT isn't defined in terms of infinite-length clauses (that would make the problems infinitely long), but rather in terms of clauses that can be of arbitrary length. – nneonneo – 2014-03-18T00:08:31.937

@DiegodeEstrada: I did not know that -- thanks for the note! – Eric Lippert – 2014-03-18T00:10:36.263

@EricLippert: AFAIK the compiler errors should tell you if the problem is satisfiable or not (i.e. whether the invocations are ambiguous or unsatisfiable). Too bad it won't produce anything executable... – nneonneo – 2014-03-18T00:11:38.060

@nneonneo: That's correct. – Eric Lippert – 2014-03-18T00:13:15.670

@mneonneo: Encoding SAT problems is a fine approach, though that encoding not explicitly written in this code, and the challenge is to write a program that solves SAT (The solution is still valid as per Petr's comment). I was not referring to infinite length clauses though. To solve a SAT problem directly with this method with a finite but arbitrarily long number of clauses would require an infinite amount of code. This is because even though each individual input is finite, it can be arbitrarily high, and so there are an infinite number of cases for the code to check. – Jonathan Pullano – 2014-03-18T00:28:56.753

1@JonathanPullano: I'm not following your train of thought here. Take your finite SAT problem. There's allegedly a polynomial algorithm to turn that into a "unique 3-SAT" problem. That will have a finite number n of variables and a finite number m of AND clauses, each clause having no more than three variables. Encode the variables by introducing n nested lambdas as I show, and encode the AND clauses with m nested calls to And. Run the compiler -- that's the non-polynomial step -- and then run the executable to get the answer. – Eric Lippert – 2014-03-18T00:35:13.127

@JonathanPullano: The contents of Main() constitute an encoding of the problem into C# code. Encoding is distinct from transformation; in the former case, you are simply translating the problem from mathematical terminology into a particular sequence of characters understood by the compiler, and in the latter you are creating a problem instance of a different problem which equivalently solves the original problem instance. – nneonneo – 2014-03-18T00:35:14.880

@EricLippert: My point actually is that you don't need to turn your SAT problem into a 3SAT problem because you can just nest Or clauses to get arbitrarily long boolean clauses. – nneonneo – 2014-03-18T00:36:08.617

Eric: I completely agree with you that transforming the problem to 3SAT is a valid answer. It might be nice to see that transformation explicitly, but even without that the answer is valid as per Petr's logic. mneonneo suggests that you can also encode arbitrarily long clauses to solve general SAT directly, however unless I am misunderstanding how he does this, I think you could only solve an instance of K-SAT this way, but not general SAT, because in the general case you would need to list out an infinite number of cases in code. This is getting a bit off-topic though guys :) – Jonathan Pullano – 2014-03-18T00:49:30.073

2Nit: UNIQUE-3SAT, the problem you are solving here, is not NP-complete. It is co-NP-complete, and it is widely thought (though not proven) that co-NP != NP. So, technically, this answer does not solve a known NP-complete problem. – nneonneo – 2014-03-18T00:54:25.273

@JonathanPullano: Why would you need to list out an infinite number of cases? For example, we can encode (x v y v z v w) as Or(Or(x,y,z),x,w), without having to create a 4-argument version of the Or function. – nneonneo – 2014-03-18T00:56:30.033

1@nneonneo: I am learning all kinds of new things today, thanks! – Eric Lippert – 2014-03-18T01:01:54.500

@nneonneo: Thanks, I now follow what you are saying. I suppose an ideal answer would take in some input and then generate the source code above via your encoding, but that is really just a technicality. – Jonathan Pullano – 2014-03-18T01:14:12.863

9Nitpicking: The code above isn't really the program, it is the input. The program that is solving 3-SAT is the C# compiler. The solution is the compiled program - it already contains the solution, you don't even have to run it. The run time of the compiled program is irreverent - the complexity is of the run time is inside the compiler. All of this isn't very important, but I wouldn't give you a million dollars. Thanks for this answer and for the interesting discussion is created! – Kobi – 2014-03-18T09:20:46.670

@Kobi even if he did solve P=NP, I don't think many people here would have the means/will to give him a million dollars. I, for starters, surely wouldn't. – Pierre Arlaud – 2014-03-18T09:27:04.130

I really love this solution. Reminds me of a C++ technique I read about once, called template metaprogramming. I think programmers often forget how powerful their compilers are. – CompuChip – 2014-03-18T10:57:44.033

44"Seriously, I have a program right here that will solve SAT with polynomial runtime." - me too, but unfortunately it does not fit in this comment box. – CompuChip – 2014-03-18T11:00:02.497

11@Kobi: Yes, that's the joke. – Eric Lippert – 2014-03-18T13:48:20.893

@CompuChip: Indeed. We see here that semantic analysis of C# is at least NP-HARD. C++ metaprogramming is even harder; it's Turing-complete and therefore not decidable. The Haskell type system also has this property. – Eric Lippert – 2014-03-18T13:50:14.527

4This program runs in O(1) actually. There is no input. If I made a program that outputted x1: false\nx2: true\nx3: false it would be equivalent to this program. And take much less time to compile as well. – Cruncher – 2014-03-18T14:27:09.693

1

@ArlaudPierre: The reference to a million dollar prize is: http://www.claymath.org/millenium-problems/p-vs-np-problem the Clay institute has a bounty of $1M each for a collection of unsolved important problems.

– Eric Lippert – 2014-03-18T15:13:02.887

@EricLippert I know, but you're not the Clay institute :-) – Pierre Arlaud – 2014-03-18T15:14:53.923

4@CompuChip, From now on you will be known as Fermat. – Stack Tracer – 2014-03-19T02:33:10.550

This particular instance of 3SAT is also an instance of 2SAT. – Blake Miller – 2014-03-20T01:04:01.200

1I don't think this program solves any SAT problem, since the problem is not taken as its input. What it does is simply printing out the answer of a specific instance of the SAT problem. – hpsMouse – 2014-03-20T10:58:52.520

3@hpsMouse: I've given you a recipe for making a program that solves any SAT problem you care to name. The example I gave is an illustration of how to do so. Making a program that takes as its input SAT problems, produces a C# program that encodes it, compiles it and runs it, is left as an exercise; I figured that was so straightforward as to not need doing explicitly. – Eric Lippert – 2014-03-20T13:47:47.847

I just wanted to point out that you could actually use dynamic code compilation in C# to take the problem as input :) – daedalus28 – 2014-03-21T00:10:44.670

2@EricLippert: Yes, but any program that takes a SAT problem as input and compiles it no longer has polynomial runtime :( – Ben Voigt – 2014-03-22T18:53:58.027

C# can do type-level programming? This puts C++ templates and Haskell multi-parameter typeclasses into shame – Ming-Tang – 2014-03-24T05:56:13.873

2@SHiNKiROU: Not really. C++ templates are known to be Turing-complete, as is I believe the Haskell type system. The C# type system is generally considered to have less representational power than either C++ or Haskell. – Eric Lippert – 2014-03-24T13:43:07.217

I've signed up here only to upvote this answer. – Nemanja Boric – 2014-03-27T14:28:48.363

Hmm, the "MEGA BONUS" on the question was removed... – wchargin – 2014-04-17T00:13:36.453

@JonathanPullano the "clay" mathematics institute? – ErlVolton – 2014-10-31T16:34:08.807

166

Multi-language (1 byte)

The following program, valid in many languages, mostly functional and esoteric, will give the correct answer for a large number of SAT problems and has constant complexity (!!!):

0

Amazingly, the next program will give the correct answer for all remaining problems, and has the same complexity. So you just need to pick the right program, and you'll have the correct answer in all cases!

1

Mau

Posted 2014-03-17T16:09:07.423

Reputation: 1 654

@shiona (I realize this comment is very late) Your comments don't make sense to me, as they are related to decidability, which this thread has nothing to do with. In fact, algorithms that don't decide the problem are explicitly acceptable. The pi-thing is decidable because if there is a longest finite number of consecutive 0s in pi (call that k), then compare our input number n to k and output "yes" iff n <= k, otherwise no. If there isn't a longest sequence, output "yes" for any input n. We just don't know which algorithm is correct, but that has nothing to do with decidability. – G. Bach – 2015-02-10T14:19:12.593

@shiona Also "problems that have constant result" makes no sense, as languages are defined as sets, and any object is either in any given set or it isn't, so every answer to every decidability problem is always constant. – G. Bach – 2015-02-10T14:19:59.790

6This is amazing. I had myself a good laugh. – Karl Damgaard Asmussen – 2014-03-18T13:16:13.420

2Absolutely f****** brilliant! – The Blue Dog – 2014-03-18T18:57:31.670

78Hmm. It's easy now. All I need to do is write a program that will pick the right program! – Cruncher – 2014-03-19T13:48:48.070

Precisely ! :-) – Mau – 2014-03-19T13:50:08.013

Just so people don't get the wrong impression: A meaningful problem, in the world of complexity theory, is a question with an infinite amount of instances. Here we have two programs that solve every instance of every problem, but solve only the (infinitely small portion of) problems that have constant result. I actually had an exercise question "Is 'does the decimal representation of pi have 100 consecutive zeroes' decidable?" The answer was "yes" since one of the above programs does solve it. – shiona – 2014-03-20T16:02:06.257

@shiona I agree on the first statement. But not on the second :) Since every problem (instance) can be formulated in terms of a yes/no question (and in particular every NP problem in terms of a SAT one), the two programs will solve any problem, once appropriately formulated :) – Mau – 2014-03-20T16:26:37.103

@Mau A wikipedia definition, and the one I was taught: "A decision problem is any arbitrary yes-or-no question on an infinite set of inputs." – shiona – 2014-03-20T17:02:46.923

@shiona I am not aware of any methods of determining whether or not a specific digit sequence exists in pi that do not involve calculations of some number of digits of pi, so is the decidability of a problem not based on the decidability of its result? While the result of the decision problem is constant (as pi does not change), any process to determine the result will only terminate if the result is "yes", which I thought would make the problem only partially decidable. – JAB – 2014-03-20T20:25:43.183

@JAB There is no method to solve the problem, so in a way I think you are on the right track. Now that you brought up partial (semi-)decidability, I think I will have to read it up some more before continuing. – shiona – 2014-03-20T23:31:29.213

6

Reminiscent of http://xkcd.com/221/.

– msh210 – 2014-03-21T06:43:28.777

I don't get it. :/ – Oliver Ni – 2014-03-23T05:50:39.663

No longer funny – Peter Taylor – 2014-03-23T08:19:45.163

34

JavaScript

By using iterated non-determinism, SAT can be solved in polynomial time!

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

Example usage:

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

This algorithm just checks given boolean formula a thousand times with random inputs. Almost always works for small inputs, but is less reliable when more variables are introduced.

By the way, I'm proud that I had the opportunity to utilize two of the most underused features of JavaScript right next to each other: eval and with.

Peter Olson

Posted 2014-03-17T16:09:07.423

Reputation: 7 412

4This is actually a well established testing method. Haskell's QuickCheck library started all the fun, I believe. It has since been reimplmented in many languages. – John Tyree – 2014-03-17T21:10:00.850

4I think it should be noted that, this program is less likely to return the correct answer, the bigger the sat expression. The 1000 in the for loop should somehow scale with the input size(some polynomial non-O(1) scaling). – Cruncher – 2014-03-18T14:32:32.607

2@Cruncher To be more precise, the larger the number of variables, the less likely it is to return the correct answer. (e.g. a very long expression with a single variable will almost always return the correct answer) – Peter Olson – 2014-03-18T14:45:44.460

@PeterOlson well of course. I was stating it as loosely as possible. A longer SAT expression is more likely to contain more variables – Cruncher – 2014-03-18T16:49:29.407

Randomness is not the same thing as nondeterministic. Both of them have precise definitions and they don't overlap. – Tim Seguine – 2014-03-19T16:42:06.460

@Tim: A program which is deterministic on its input may be fed random input, is that what you're getting at? But a random (not pseudo-random) number generator is non-deterministic, and a program whose output depends on an entropy source other than its input is also non-deterministic (wrt its input). – Ben Voigt – 2014-03-19T16:52:08.227

@BenVoigt no I am getting at: The colloquial use of the word "nondeterministic" is different than its use in complexity theory. This program is obviously making a play on the fact that SAT is in NP (nondeterministic polynomial time), but then proceeds to branching randomly. But a non deterministic program (in the sense of a nondeterministic Turing machine) will always accept if any of the reachable branches accepts. – Tim Seguine – 2014-03-19T16:56:58.263

@Tim: Hmm. But nondeterministic also has a strong definition (stochastic) in other technical fields. If I needed a formal technical term for your NTM it would be list-valued or vector-valued computation. So sorry, you're trying to impose the definition from another field, when the word was used correctly in context. The technical meaning of non-deterministic is multi-valued (and many of those values are quite precise). I guess a complexity theorist would say the meaning is non-deterministic?

– Ben Voigt – 2014-03-19T17:13:39.877

@BenVoigt since the question is based on a complexity theoretic claim, I think it is more than reasonable to expect the term to be used in that sense in an answer. No I would just call it ambiguous, just like the question it is posted as an answer to. – Tim Seguine – 2014-03-19T17:23:46.190

2@TimSeguine I admit that my use of the word "nondeterministic" in this context is dubious at best, just like the claim that SAT can be solved in polynomial time. I know it's not correct, it's just part of the game of deception. – Peter Olson – 2014-03-19T19:30:47.703

You had (and took) the opportunity to use the two worst features of Javascript: eval and with. – Paul Draper – 2014-03-20T00:49:18.683

4@PaulDraper and then call them underused! I had a nice laugh! – Rob – 2014-03-20T16:01:41.753

32

Mathematica + Quantum Computing

You may not know that Mathematica comes with quantum computer aboard

Needs["Quantum`Computing`"];

Quantum Adiabatic Commputing encodes a problem to be solved in a Hamiltonian (energy operator) in such way that its state of minimum energy ("ground state") represents the solution. Therefore adiabatic evolution of a quantum system to the ground state of the Hamiltonian and subsequent measurement gives the solution to the problem.

We define a subhamiltonian that corresponds to || parts of the expression, with appropriate combination of Pauli operators for variables and its negation

enter image description here

Where for expression like this

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

the argument should look like

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

Here is the code to construct such argument from bool expression:

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

Now we construct a full Hamiltonian, summing up the subhamiltonians (the summation corresponds to && parts of the expression)

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

And look for the lowest energy state

QuantumEigensystemForm[H, -1]

enter image description here

If we got an eigenvalue of zero, then the eigenvector is the solution

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

Unfortunately the official site for the "Quantum Computing" add-on is not active and I can't find a place to download it, I just still had it installed on my computer. The Add-on also have a documented solution to the SAT problem, on which I based my code.

swish

Posted 2014-03-17T16:09:07.423

Reputation: 7 484

19I have no idea how this answer works. +1 – Jonathan Pullano – 2014-03-19T20:07:46.687

"adiabatic evolution of a quantum system to the ground state", how that happens? – Xiaoge Su – 2014-03-20T17:45:23.383

5@XiaogeSu "Naturally". – swish – 2014-03-21T00:14:24.307

1@swish OK. Now consider a Hydrogen atom, in 1st excited state. If there is no vacuum fluctuation, then base on Schoedinger equation it will stay in 1st excited state. I cannot see how it goes to ground state. – Xiaoge Su – 2014-03-21T00:23:17.760

3@XiaogeSu Evolution determined by the Hamiltonian, and naturally it evolves to the lowest energy. So knowing the spectrum, we can assume that the system will end up in the ground state. – swish – 2014-03-21T00:30:03.027

1@SCOTTAARONSON did you have a momentary lapse of your ethics? – sehe – 2014-03-22T00:07:08.320

3@XiaogeSu in order to go to the ground state, one also needs to have an interaction with the environment that deexcitates the higher states, you're right. The idea here is that this interaction is very small, "adiabatic". – Turion – 2014-03-22T01:11:01.067

3

fyi adiabatic QM computing has a lot of similarities to classical simulated annealing. now implemented by Dwave. its similar to a "cooling" temperature/energy system that "finds/settles" in local minima.

– vzn – 2014-03-22T14:34:46.863

see also Dwave & the inception of the QM computing dream for more bkg/details on the world-leading implementation of QM computing

– vzn – 2014-03-26T01:55:48.913

FWIW, I think you got this package from here - http://homepage.cem.itesm.mx/lgomez/quantum/index.htm

– Noon SIlk – 2014-04-12T07:46:50.973

1How does this work, given NP is not known to be in BQP? Even with (theoretically) a quantum computer, how does this give a polynomial time solution to 3-SAT? – isaacg – 2014-06-20T18:03:49.390

27

Three approaches here, all involve a reduction of SAT into its 2D geometric lingua franca: nonogram logic puzzles. Cells in the logic puzzle correspond to SAT variables, constraints to clauses.

For a full explanation (and to please review my code for bugs!) I've already posted some insight to patterns within the nonogram solution space. See https://codereview.stackexchange.com/questions/43770/nonogram-puzzle-solution-space . Enumerating >4 billion puzzle solutions and encoding them to fit in a truth table shows fractal patterns -- self-similarity and especially self-affinity. This affine-redundancy demonstrates structure within the problem, exploitable to reduce the computational resources necessary to generate solutions. It also shows a need for chaotic feedback within any successful algorithm. There is explanatory power in the phase transition behavior where "easy" instances are those that lie along the coarse structure, while "hard" instances require further iteration into fine detail, quite hidden from normal heuristics. If you'd like to zoom into the corner of this infinite image (all <=4x4 puzzle instances encoded) see http://re-curse.github.io/visualizing-intractability/nonograms_zoom/nonograms.html

Method 1. Extrapolate the nonogram solution space shadow using chaotic maps and machine learning (think fitting functions similar to those that generate the Mandelbrot Set).

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

Here is a visual proof of induction. If you can scan these four images left to right and think you have a good idea to generate the missing 5th... 6th... etc. images, then I have just programmed you as my NP oracle for the decision problem of nonogram solution existence. Please step forth to claim your prize as the world's most powerful supercomputer. I'll feed you jolts of electricity every now and then while the world thanks you for your computational contributions.

Method 2. Use Fourier Transforms on the boolean image version of inputs. FFTs provide global information about frequency and position within an instance. While the magnitude portion should be similar between the input pair, their phase information is completely different -- containing directionalized information about a solution projection along a specific axis. If you're clever enough you might reconstruct the phase image of the solution via some special superposition of the input phase images. Then inverse transform the phase and common magnitude back to the time domain of the solution.

What could this method explain? There are many permutations of the boolean images with flexible padding between contiguous runs. This allows a mapping between input -> solution taking care of multiplicity while still retaining FFTs' property of bidirectional, unique mappings between time domain <-> (frequency, phase). It also means there's no such thing as "no solution." What it would say is that in a continuous case, there are greyscale solutions that you're not considering when looking at the bilevel image of traditional nonogram puzzle solving.

Why wouldn't you do it? It's a horrible way to actually compute, as FFTs in today's floating-point world would be highly inaccurate with large instances. Precision is a huge problem, and reconstructing images from quantized magnitude and phase images usually creates very approximate solutions, although maybe not visually for human eye thresholds. It's also very hard to come up with this superpositioning business, as the type of function actually doing it is currently unknown. Would it be a simple averaging scheme? Probably not, and there's no specific search method to find it except intuition.

Method 3. Find a cellular automata rule (out of a possible ~4 billion rule tables for von Neumann 2-state rules) that solves a symmetric version of the nonogram puzzle. You use a direct embedding of the problem into cells, shown here. Conservative, symmetric nonograms

This is probably the most elegant method, in terms of simplicity and good effects for the future of computing. The existence of this rule isn't proven, but I have a hunch it exists. Here's why:

Nonograms require lots of chaotic feedback in the algorithm to be solved exactly. This is established by the brute force code linked to on Code Review. CA is just about the most capable language to program chaotic feedback.

It looks right, visually. The rule would evolve through an embedding, propogate information horizontally and vertically, interfere, then stabilize to a solution that conserved the number of set cells. This propogation route follows the path (backwards) that you normally think of when projecting a physical object's shadow into the original configuration. Nonograms derives from a special case of discrete tomography, so imagine sitting concurrently in two kitty-cornered CT scanners.. this is how the X-rays would propogate to generate the medical images. Of course, there are boundary issues -- the edges of the CA universe cannot keep propogating information beyond the limits, unless you allow a toroidal universe. This also casts the puzzle as a periodic boundary value problem.

It explains multiple solutions as transient states in a continuously oscillating effect between swapping outputs as inputs, and vis versa. It explains instances that have no solution as original configurations that don't conserve the number of set cells. Depending on the actual outcome of finding such a rule, it may even approximate unsolvable instances with a close solution where the cell states are conserved.

user19710

Posted 2014-03-17T16:09:07.423

Reputation:

2+1 for leaving me saying "why didn't I think of that?" :P – Navin – 2014-03-24T22:53:54.560

You are Stephen Wolfram and I claim my five pounds! – Quuxplusone – 2014-03-25T05:12:53.577

4This answer really deserves more credit, as it's the best attempt to make a convincing program. Good show. – Jonathan Pullano – 2014-04-02T16:23:59.137

10

C++

Here is a solution that is guaranteed to run in polynomial time: it runs in O(n^k) where n is the number of booleans and k is a constant of your choice.

It is heuristically correct, which I believe is CS-speak for "it gives the correct answer most of the time, with a bit of luck" (and, in this case, an appropriately large value of k - edit it actually occurred to me that for any fixed n you can set k such that n^k > 2^n - is that cheating?).

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

CompuChip

Posted 2014-03-17T16:09:07.423

Reputation: 439

Good answer. I would put the explanation in a spoiler tag so people can stare at it and scratch their head a bit. – Jonathan Pullano – 2014-03-19T18:28:44.480

Thanks for the suggestion @JonathanPullano, I've added a spoiler tag and obfuscated the code a bit. – CompuChip – 2014-03-19T18:38:11.913

By the way, I only just found out about bitfield, maybe I would have preferred that over std::vector. – CompuChip – 2014-03-19T18:38:52.233

3+1 for the creative obfuscation and hitchhiker's references – Blake Miller – 2014-03-20T01:12:55.197

2Yes of course that's cheating, if k depends on n it's not much of a constant :-) – RemcoGerlich – 2014-03-23T20:17:38.833

@RemcoGerlich k doesn't depend on n - you can set it to whatever you want. If you choose k "large" the algorithm just is more likely to get the answer right ;) The observation was that if you choose it to be of the order 2^n then average run time is O(2^(n-1)) (I think) but with a proper uniform random generator the answer will be found with probability 1. – CompuChip – 2014-03-24T06:18:49.180

@RemcoGerlich and of course it's cheating - if you have a real polynomial-order algorithm that is guaranteed to find the correct answer then please publish it! – CompuChip – 2014-03-24T06:23:16.247

3

ruby/gnuplot 3d surface

(ooh stiff competition!) ... anyway ... is a picture worth a thousand words? these are 3 separate surface plots made in gnuplot of the SAT transition point. the (x,y) axes are clause & variable count and the z height is total # of recursive calls in the solver. code written in ruby. it samples 10x10 points at 100 samples each. it demonstrates/uses basic principles of statistics and is a Monte Carlo simulation.

its basically a davis putnam algorithm running on random instances generated in DIMACS format. this is the type of exercise that ideally would be done in CS classes around the world so students could learn the basics but is almost not taught specifically at all... maybe some reason why there are so many bogus P?=NP proofs? there is not even a good wikipedia article describing the transition point phenomenon (any takers?) which is a very prominent topic in statistical physics & is key also in CS.[a][b] there are many papers in CS on the transition point however very few seem to show surface plots! (instead typically showing 2d slices.)

the exponential increase in runtime is clearly evident in 1st plot. the saddle running through the middle of 1st plot is the transition point. the 2nd and 3rd plots show the % satisfiable transition.

[a] phase transition behavior in CS ppt Toby Walsh
[b] empirical probability of k-SAT satisfiability tcs.se
[c] great moments in empirical/experimental math/(T)CS/SAT, TMachine blog

enter image description here enter image description here enter image description here

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
}

vzn

Posted 2014-03-17T16:09:07.423

Reputation: 359

2I'm glad you contributed this answer. In any successful proof of P versus NP (either way) it's one of many requirements for predictive power. Thanks for pointing out its importance. :) – None – 2014-03-25T00:20:54.337

more musings on P vs NP, many top/ collected refs, etc

– vzn – 2014-12-05T05:13:41.810