3.8 Раскраски
3.8.1 Правильные раскраски
Пусть G=(V,E) - неориентированный граф. Произвольная функция f:V®{1,2,...,k}, где k принадлежит множеству натуральных чисел, называется вершинной k-раскраской графа G. Раскраска называется правильной, если f(u)f(v), для любых смежных вершин u и v. Граф, для которого существует правильная k-раскраска, называется k-раскрашиваемым. Минимальное число k, при котором граф G является k-раскрашиваемым, называется хроматическим числом графа и обозначается c(G).
Пример.c(G)=3. Меньшим количеством цветов граф правильно раскрасить нельзя из-за наличия треугольников. Рядом с “кружками” - вершинами графа - указаны номера цветов.
Метод получения правильной раскраски. Идея достаточно проста. Закрашиваем очередную вершину в минимально возможный цвет. Введем следующие структуры данных.
Const Nmax=100; {максимальное количество вершин графа}
Type V=0..Nmax;
Ss=Set of V;
My_array=array[1..Nmax] of V;
Var Gr:My_array;{Gr - каждой вершине графа определяется номер цвета}
Для примера, приведенного выше, массив Gr имеет вид: Gr[1]=Gr[3]=Gr[5]=1; Gr[2]=Gr[4]=Gr[7]=2; Gr[6]=3.
Фрагмент основной логики.
....
;
for i:=1 to N do Gr[i]:=Color(i,0);
;
Поиск цвета раскраски для одной вершины можно реализовать с помощью следующей функции:
function Color(i,t:V):integer;{i - номер окрашиваемой вершины, t - номер цвета, с которого следует искать раскраску данной вершины}
{A - матрица смежности, Gr - результирующий массив}
var Ws:Ss;
j:byte;
begin
Ws:=[ ];
for j:=1 to i-1 do {формируем множество цветов, в которые окрашены смежные вершины с меньшими номерами}
if A[j,i]=1 then Ws:=Ws+[Gr[j]];
j:=t;
repeat {поиск минимального номера цвета, в который можно окрасить данную вершину}
Inc(j);
until Not(j in Ws);

Color:=j;
end;
Пример. Получаем правильную раскраску: Gr[1]=1, Gr[2]=Gr[4]=2, Gr[3]=3, Gr[5]=4. Однако минимальной раскраской является: Gr[1]=1, Gr[2]=Gr[5]=2, и Gr[3]=Gr[4]=3, и хроматическое число графа равно трем.
3.8.2. Поиск минимальной раскраски вершин графа
Метод основан на простой идее[7], и в некоторых случаях он дает точный результат. Пусть получена правильная раскраска графа, q - количество цветов в этой раскраске. Если существует раскраска, использующая только q-1 цветов, то все вершины, окрашенные в цвет q, должны быть окрашены в цвет g, меньший q. Согласно логике формирования правильной раскраски вершина была окрашена в цвет q, потому что не могла быть окрашена в цвет с меньшим номером. Следовательно, необходимо попробовать изменить цвет у вершин, смежных с рассматриваемой. Но как это сделать? Найдем вершину с минимальным номером, окрашенную в цвет q, и просмотрим вершины, смежные с найденной. Попытаемся окрашивать смежные вершины не в минимально возможный цвет. Для этого находим очередную смежную вершину и стараемся окрасить ее в другой цвет. Если это получается, то перекрашиваем вершины с большими номерами по методу правильной раскраски. При неудаче, когда изменить цвет не удалось или правильная раскраска не уменьшила количества цветов, переходим к следующей вершине. И так, пока не будут просмотрены все смежные вершины.
Опишем логику, используя функцию Color предыдущего параграфа.
var MaxC,MinNum,i:V;
procedure MaxMin(var c,t:V);
begin
...
end;
procedure Change(t:V);
begin
...
end;
begin
;
for i:=1 to N do Gr[i]:=Color(i,0);{первая правильная раскраска}
MaxC:=0;MinNum:=0;
repeat
;
;
until MaxC=Gr[MinNum];
;
end.
Если работа процедуры MaxMin достаточно очевидна, то Change требует дальнейшего уточнения.
procedure Change(t:V);
var r,q:V;
Ws:Ss;
function MaxCon(l:V;Rs:Ss):V;{находим смежную с l вершину с наибольшим номером и не принадлежащую множеству Rs}
var i:V;
begin
for i:=l-1 downto 1 do
if (A[l,i]=1) and( not(i in Rs) then begin MaxCon:=i;
exit
end
MaxCon:=0;
end;
begin
Ws:=[];
q:=MaxCon(t,Ws);
while q0 do begin
r:=Color(q,Gr[q]);
if r
else Ws:=Ws+[q];
q:=MaxCon(t,Ws);
end;
end;
Осталось заметить, что при изменении цвета у вершин с номерами, большими значения t, по методу правильной раскраски следует запоминать в рабочих переменных значения Gr и MaxC, так как при неудаче ( раскраску не улучшим) их необходимо восстанавливать, и на этом закончить уточнение логики.
При любом упорядочении вершин допустимые цвета j для вершины с номером i удовлетворяют условию ji . Это очевидно, так как вершине i предшествует i-1 вершина, и, следовательно, никакой цвет j>i не использовался. Итак, для вершины 1 допустимый цвет 1, для 2 - цвет 1 и 2 и так далее. С точки зрения скорости вычислений вершины следует помечать так, чтобы первые q вершин образовывали наибольшую клику графа G. Это приведет к тому, что каждая из этих вершин имеет один допустимый цвет и процесс возврата в алгоритме можно будет заканчивать при достижении вершины из этого множества.


В алгоритме рассматриваются только вершины смежные с вершиной, окрашенной в максимальный цвет. Однако следует работать и с вершинами являющимися смежными для смежных. На рисунке приведены примеры графов и их раскраски. Первая цифра в круглых скобках обозначает значение цвета при правильной раскраске, вторая - при минимальной.


Для графов на первом и третьем рисунках алгоритм дает правильный результат. Для графа на втором рисунке необходимо просматривать вершины, не смежные для вершины с номером 6, а для этого необходимо модифицировать алгоритм. Самый интересный случай на последнем рисунке. Мы не можем получить минимальную раскраску с помощью рассмотренного алгоритма, хотя она, конечно, существует и совпадает с предыдущей.