C++_地圖四色着色

​​​​​​

  1. 問題描述

問題描述:地圖四色着色

給已知的地圖(比如中國地圖)着色,請設計地圖着色軟件,對個區域(各省)進行着色,要求相鄰區域(省)所使用的顏色不同,並保證使用的顏色最少(最少是四色)。

  1. 設計思路

設計思路:

數據結構的設計:地圖可以採用圖的數據結構,每個省爲一個節點,邊表示對應的兩個省相鄰。
  算法設計:設計着色算法,保證鄰接點不是同一種顏色。

算法實現:

初始狀態:集合A元素放入cq中,Result及newr置零,設置組號group=1,group1,2,3,4分別代表顏色紅色,藍色,黃色,綠色。

當第1個元素出隊時。將R矩陣中第1行元素中的“1”拷入newr向量對應位置;凡是與第一元素有衝突的元素處均置爲“1”。這裏說明序號爲2的元素不能進入第一組,則應將元素2出隊後重新入cq的隊尾。繼續將元素3出隊,並將R矩陣中第三行元素中的“1”拷入newr向量對應位置;如此繼續,直到9個元素依次出隊後,由newr單元中爲“0”的單元序號構成第1組,將“1”標誌放入Result向量對應單元中;將group=2,newr清零,重新對cq中剩餘的元素重複上述操作,可得第2組元素,第3組元素……直到cq中front=rear,隊空,運算結束。

數據結構:

n——區域(省份)個數;

m——爲着色數4

a[n][n]爲鄰接矩陣。

循環隊列cq[0:n-1],存放集合a的元素;

數組Result[1:n]用以存放每個元素的分組號;

newr[1:n]爲工作數組。

算法描述:

MAP COLORING(R, n, cq, newr, Result)

  1. Input(n,a[n][n])//輸入區域個數及其鄰接情況//
  2. FOR  k=0  TO  n-1  cq[k]←k+1;   //n個元素存入循環隊列cq//
  3. front←n-1; rear←n-1;   //頭尾指針賦初值//
  4. FOR  K=1  TO  n  newr[k]←0    //newr向量置初值//
  5. group←1; pre←0;  //group爲當前組號,pre爲前一個出隊元素編號,初值爲零//(pre←9);
  6. fi=.t.  
  7. WHILE   rear≠front.or.fi=.t.  DO  //隊列非空//
  8. Fi=.f.
  9.    front←front+1;   IF  front=n+1  THEN  front←1;
  10.    I←cq[front];    //I爲當前出隊元素//
  11. IF  I<pre
  12. THEN  //重新開闢新組//
  13. group←group+1; Result[I]←group;   //記錄組號//
  14. FOR  k=1  TO   n  newr[k]←R[I, k]
  15. ELSE 
  16. IF newr[I]≠0
  17.   THEN   //發生衝突元素,重新入隊//
  18.   rear=rear+1;   IF  rear=n+1  THEN  rear=1;
  19.   cq[rear]←I
  20.   ELSE    //可以分在當前組//
  21.       Result[I]←group;
  22.       FOR   k=1  TO  n
  23.       Newr[k]←newr[k]+R[I, k];
  24. pre←I
  25. END(WHILE)
  26. Output(result)
  1. 測試用例及結果說明

測試用例:

區域個數n=9;

各個區域的接壤情況爲:

第1組相鄰區域編號爲:1,2

第2組相鄰區域編號爲:2,3

第3組相鄰區域編號爲:3,4

第4組相鄰區域編號爲:4,5

第5組相鄰區域編號爲:5,6

第6組相鄰區域編號爲:6,7

第7組相鄰區域編號爲:7,8

第8組相鄰區域編號爲:8,9

第9組相鄰區域編號爲:1,3

第10組相鄰區域編號爲:1,4

第11組相鄰區域編號爲:1,5

地圖組成的鄰接矩陣爲:

0 1 1 1 1 0 0 0 0

1 0 1 0 0 0 0 0 0

1 1 0 1 0 0 0 0 0

1 0 1 0 1 0 0 0 0

1 0 0 1 0 1 0 0 0

0 0 0 0 1 0 1 0 0

0 0 0 0 0 1 0 1 0

0 0 0 0 0 0 1 0 1

0 0 0 0 0 0 0 1 0

着色結果爲:

區域1爲紅色

區域2爲藍色

區域3爲黃色

區域4爲藍色

區域5爲黃色

區域6爲紅色

區域7爲藍色

區域8爲紅色

區域9爲藍色

  1. 設計及測試過程

第一步:提出問題;

第二步:問題轉換;

第三步:算法構思;

第四步:僞碼描述;

第五步:代碼編寫;

第六步:代碼測試;

第七步:代碼修正;

參考書籍:《計算機軟件技術基礎》 清華大學出版社 第三版

#include <iostream>
using namespace std;
#define N 64
int main()
{
	int a[N][N], i, j, k, n, b, c, d, e, f, cq[N], result[N], newr[N], front, rear, group, pre;
	for(i=0;i<N;i++)
		for(j=0;j<N;j++)
			a[i][j]=0;
	cout<<"請輸入地圖區域個數"<<endl;
	cin>>n;
	cout<<"各區域編號分別爲:"<<endl;
	for(i=0;i<n;i++)
		cout<<i+1<<", ";
	cout<<"請輸入各個區域的接壤情況(結束輸入請輸入'0')"<<endl;
	i=0;
	while(1)
	{
		cout<<"第"<<i+1<<"組相鄰區域編號爲:"<<endl;
		cin>>b;
		if(b==0)
			break;
		cin>>c;
		a[b-1][c-1]=1;
		a[c-1][b-1]=1;
		i++;
	}
	cout<<"地圖組成的鄰接矩陣爲:"<<endl;
	for(i=0;i<n;i++)
	{
		for(j=0;j<n;j++)
			cout<<a[i][j]<<" ";
		cout<<endl;
	}
	for(i=0;i<N;i++)
		cq[i]=i+1;
	front=N-1;
	rear=N-1;
	for(i=0;i<N;i++)
		newr[i]=0;
	group=1;
	pre=0;
	f=0;
	while(rear!=front||f==0)
	{
		f=1;
		front=(front+1)%N;
		i=cq[front];
		if(i<pre)
		{
			group++;
			result[i-1]=group;
			for(j=0;j<N;j++)
				newr[j]=a[i-1][j];
		}
		else
		{
			if(newr[i-1]!=0)
			{
				rear=(rear+1)%N;
				cq[rear]=i;
			}
			else
			{
				result[i-1]=group;
				for(j=0;j<N;j++)
					newr[j]=newr[j]+a[i-1][j];
			}
		}
		pre=i;
	}
	cout<<"着色結果爲:"<<endl;
	for(i=0;i<n;i++)
	{
		if(result[i]==1)
			cout<<"區域"<<i+1<<"爲紅色"<<endl;
		if(result[i]==2)
			cout<<"區域"<<i+1<<"爲藍色"<<endl;
		if(result[i]==3)
			cout<<"區域"<<i+1<<"爲黃色"<<endl;
		if(result[i]==4)
			cout<<"區域"<<i+1<<"爲綠色"<<endl;
	}
	system("pause");
	return 0;
}

 

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