#################本文为学习《图论算法及其MATLAB实现》的学习笔记#################
- 全染色以及全色数
图G的顶点和边满足使相邻或关联的元素得到不同的颜色,则称此染色为G的全染色;其所用最少色数称为G的全色数
- 算法用途
给出简单图的染色数尽可能少的全染色方案
- 算法思想
从图上的某个顶点开始染色,然后对其不相邻的顶点进行染色(同色),再对其相关联的每条边进行染色(新色),再对其相关联的边集合中的每条边的不相邻的边进行染色。
重复以上过程。
- 程序参数说明
M: 任意图的邻接矩阵;
k: 全染色数
C: 图顶点的染色方案
W: 图边集合的染色方案,以矩阵形式输出
- 算法的matlab程序详解
function [k,C,W] = graphcodf(M)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 全染色算法 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%% 输入: M: 任意图的邻接矩阵;
%%%%%%%%% 输出: k: 全染色数
%%%%%%%%% C: 图顶点的染色方案
%%%%%%%%% W: 图边集合的染色方案,以矩阵形式输出
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
G = M;
n = size(G,1); % n 为 G 的行数
W = G;
for i = 1:n
for j = 1:(i-1)
W(i,j) = 0; % 使 W 主对角线下三角区元素全为零
end
end
C = zeros(1,n); % C 为1行n列的全零数组
i = 1;
k = 1; % 初始待染色号为 1 色
Z = [1:n]; % 建立一个1到n的数组
while sum(find(C == 0))
%%%%%%%% 对没有染色的顶点染色 %%%%%%%%
if C(1,i) == 0 % 如果第 i 个顶点未被染色
C(1,i) = k; % 将第 i 个顶点染为 k 色
Sn = find(G(i,:) ~= 0); % Sn 为 G 中第i行非零元素的索引值,即找到与当前选中点相邻的顶点
flag = 1;
while flag
tc = setdiff(Z,Sn); % tc 为在 Z 中而不在 Sn 中的元素,即找到与当前选中点不相邻的顶点
if isempty(tc)
flag = 0;
else
c = G(tc(1),:); % c 为 G 的第 tc(1) 行
c(1,tc(1)) = 1; % 使 c 的 (1,tc(1)) 元素为1
C(tc(1)) = k; % 使数组 C 中的第 tc(1) 个元素为k,即将与选中点不相邻的顶点染成 k 色
Sn1 = find(c ~= 0); % Sn1 为 c 中元素不为0的索引值
Sn = union(Sn,Sn1); % Sn(新) 为 Sn 与 Sn1 的并集
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%% 对相应的边集合进行染色 %%%%%%%%
for j = (i+1):n
W1 = W;
if W(i,j) == 1 % 寻找与顶点 i 相关联的边
k = k+1; % 更新待染色号 k
W(i,j) = k; % 对与顶点 i 相关联的边(i,j)染色
W1(:,i) = 0;W1(:,j) = 0; % 将 W1 的第i列和第j列元素变为0
W1(i,:) = 0;W1(j,:) = 0; % 将 W1 的第i行和第j行元素变为0
m = 0;
while sum(sum(W1)) ~= 0 & m == 0
c2 = find(W1 ~= 0); % c2 为 W1 中非零元素索引值
c3 = find(W == 1); % c3 为 W 中元素值为1的索引值
c4 = intersect(c2,c3); % c4 为 c2 与 c3 中相同的元素,即找到与已染色边 (i,j) 不相邻的边
if ~isempty(c4) % 若 c4 非空,即找到与已染色边 (i,j) 不相邻的边
k1 = floor(c4(1) / n); % 对 c4(1)/n 取余
k2 = mod(c4(1),n); % 对 c4(1)/n 取模,即找到与新边相关联的顶点
if k2 == 0
k2 = n;
end
W1(k2,:) = 0;W1(:,k2) = 0; % 将 W1 的第k2行和第k2行元素变为0
W1((k1+1),:) = 0;W1(:,(k1+1)) = 0; % 将 W1 的第k1+1行和第k1+1行元素变为0
if k1+1 < k2
W((k1+1),k2) = k;
else
W(k2,(k1+1)) = k; % 对新边进行染色
end
else
m = 1;
end
end
end
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i = i+1;
k = k+1;
end
%%%%%%%%%%%%%%%% 计算总染色数 %%%%%%%%%%%%%%%%%%%
k = k-1;
m = 0;
for i = 1:k
t1 = find(C == i); % 找到染色为 i 的顶点索引值集合
t2 = find(W == i); % 找到染色为 i 的边索引值集合
t3 = sum(t1);
t4 = sum(sum(t2));
t5 = t3 + t4;
if t5 ~= 0
m = m+1; % 总染色数+1
end
end
k = m;