圖著色所需的最少顏色數
圖著色所需的最少顏色數是一個基本的圖論問題,它包括對頂點進行著色,使得沒有兩個相鄰的頂點具有相同的顏色。確定有效著色所需的最小顏色數量。貪婪著色是一種簡單且常用的技術,它根據頂點的鄰居逐個對頂點進行著色。回溯法也會仔細分析所有顏色分配。基於DSatur的圖著色優先考慮具有最高度和飽和度的頂點。
使用的方法
貪婪著色
回溯法
圖著色
貪婪著色方法
貪婪著色技術使圖著色變得容易。它對第一個頂點進行著色,然後迭代其餘的頂點。它透過檢查其相鄰頂點來為每個頂點分配最小的顏色。這種“貪婪”技術會做出區域性最優的判斷,而不會考慮顏色消耗。貪婪著色易於應用,通常效果很好,儘管它可能無法提供最少的顏色數量。
演算法
將大小為“numVertices”的陣列“colours”的所有成員初始化為-1。
對第一個圖頂點0著色。
對於從1到numVertices-1的每個頂點“v”,執行以下操作
將相鄰頂點的顏色儲存在一個空集合“usedColors”中。
迭代“v”的相鄰頂點
將相鄰頂點的非零顏色新增到“usedColors”中。
從0開始遞增,直到“usedColors”不包含最小的顏色。
在“colours”陣列中為“v”賦予最小的顏色。
找到“colours”陣列中使用的最大顏色,並返回+1作為“minColors”。
示例
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
// Structure to represent an edge in the graph
struct Edge {
int src, dest;
};
// Function to add an edge to the graph
void addEdge(std::vector<std::vector<int>>& graph, int src, int dest) {
graph[src].push_back(dest);
graph[dest].push_back(src);
}
// Greedy Coloring Algorithm
int greedyColoring(const std::vector<std::vector<int>>& graph, int numVertices) {
std::vector<int> colors(numVertices, -1);
colors[0] = 0;
for (int vertex = 1; vertex < numVertices; ++vertex) {
std::unordered_set<int> usedColors;
for (int neighbor : graph[vertex]) {
if (colors[neighbor] != -1) {
usedColors.insert(colors[neighbor]);
}
}
int availableColor = 0;
while (usedColors.count(availableColor) != 0) {
++availableColor;
}
colors[vertex] = availableColor;
}
return *std::max_element(colors.begin(), colors.end()) + 1;
}
int main() {
// Example usage
int numVertices = 6;
std::vector<Edge> edges = {
{0, 1},
{0, 2},
{1, 2},
{1, 3},
{2, 3},
{3, 4},
{4, 5}
};
int numEdges = edges.size();
std::vector<std::vector<int>> graph(numVertices);
for (const auto& edge : edges) {
addEdge(graph, edge.src, edge.dest);
}
int minColorsGreedy = greedyColoring(graph, numVertices);
std::cout << "Minimum number of colors (Greedy Coloring): " << minColorsGreedy << std::endl;
return 0;
}
輸出
Minimum number of colors (Greedy Coloring): 3
回溯法
回溯法是一種查詢所有可行解的方法。在圖著色中,回溯法遞迴地為頂點分配顏色。當出現問題時,它會撤消顏色分配並考慮替代方案。回溯法可以確保對圖著色所需的最小顏色數量,儘管由於其徹底的搜尋,對於大型圖來說,它的計算成本很高。
演算法
將大小為“numVertices”的陣列“colours”的所有成員初始化為-1。
對於從1到numVertices的“numColors”
如果graphColoringUtil(graph, numColors, colours, 0)返回true,則返回“numColors”作為“minColors”。
如果沒有找到可接受的著色,則返回“numVertices”作為“minColors”。
示例
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
// Structure to represent an edge in the graph
struct Edge {
int src, dest;
};
// Function to add an edge to the graph
void addEdge(std::vector<std::vector<int>>& graph, int src, int dest) {
graph[src].push_back(dest);
graph[dest].push_back(src);
}
// Backtracking Algorithm
bool isSafe(int vertex, const std::vector<std::vector<int>>& graph, const std::vector<int>& colors, int color) {
for (int neighbor : graph[vertex]) {
if (colors[neighbor] == color) {
return false;
}
}
return true;
}
bool graphColoringUtil(const std::vector<std::vector<int>>& graph, int numColors, std::vector<int>& colors, int vertex) {
if (vertex == colors.size()) {
return true;
}
for (int color = 0; color < numColors; ++color) {
if (isSafe(vertex, graph, colors, color)) {
colors[vertex] = color;
if (graphColoringUtil(graph, numColors, colors, vertex + 1)) {
return true;
}
colors[vertex] = -1;
}
}
return false;
}
int backtrackingColoring(const std::vector<std::vector<int>>& graph, int numVertices) {
std::vector<int> colors(numVertices, -1);
for (int numColors = 1; numColors <= numVertices; ++numColors) {
if (graphColoringUtil(graph, numColors, colors, 0)) {
return numColors;
}
}
return numVertices;
}
int main() {
// Example usage
int numVertices = 6;
std::vector<Edge> edges = {
{0, 1},
{0, 2},
{1, 2},
{1, 3},
{2, 3},
{3, 4},
{4, 5}
};
int numEdges = edges.size();
std::vector<std::vector<int>> graph(numVertices);
for (const auto& edge : edges) {
addEdge(graph, edge.src, edge.dest);
}
int minColorsBacktracking = backtrackingColoring(graph, numVertices);
std::cout << "Minimum number of colors (Backtracking): " << minColorsBacktracking << std::endl;
return 0;
}
輸出
Minimum number of colors (Backtracking): 3
圖著色方法
複雜的圖著色啟發式演算法DSatur(最大飽和度)減少了顏色使用。首先對度數最高的頂點著色。接下來檢查飽和度,即每個頂點的鄰居使用的顏色數量。為了打破平局,DSatur會對飽和度最高的頂點著色。
這種方法根據頂點的度數和飽和度來最佳化顏色組合。
演算法
將大小為“numVertices”的陣列“colours”初始化為-1。
將大小為“numVertices”的“saturation”陣列初始化為0。
使“saturationMap”為空。
對圖中度數最高的頂點0著色。
更新所選頂點的相鄰頂點的飽和度和saturationMap。
示例
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
// Structure to represent an edge in the graph
struct Edge {
int src, dest;
};
// Function to add an edge to the graph
void addEdge(std::vector<std::vector<int>>& graph, int src, int dest) {
graph[src].push_back(dest);
graph[dest].push_back(src);
}
// Graph Coloring using DSatur Algorithm
int getMaxDegreeVertex(const std::vector<std::vector<int>>& graph, const std::vector<int>& saturation) {
int maxDegree = -1;
int maxDegreeVertex = -1;
for (int vertex = 0; vertex < graph.size(); ++vertex) {
if (saturation[vertex] == -1 && graph[vertex].size() > maxDegree) {
maxDegree = graph[vertex].size();
maxDegreeVertex = vertex;
}
}
return maxDegreeVertex;
}
int dsaturColoring(const std::vector<std::vector<int>>& graph, int numVertices) {
std::vector<int> colors(numVertices, -1);
std::vector<int> saturation(numVertices, -1);
std::unordered_map<int, int> saturationMap;
colors[0] = 0;
for (int vertex = 1; vertex < numVertices; ++vertex) {
for (int neighbor : graph[vertex]) {
if (colors[neighbor] != -1) {
saturation[vertex]++;
saturationMap[colors[neighbor]]++;
}
}
}
while (*std::max_element(colors.begin(), colors.end()) == -1) {
int maxDegreeVertex = getMaxDegreeVertex(graph, saturation);
std::unordered_set<int> usedColors;
for (int neighbor : graph[maxDegreeVertex]) {
if (colors[neighbor] != -1) {
usedColors.insert(colors[neighbor]);
}
}
int availableColor = 0;
while (usedColors.count(availableColor) != 0) {
++availableColor;
}
colors[maxDegreeVertex] = availableColor;
for (int neighbor : graph[maxDegreeVertex]) {
if (colors[neighbor] == -1) {
saturation[neighbor]++;
}
}
saturationMap.clear();
for (int vertex = 0; vertex < numVertices; ++vertex) {
if (colors[vertex] == -1) {
saturationMap[saturation[vertex]]++;
}
}
int maxSaturation = -1;
for (auto& entry : saturationMap) {
if (entry.second > maxSaturation) {
maxSaturation = entry.second;
}
}
std::vector<int> maxSaturationVertices;
for (int vertex = 0; vertex < numVertices; ++vertex) {
if (colors[vertex] == -1 && saturation[vertex] == maxSaturation) {
maxSaturationVertices.push_back(vertex);
}
}
if (maxSaturationVertices.size() > 1) {
int maxDegree = -1;
for (int vertex : maxSaturationVertices) {
if (graph[vertex].size() > maxDegree) {
maxDegree = graph[vertex].size();
maxDegreeVertex = vertex;
}
}
}
else {
maxDegreeVertex = maxSaturationVertices[0];
}
}
return *std::max_element(colors.begin(), colors.end()) + 1;
}
int main() {
// Example usage
int numVertices = 6;
std::vector<Edge> edges = {
{0, 1},
{0, 2},
{1, 2},
{1, 3},
{2, 3},
{3, 4},
{4, 5}
};
int numEdges = edges.size();
std::vector<std::vector<int>> graph(numVertices);
for (const auto& edge : edges) {
addEdge(graph, edge.src, edge.dest);
}
int minColorsDSatur = dsaturColoring(graph, numVertices);
std::cout << "Minimum number of colors (DSatur): " << minColorsDSatur << std::endl;
return 0;
}
輸出
Minimum number of colors (DSatur): 1
結論
總而言之,圖論中的最小顏色問題有很多應用。我們討論了貪婪著色、回溯法和DSatur圖著色來解決這個問題。貪婪著色很簡單,但它並不總是使用最少的顏色。回溯法可以確保最佳答案,但對於更大的網路來說,計算成本很高。DSatur的複雜啟發式演算法考慮頂點的度數和飽和度來最佳化圖著色。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP