四色標記算法

四色標記算法

著名的四色定理,無需贅述。
然而在實際使用過程中會發現,四色算法過於複雜並且時間花銷巨大,四個顏色的限制過於苛刻。因此有人提出了五色算法
如果條件允許,將條件鬆弛一下就可以極大的提高運算速度。
參考這篇博文第一個算法,採取樸素的“試錯,回溯”的思路,稍微修改下,所有參數都是從 0 開始計數:

/*!
 * \brief This method labels the regions of a map
 * \param Adj: input adjacent matrix
 * \param Record: output region facet label
 * \param num_regions: number of regions
 * \param num_colors: available colors
 */
int RelaxedColorLabeling(int *Adj, int *Record, int num_regions, int num_colors)
{
    if (num_colors < 4)
        return -1;

    int region_idx = 0, color_idx = 0;
    while (region_idx < num_regions)
    {
        while (color_idx >= num_colors)
        {
            region_idx--;
            if (region_idx < 0)
            {
                std::cerr << "Color Labeling failed!" << std::endl;
                return -1;
            }
            color_idx = Record[region_idx] + 1;
        }

        // test if current color is suitable
        bool change_color = false;
        for (int neigh_idx = 0; neigh_idx < region_idx; neigh_idx++)
        {
            if (Adj[region_idx * num_regions + neigh_idx] == 1 &&
                Record[neigh_idx] == color_idx)
            {
                change_color = true;
                break;
            }
        }
        // try another color
        if (change_color)
            color_idx++;
        else
        {
            Record[region_idx] = color_idx;
            region_idx++;
            color_idx = 0;
        }
    }

    int max_color = 0;
    for (int i = 0; i < num_regions; i++)
    {
        if (Record[i] > max_color)
            max_color = Record[i];
    }
    std::cerr << "Used color= " << max_color << std::endl;

    return 0;
}

經實測,在圖達到 40k 級別,只有 4 個顏色可供選擇的時候,時間花銷至少十幾個小時,而內存開銷達到了5G了,幾乎不能使用。如果將可供選擇的顏色提高到 5 個的時候,只需要數秒就能解決問題。
而空間開銷的問題可以使用 Eigen sparse matrix 有效的解決。如果將可供選擇顏色提高到高於 5(例如 8),實驗表明實際使用的顏色一般也就到 5。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章