我正在做一个最佳图形着色的工作,所以,我需要为图形生成所有可能的颜色组合(数组代表每个节点的颜色)。我在这里得到了很多帮助,正如你在这个问题中看到的那样:
Generate all possible array combinations in C - Optimal Graph Colouring
目前,我的代码是:
void generatearray( int array[], int array_size, int idx = 0, int fixed = 0 )
{
int i;
if ( idx == array_size )
{
putchar('\n');
for( i = 0; i < array_size; i++ ) printf( "%i ", array[i] );
} else {
for( i = 0; i <= 3; i++ )
{
if ( fixed == i )
{
fixed++;
array[idx] = i;
return generatearray( array, array_size, idx + 1, fixed );
}
array[idx] = i;
generatearray( array, array_size, idx + 1, fixed );
}
}
}
int arr[3];
generatearray( arr, 3 );
在这种情况下,输出将是:
0 0 0
0 0 1
0 1 0
0 1 1
0 1 2
如果0表示蓝色,2表示红色,则在图表着色中,红 - 红 - 红色与蓝 - 蓝 - 蓝色相同。这就是我的代码所做的:它为图形生成所有可能的不同颜色组合。
现在我需要改进我的代码,但我想不出任何东西。我希望它只使用给定数量的颜色生成数组,因为我使用的是pthreads,我希望每个线程都能处理具有多种颜色的图形。
例如:有2种颜色,输出为:
0 0 1
0 1 0
0 1 1
有3种颜色:
1 2 3
我不需要它来创建颜色少于数字集的数组,因为还有另外一个线程这样做。
你们中的任何人可以帮助我使用我的代码吗?对不起,如果我在任何时候都没有说清楚。
答案 0 :(得分:1)
所以你需要系统地枚举从图中顶点集V (#V = n)
到表示k
个不同颜色的k
个元素的所有主观映射以及附加约束限制在与相同颜色相关的所有其他顶点中索引最少的顶点的地图必须严格单调(因为您对相应颜色的标识不感兴趣)。
让我们假设颜色的数量是固定的。首先选择颜色代表的最小索引i_1, ..., i_k
。根据定义,i_1 < ... < i_k
。
对于任何剩余顶点v
,i_j < v < i_(j+1)
,其颜色可以从{ 1, ..., j }
自由选择。
这可以通过以下代码实现:
/*
* sample values
* K ist to be substituted with the number of colors to use and thus in actual usage scenarios will be a parameter of thread instantiation
*/
const K = 4;
const N = 10;
void
next_pattern ( int *out, int set_up_to, int *mins, int mins_seen ) {
int i;
int choice;
/* in-place updating: only elements 1..set_up_to are valid */
if (set_up_to < N) {
if (set_up_to + 1 == mins[mins_seen+1]) {
out[set_up_to + 1] = mins_seen+1;
next_pattern ( out, set_up_to + 1, mins, mins_seen+1 );
}
else {
for ( choice = 1; choice <= mins_seen; choice++ ) {
out[set_up_to + 1] = choice;
next_pattern ( out, set_up_to + 1, mins, mins_seen );
}
}
}
else {
/* coloring complete */
printf("[");
for (i=1; i <= N; i++) {
printf(" %u ", out[i]);
}
printf("];\n");
}
} /* next_pattern */
void
next_mindist ( int *mins, int issued, int *out ) {
int lo;
/* in-place updating: only elements 1..issued are valid */
if (issued < K) {
for ( lo = mins[issued] + 1; lo < N - issued; lo++ ) {
mins[issued+1] = lo;
next_mindist ( mins, issued+1, out );
}
}
else {
// min mapping complete
next_pattern ( out, 0, mins, 0 );
}
} /* next_mindist */
void main ( char **argv, int *argc ) {
/* in-place arrays
* mins: minimum vertex index of color <index>
* out: current mapping vertex -> color (mostly partial during processing)
*/
int *mins = (int *) calloc ( sizeof(int), K + 2 ); /* supporting indices 1 .. K and upper guard to avoid conditional statements */
int *out = (int *) calloc ( sizeof(int), N + 1 ); /* supporting indices 1 .. N */
next_mindist ( mins, 0, out );
}
警告: 上面的代码编译并运行,其结果出现是正确的。当然它的远程形式正式验证...... ;-)。