* buddy/src/bdd.h, buddy/src/bvec.h, buddy/src/fdd.h: Rename as... * buddy/src/bddx.h, buddy/src/bvecx.h, buddy/src/fddx.h: ... these. * buddy/src/Makefile.am: Build libbddx.la instead of libbdd.la. * buddy/examples/Makefile.def: Use it. * Makefile.am, buddy/src/bddtest.cxx, buddy/src/bvec.c, buddy/src/cppext.cxx, buddy/src/fdd.c, buddy/src/imatrix.h, buddy/src/kernel.h, buddy/examples/adder/adder.cxx, buddy/examples/bddcalc/parser_.h, buddy/examples/bddtest/bddtest.cxx, buddy/examples/cmilner/cmilner.c, buddy/examples/fdd/fdd.cxx, buddy/examples/milner/milner.cxx, buddy/examples/money/money.cxx, buddy/examples/queen/queen.cxx, buddy/examples/solitare/solitare.cxx, m4/buddy.m4, src/ltlvisit/apcollect.hh, src/ltlvisit/simplify.hh, src/misc/bddlt.hh, src/misc/bddop.hh, src/misc/minato.hh, src/priv/acccompl.hh, src/priv/accconv.hh, src/priv/accmap.hh, src/priv/bddalloc.cc, src/tgba/bdddict.hh, src/tgba/bddprint.hh, src/tgba/tgbamask.hh, src/tgba/tgbasafracomplement.cc, src/tgbaalgos/emptiness.hh, src/tgbaalgos/gtec/sccstack.hh, src/tgbaalgos/neverclaim.cc, src/tgbaalgos/powerset.cc, src/tgbaalgos/sccfilter.hh, src/tgbaalgos/sccinfo.hh, src/tgbaalgos/weight.hh, wrap/python/buddy.i: Adjust. * NEWS, README: Document it.
136 lines
2.9 KiB
C++
136 lines
2.9 KiB
C++
/**************************************************************************
|
|
BDD demonstration of the N-Queen chess problem.
|
|
-----------------------------------------------
|
|
The BDD variables correspond to a NxN chess board like:
|
|
|
|
0 N 2N .. N*N-N
|
|
1 N+1 2N+1 .. N*N-N+1
|
|
2 N+2 2N+2 .. N*N-N+2
|
|
.. .. .. .. ..
|
|
N-1 2N-1 3N-1 .. N*N-1
|
|
|
|
So for example a 4x4 is:
|
|
|
|
0 4 8 12
|
|
1 5 9 13
|
|
2 6 10 14
|
|
3 7 11 15
|
|
|
|
One solution is then that 2,4,11,13 should be true, meaning a queen
|
|
should be placed there:
|
|
|
|
. X . .
|
|
. . . X
|
|
X . . .
|
|
. . X .
|
|
|
|
**************************************************************************/
|
|
#include <stdlib.h>
|
|
#include <iostream>
|
|
#include "bddx.h"
|
|
using namespace std;
|
|
|
|
int N; /* Size of the chess board */
|
|
bdd **X; /* BDD variable array */
|
|
bdd queen; /* N-queen problem express as a BDD */
|
|
|
|
|
|
/* Build the requirements for all other fields than (i,j) assuming
|
|
that (i,j) has a queen */
|
|
void build(int i, int j)
|
|
{
|
|
bdd a=bddtrue, b=bddtrue, c=bddtrue, d=bddtrue;
|
|
int k,l;
|
|
|
|
/* No one in the same column */
|
|
for (l=0 ; l<N ; l++)
|
|
if (l != j)
|
|
a &= X[i][j] >> !X[i][l];
|
|
|
|
/* No one in the same row */
|
|
for (k=0 ; k<N ; k++)
|
|
if (k != i)
|
|
b &= X[i][j] >> !X[k][j];
|
|
|
|
/* No one in the same up-right diagonal */
|
|
for (k=0 ; k<N ; k++)
|
|
{
|
|
int ll = k-i+j;
|
|
if (ll>=0 && ll<N)
|
|
if (k != i)
|
|
c &= X[i][j] >> !X[k][ll];
|
|
}
|
|
|
|
/* No one in the same down-right diagonal */
|
|
for (k=0 ; k<N ; k++)
|
|
{
|
|
int ll = i+j-k;
|
|
if (ll>=0 && ll<N)
|
|
if (k != i)
|
|
d &= X[i][j] >> !X[k][ll];
|
|
}
|
|
|
|
queen &= a & b & c & d;
|
|
}
|
|
|
|
|
|
int main(int ac, char **av)
|
|
{
|
|
using namespace std ;
|
|
int n,i,j;
|
|
|
|
if (ac != 2)
|
|
{
|
|
fprintf(stderr, "USAGE: queen N\n");
|
|
return 1;
|
|
}
|
|
|
|
N = atoi(av[1]);
|
|
if (N <= 0)
|
|
{
|
|
fprintf(stderr, "USAGE: queen N\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Initialize with 100000 nodes, 10000 cache entries and NxN variables */
|
|
bdd_init(N*N*256, 10000);
|
|
bdd_setvarnum(N*N);
|
|
|
|
queen = bddtrue;
|
|
|
|
/* Build variable array */
|
|
X = new bdd*[N];
|
|
for (n=0 ; n<N ; n++)
|
|
X[n] = new bdd[N];
|
|
|
|
for (i=0 ; i<N ; i++)
|
|
for (j=0 ; j<N ; j++)
|
|
X[i][j] = bdd_ithvar(i*N+j);
|
|
|
|
/* Place a queen in each row */
|
|
for (i=0 ; i<N ; i++)
|
|
{
|
|
bdd e = bddfalse;
|
|
for (j=0 ; j<N ; j++)
|
|
e |= X[i][j];
|
|
queen &= e;
|
|
}
|
|
|
|
/* Build requirements for each variable(field) */
|
|
for (i=0 ; i<N ; i++)
|
|
for (j=0 ; j<N ; j++)
|
|
{
|
|
cout << "Adding position " << i << "," << j << "\n" << flush;
|
|
build(i,j);
|
|
}
|
|
|
|
/* Print the results */
|
|
cout << "There are " << bdd_satcount(queen) << " solutions\n";
|
|
cout << "one is:\n";
|
|
bdd solution = bdd_satone(queen);
|
|
cout << bddset << solution << endl;
|
|
|
|
bdd_done();
|
|
|
|
return 0;
|
|
}
|