There is a example of constaint satisfatory problem-Australia Map Coloring. the kernel of follow procedure is depth-first search.
sample of input:
1 2 3 4 5 6 7
8
1 2 1 3 2 3 2 4 3 5 3 6 4 5 5 6
coressponding output:
1 red
2 blue
3 green
5 red
6 blue
4 green
7 red
Follow is the procedure:
/**/
/*
Name: AustraliaColoring.cpp
Copyright: All Right Reserved 2008
Author: li zu-ding <lizuding@gmail.com>
Date: 10-05-08 15:01
Description: Australia Coloring Problem, one of constraint statisfactory problem
can be probed in AI:MA at P.109
*/
#include < string >
#include < vector >
#include < iostream >
using namespace std;
#define VERTICS_NUM 7 // the number of Vertices
enum Color ... {noncolor = 0, red, blue, green} ;
struct Graph
... {
string name[VERTICS_NUM]; // name of node
Color nodes_color[VERTICS_NUM]; // hue of node been colored
int matrix_of_graph[VERTICS_NUM][VERTICS_NUM];
} ;
struct ColoredNode
... {
int node;
Color hue;
} ;
void initial_graph (Graph * );
void create_graph (Graph * );
bool coloring (Graph * );
bool recursive_coloring (Graph & , vector < ColoredNode > & );
int select_unassigning_variable (Graph & , vector < ColoredNode > & );
bool is_consistent (Graph & , Color, int );
string print_color(Color & );
int main ( int argc, char * argv[])
... {
Graph cg;
initial_graph (&cg);
create_graph (&cg);
coloring (&cg);
system ("pause");
return 0;
}
/**/ /**
* @function: initialize one flat constraint network
* @para: cg flat constraint network
* @ret: void
**/
void initial_graph (Graph * cg)
... {
for (int i = 0; i < VERTICS_NUM; ++i)
...{
cg->nodes_color[i] = noncolor;
for (int j = 0; j < VERTICS_NUM; ++j)
cg->matrix_of_graph[i][j] = 0;
}
}
/**/ /**
* @function: create nodes and edges of constraint network
* @para: cp flat constraint network which has been initiliazed
* @ret : void
**/
void create_graph (Graph * cg)
... {
string name;
cout << "input name of vertexs ";
int i = 0;
while (i < VERTICS_NUM)
...{
cin >> name;
cg->name[i] = name;
++ i;
}
int num_of_edges = 0;
cout << "How many edges you contraint graph contain ";
cin >> num_of_edges;
cout << "input edges ";
int head; // the head node of edge
int tail; // the tail node of edge
for (int i = 0; i < num_of_edges; ++i)
...{
cin >> head >> tail;
cg->matrix_of_graph[head - 1][tail - 1] = 1;
cg->matrix_of_graph[tail - 1][head - 1] = 1;
}
}
/**/ /**
*@function: color the constraint network cg
*@para: cg constraint network
*@ret : if there is a complete assignment to the constraint network, return true;
* otherwise, return false
**/
bool coloring (Graph * cg)
... {
vector<ColoredNode> assignment;
if ( recursive_coloring (*cg, assignment) )
...{
for ( vector<ColoredNode>::iterator itr = assignment.begin();
itr != assignment.end(); ++ itr )
cout << (*itr).node + 1 << " " << print_color((*itr).hue) << " ";
return true;
}
return false;
}
/**/ /**
*@function: recursive procedure to color the constraint network
*@para: cg constraint network
*@para: assignation vector to store variable's assigned value
*@ret : if there is a complete assignment to the constraint network, return true;
* otherwise, return false
**/
bool recursive_coloring (Graph & cg, vector < ColoredNode > & assignment)
... {
if ( assignment.size() >= VERTICS_NUM ) return true;
int unassigning_variable = select_unassigning_variable (cg, assignment);
int clor = red;
while (clor <= green)
...{
if ( is_consistent (cg, (Color)clor, unassigning_variable) )
...{
ColoredNode new_node;
new_node.node = unassigning_variable;
new_node.hue = (Color)clor;
assignment.push_back (new_node);
cg.nodes_color[unassigning_variable] = (Color)clor;
if ( recursive_coloring (cg, assignment) )
return true;
else
...{
assignment.pop_back ();
cg.nodes_color[unassigning_variable] = noncolor;
}
}
++ clor;
}
if (clor > green)
return false;
}
/**/ /**
* @function: select unassigned variable
* @ para: cg constraint network
* @ para: assignment vector of assigned variable
# @ ret : the no. of unassigned variable has been selected
**/
int select_unassigning_variable (Graph & cg, vector < ColoredNode > & assignment)
... {
if ( !assignment.size () ) return 0;
for (vector<ColoredNode>::reverse_iterator itr = assignment.rbegin ();
itr != assignment.rend ();
++ itr)
...{
ColoredNode lastColored = *itr;
for (int i = lastColored.node; i < VERTICS_NUM; ++i)
...{
if (cg.matrix_of_graph[lastColored.node][i]
&& cg.nodes_color[i] == noncolor)
return i;
}
}
for (int i = 0; i < VERTICS_NUM; ++i)
if (cg.nodes_color[i] == noncolor)
return i;
}
/**/ /**
*@function: check whether the assignment of current unassigned variable
* is consistent with assignment vector or not.
*@para: cg constraint network
*@para: color assignment to current unassigned variable v
*@para: v unassigned variable v
*@ret : value of boolean.
* if the assignment of current unassigned variable is consistent with
* assignment vector, return true, otherwise return false.
**/
bool is_consistent ( Graph & cg, Color color, int v )
... {
bool consistent = true;
for (int i = 0; i < VERTICS_NUM; ++ i)
...{
// detect consistent
if (cg.matrix_of_graph[v][i] && cg.nodes_color[i] == color)
...{
consistent = false;
break;
}
}
return consistent;
}
/**/ /**
*@function: print enumerations Color
*@para: clor instance of enumerations Color
*@ret : string of color corresponding to instance of enumerations Color
**/
string print_color(Color & clor)
... {
switch(clor)
...{
case red:
return "red";
case blue:
return "blue";
case green:
return "green";
default:
return "non color";
}
}
Name: AustraliaColoring.cpp
Copyright: All Right Reserved 2008
Author: li zu-ding <lizuding@gmail.com>
Date: 10-05-08 15:01
Description: Australia Coloring Problem, one of constraint statisfactory problem
can be probed in AI:MA at P.109
*/
#include < string >
#include < vector >
#include < iostream >
using namespace std;
#define VERTICS_NUM 7 // the number of Vertices
enum Color ... {noncolor = 0, red, blue, green} ;
struct Graph
... {
string name[VERTICS_NUM]; // name of node
Color nodes_color[VERTICS_NUM]; // hue of node been colored
int matrix_of_graph[VERTICS_NUM][VERTICS_NUM];
} ;
struct ColoredNode
... {
int node;
Color hue;
} ;
void initial_graph (Graph * );
void create_graph (Graph * );
bool coloring (Graph * );
bool recursive_coloring (Graph & , vector < ColoredNode > & );
int select_unassigning_variable (Graph & , vector < ColoredNode > & );
bool is_consistent (Graph & , Color, int );
string print_color(Color & );
int main ( int argc, char * argv[])
... {
Graph cg;
initial_graph (&cg);
create_graph (&cg);
coloring (&cg);
system ("pause");
return 0;
}
/**/ /**
* @function: initialize one flat constraint network
* @para: cg flat constraint network
* @ret: void
**/
void initial_graph (Graph * cg)
... {
for (int i = 0; i < VERTICS_NUM; ++i)
...{
cg->nodes_color[i] = noncolor;
for (int j = 0; j < VERTICS_NUM; ++j)
cg->matrix_of_graph[i][j] = 0;
}
}
/**/ /**
* @function: create nodes and edges of constraint network
* @para: cp flat constraint network which has been initiliazed
* @ret : void
**/
void create_graph (Graph * cg)
... {
string name;
cout << "input name of vertexs ";
int i = 0;
while (i < VERTICS_NUM)
...{
cin >> name;
cg->name[i] = name;
++ i;
}
int num_of_edges = 0;
cout << "How many edges you contraint graph contain ";
cin >> num_of_edges;
cout << "input edges ";
int head; // the head node of edge
int tail; // the tail node of edge
for (int i = 0; i < num_of_edges; ++i)
...{
cin >> head >> tail;
cg->matrix_of_graph[head - 1][tail - 1] = 1;
cg->matrix_of_graph[tail - 1][head - 1] = 1;
}
}
/**/ /**
*@function: color the constraint network cg
*@para: cg constraint network
*@ret : if there is a complete assignment to the constraint network, return true;
* otherwise, return false
**/
bool coloring (Graph * cg)
... {
vector<ColoredNode> assignment;
if ( recursive_coloring (*cg, assignment) )
...{
for ( vector<ColoredNode>::iterator itr = assignment.begin();
itr != assignment.end(); ++ itr )
cout << (*itr).node + 1 << " " << print_color((*itr).hue) << " ";
return true;
}
return false;
}
/**/ /**
*@function: recursive procedure to color the constraint network
*@para: cg constraint network
*@para: assignation vector to store variable's assigned value
*@ret : if there is a complete assignment to the constraint network, return true;
* otherwise, return false
**/
bool recursive_coloring (Graph & cg, vector < ColoredNode > & assignment)
... {
if ( assignment.size() >= VERTICS_NUM ) return true;
int unassigning_variable = select_unassigning_variable (cg, assignment);
int clor = red;
while (clor <= green)
...{
if ( is_consistent (cg, (Color)clor, unassigning_variable) )
...{
ColoredNode new_node;
new_node.node = unassigning_variable;
new_node.hue = (Color)clor;
assignment.push_back (new_node);
cg.nodes_color[unassigning_variable] = (Color)clor;
if ( recursive_coloring (cg, assignment) )
return true;
else
...{
assignment.pop_back ();
cg.nodes_color[unassigning_variable] = noncolor;
}
}
++ clor;
}
if (clor > green)
return false;
}
/**/ /**
* @function: select unassigned variable
* @ para: cg constraint network
* @ para: assignment vector of assigned variable
# @ ret : the no. of unassigned variable has been selected
**/
int select_unassigning_variable (Graph & cg, vector < ColoredNode > & assignment)
... {
if ( !assignment.size () ) return 0;
for (vector<ColoredNode>::reverse_iterator itr = assignment.rbegin ();
itr != assignment.rend ();
++ itr)
...{
ColoredNode lastColored = *itr;
for (int i = lastColored.node; i < VERTICS_NUM; ++i)
...{
if (cg.matrix_of_graph[lastColored.node][i]
&& cg.nodes_color[i] == noncolor)
return i;
}
}
for (int i = 0; i < VERTICS_NUM; ++i)
if (cg.nodes_color[i] == noncolor)
return i;
}
/**/ /**
*@function: check whether the assignment of current unassigned variable
* is consistent with assignment vector or not.
*@para: cg constraint network
*@para: color assignment to current unassigned variable v
*@para: v unassigned variable v
*@ret : value of boolean.
* if the assignment of current unassigned variable is consistent with
* assignment vector, return true, otherwise return false.
**/
bool is_consistent ( Graph & cg, Color color, int v )
... {
bool consistent = true;
for (int i = 0; i < VERTICS_NUM; ++ i)
...{
// detect consistent
if (cg.matrix_of_graph[v][i] && cg.nodes_color[i] == color)
...{
consistent = false;
break;
}
}
return consistent;
}
/**/ /**
*@function: print enumerations Color
*@para: clor instance of enumerations Color
*@ret : string of color corresponding to instance of enumerations Color
**/
string print_color(Color & clor)
... {
switch(clor)
...{
case red:
return "red";
case blue:
return "blue";
case green:
return "green";
default:
return "non color";
}
}