地圖染色問題


四色定理是一個著名的數學定理:如果在平面上划出一些鄰接的有限區域,那么可以用四種顏色來給這些區域染色,使得每兩個鄰接區域染的顏色都不一樣[2][3];另一個通俗的說法是:每個(無飛地的)地圖都可以用不多於四種顏色來染色,而且不會有兩個鄰接的區域顏色相同。被稱為鄰接的兩個區域是指它們有一段公共的邊界,而不僅僅是一個公共的交點。例如右圖左下角的圓形中,紅色部分和綠色部分是鄰接的區域,而黃色部分和紅色部分則不是鄰接區域。

“是否只用四種顏色就能為所有地圖染色”的問題最早是由一位英國制圖員在1852年提出的,被稱為“四色問題”或“四色猜想”。人們發現,要證明寬松一點的“五色定理”(即“只用五種顏色就能為所有地圖染色”)很容易,但四色問題卻出人意料地異常困難。曾經有許多人發表四色問題的證明或反例,但都被證實是錯誤的。

1976年,數學家凱尼斯·阿佩爾和沃夫岡·哈肯借助電子計算機首次得到一個完全的證明,四色問題也終於成為四色定理。這是首個主要借助計算機證明的定理。這個證明一開始並不為許多數學家接受,因為不少人認為這個證明無法用人手直接驗證。盡管隨着計算機的普及,數學界對計算機輔助證明更能接受,但仍有數學家希望能夠找到更簡潔或不借助計算機的證明。

 

程序代碼:

#include <stdio.h>

#define N 6                                                                     /* N表示區域個數 */

int s[N];                                                                       /* 棧s[i]來表示地圖的區域的顏色序號 */

void MapColor( int dist[N][N], int s[N] )
{
    int color, area, k, i;                                                  /* color代表顏色,area 表示當前要染色的是第幾個區域,k表示已經染色區域的顏色 */
    s[0]    = 1;                                                            /* 第一個區域先着色為顏色1 */
    area    = 1;                                                            /* 從第二區域開始試探染色 */
    color    = 1;                                                            /* 從第一種顏色開始試探 */
    while ( area < N )                                                      /* 是否全部染色完畢 */
    {
        while ( color <= 4 )
        {
            k = 0;                                                  /* 對每一個區域,都從第一個區域的顏色開始比較。 */
            while ( (k < area) && (s[k] * dist[area][k] != color) ) /* 判斷是否重色 */

/* 這個循環判定條件是整個算法的關鍵,理解了這個,整個算法就很easy了,所以小夢就啰嗦幾句吧。  dist[area][k]表示當前即將染色區域和已經染色的第K個區域是否相鄰。s[k]*dist[area][k] 若K區域和area區域相鄰,則其表示當前第K個區域的顏色,若不相鄰,則其值為0,則肯定不會重色,就可以將color復制給當前區域area的顏色s[k].解釋的有些費勁,大家可以直接復制代碼,運行一下,在對着圖上的顏色跟着代碼走幾步就會理解了。 */
                k++;
            if ( k < area )
                color++;                                        /* area 區域與K區域重色 */
            else{
                s[area] = color;                                /* 保存area區域的顏色 */
                area++;                                         /* 准備顏色下一個區域 */
                if ( area >= N )
                    break;
                color = 1;                                      /* 每次都從第一個顏色開始試探 */
            }
        }
        if ( color > 4 )                                                /* area沒有找到合適的顏色,需要進行回溯 */
        {
            area    = area - 1;                                     /* 回溯並修改area-1域並用顏色 */
            color    = s[area] + 1;  將 預 備 要染色的顏色換 為 當前 棧 頂 區 域的 一 個 顏色
        }
    }

    printf( “ 地 圖 區 域 標 號 為 1 ~6的染色情況 為 : \ n ” );
    for ( i = 0; i < N; i++ )
    {
        printf( “ NO.% d: ”, i + 1 );
        switch ( s[i] )
        {
        case 0: printf( “ WRONG MAP !\ n ” ); break;
        case 1: printf( “ RED \ n ” ); break;
        case 2: printf( “ BLUE \ n ” ); break;
        case 3: printf( “ GREEN \ n ” ); break;
        case 4: printf( “ YELLOW \ n ” ); break;
        default: printf( “ 什么的什么啊 ! 1 ″ ); break;
        }
    }
}


int main()
{
    int    dist[N][N] = { { 0, 1, 1, 1, 1, 1 }, /* 地圖的鄰接矩陣 */
                   { 1, 0, 1, 1, 0, 0 },
                   { 1, 1, 0, 1, 1, 1 },
                   { 1, 0, 1, 0, 0, 1 },
                   { 1, 1, 1, 0, 0, 1 },
                   { 1, 0, 1, 1, 1, 0 },};
    int    s[N] = { 0 };
    MapColor( dist, s );
    return(0);
}
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM