简体   繁体   English

所有可能的数组组合(并行编程)-最佳图形着色

[英]All possible array combinations (parallel programming) - Optimal Graph Colouring

I'm doing again a work of optimal Graph Coloring, so, I need to generate all possible color combinations (the array represents the color for each node) for a graph. 我再次进行最佳图形着色的工作,因此,我需要为图形生成所有可能的颜色组合(数组代表每个节点的颜色)。 I got a lot of help here, as you can see in this question: 正如您在以下问题中所看到的,我在这里得到了很多帮助:

Generate all possible array combinations in C - Optimal Graph Colouring 在C-最佳图形着色中生成所有可能的数组组合

For now, my code is: 现在,我的代码是:

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

The output, in this case, would be: 在这种情况下,输出为:

0 0 0
0 0 1
0 1 0
0 1 1
0 1 2

If 0 means blue and 2 means red, in Graph coloring, red-red-red is the same thing of blue-blue-blue. 如果0表示蓝色,而2表示红色,则在Graph着色中,红色-红色-红色与蓝色-蓝色-蓝色相同。 That's what my code do: it generates all possible different color combinations for a graph. 那就是我的代码所做的:它为图形生成所有可能的不同颜色组合。

Now I need to improve my code, but I couldn't think of anything. 现在我需要改进代码,但是我什么也没想到。 I want it to generate arrays only with a given number of colors, because I'm using pthreads and I want each thread to deal with the graph with a number of colors. 我希望它仅生成具有给定颜色数的数组,因为我使用的是pthreads,并且我希望每个线程都可以处理具有多种颜色的图形。

For example: with 2 colors, the output would be: 例如:使用2种颜色,输出​​将是:

0 0 1
0 1 0
0 1 1

And with 3 colors: 并具有3种颜色:

1 2 3

I don't need it to create arrays with less colors than the number set, as there's another threads doing this. 我不需要它来创建颜色比设置的颜色少的数组,因为还有其他线程在执行此操作。

Could any of you guys help me with my code? 你们中的任何人都可以帮助我编写代码吗? Sorry if I didn't made myself clear at any point. 抱歉,如果我在任何时候都没有明确表示自己。

so you need a systematic enumeration of all surjective mappings from the set V (#V = n) of vertices in your graph into a set of k elements representing k different colors along with the additional constraint that the map restricted to vertices with the least index among all other vertices associated with the same color must be strictly monotone (as you are not interested in the identity of the respective color). 因此,您需要系统地枚举所有从图的顶点集V (#V = n)到代表k种不同颜色的k元素的集合,以及将图限制为索引最小的顶点的附加约束与相同颜色关联的所有其他顶点之间,必须严格是单调的(因为您对各个颜色的标识不感兴趣)。

let's assume the number of colors be fixed. 让我们假设颜色的数量是固定的。 choose the least indices of the color representatives first, i_1, ..., i_k . 首先选择颜色代表的最小索引i_1, ..., i_k by definition, i_1 < ... < i_k . 根据定义, i_1 < ... < i_k for any of remaining vertices v , i_j < v < i_(j+1) , its color can be chosen freely from { 1, ..., j } . 对于任何剩余顶点vi_j < v < i_(j+1) ,其颜色可以从{ 1, ..., j }自由选择。

this can be implemented by the following code: 这可以通过以下代码实现:

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

caveat: the above code does compile and run, and its results appear to be correct. 注意:上面的代码确实可以编译和运行,其结果似乎是正确的。 of course its far form being formally verified ... ;-). 当然,其远端形式已被正式验证... ;-)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM