全染色算法及其matlab程序详解

#################本文为学习《图论算法及其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;

你可能感兴趣的:(图论,算法,图论,matlab)