独立集是一组顶点或边,其中任意两个顶点或边的对彼此不相邻。假设独立集意味着独立的顶点集,我们必须找到一组这样的顶点,其中任意两对顶点彼此不相邻。使用图形着色我们可以解决这个问题。我们将修改图形着色方法,因为我们将只使用两种颜色,即 0,1,而不是使用不同的颜色。所以我们假设那些标记为 0 的顶点是集合的一部分,而其他的则不是。所以标记为 0 的顶点没有任何标记为 0 的相邻顶点。
方法:
有关的基本思想 Java引用调用的功能和向量的概念是必须的。此外,我们假设索引标记为顶点名称,该索引处的向量中的值作为该顶点的颜色(0 或 1)。最初找到的变量设置为 false,即未找到所需大小的集合。我们将使用单词removed 和任何顶点的颜色“0”。两者都表示可以从图中删除特定顶点并可以包含在集合中的同一件事。
程序:
它在程序中使用的方法的帮助下进行说明,以供理解目的顺序解释如下:
- 程序的输入是图的一个相邻矩阵,这里给出了一个集合的最大大小。首先,我们必须制作图矩阵的邻接表。现在我们将为每个顶点运行一个循环,首先给第 i 个顶点颜色“0”,然后找到所有其他可能的顶点颜色“0”(包括在集合中)。
- 因此,我们正在制作一个名为“color”的向量,并使用所有索引(顶点)的颜色为“1”,将第 i 个顶点的颜色初始化为“0”。然后,我们将使用Util()方法检查所有可以赋予颜色“0”(包含在集合中)的可能顶点,如下所述。
- Util() 方法调用另外两个名为can_remove()和remove_all() 的方法。此方法的主要目的是删除所有可以从颜色向量中删除的顶点,如果删除了“第 i 个”顶点(指定为“0”)。该方法查找使用上述两种方法可以删除的顶点的索引。然后它为该顶点分配“0”,并继续这样做,直到没有更多的顶点需要删除。它返回修改后的颜色向量。
- can_remove() 方法检查是否可以毫无困难地将给定的顶点指定为“0”。它比较给定顶点的每个邻居顶点,并检查是否有任何邻居为“0”。如果在这种情况下没有顶点,则该顶点被分配一个值“0”。它返回一个布尔值,指示是或否。
- remove_all() 方法用于查找顶点,该顶点的删除每次都会产生大量要删除的顶点。这一步主要是贪心的做法。它找到在删除特定顶点后可以删除的顶点数,并找到所有这些数字的最大值,并返回该特定顶点的索引,其删除将导致删除最大顶点。然后在 Util() 方法中删除这个顶点。
- 所以到目前为止我们已经了解了 Util()、remove_all() 和 can_remove() 方法在做什么。基本上,对于每个“第 i”个颜色向量,“第 i 个”顶点为“0”,这些方法尝试找到可以从图中删除的顶点数(分配为“0”)。所以在调用这个 Util() 方法之后,颜色向量正在被修改,并且可以分配为“0”的顶点数被赋予该值。
- 现在因为颜色向量被修改了,所以我们必须计算分配为’0’的顶点的数量(这意味着可以包含在集合中的顶点)。如果计数大于所需的大小,那么我们已经找到了解决方案,并且 found 变量被设置为 true 并且输出完成并且循环中断,否则它将继续尝试下一个颜色向量并删除下一个顶点。计数由Util3()方法完成。
- 尽管如此,我们还是错过了边缘情况,如下图所示。这里不是给第一个图中的第二个着色顶点着色,而是为它的一个相邻顶点着色,如第二个图所示。这样做我们将在集合中得到许多顶点。因此,对于每个颜色向量,我们将调用 Util2() 方法。只有当某个顶点的值为“1”(未着色)并且只有一个着色的相邻顶点时才会出现这种情况,如上所示。
- *Util2() 方法基本上检查每个未被移除的顶点(具有“1”),该顶点是否只有一个相邻的顶点着色(值“1”)。如果找到任何这样的顶点,则此方法将在顶点之间交换颜色并调用 Util() 方法以刷新颜色向量。这可以很容易地证明,这种方法将始终要么增加带有“0”的顶点的数量,要么数量保持不变。它永远不会减少彩色顶点的数量。
因此,这种方法证明对我们的方法特别有益。
Note: Why it always increases?
There is only swap of color between two adjacent vertices. Hence, the count will remain same till now. Thinking for rest of the configuration we can say that before swap the newly colored vertex is not having more than one colored adjacent vertex. So after swap also there are no adjacent vertices to it that are colored. This will maintain the property of independent sets.
执行:
到目前为止,如果我们有任何解决方案,那么我们将设置 found true 否则将保存颜色矢量的配置以供进一步使用。所有这些都是针对循环中的每个“第 i 个”顶点完成的,修改后的颜色向量存储在程序中名为set_found的向量向量中。
如果到目前为止还没有找到所需的大小,那么我们将尝试我们将执行所有生成的配置集的成对交集的最后一种情况。
在此,我们将再次从颜色向量开始并保持生成的配置重复相同的过程。唯一的区别是我们不会从将“0”分配给第 i 个顶点开始。取而代之的是,我们将检查那些标有“0”并且对两个集合都通用的顶点的配置对(在 set_found 中)。它们将在颜色向量和最佳部分中标记为“0”,上述过程将相同,以检查可能的集合的最大大小和上述情况。
例子
Java
// Java Program to Find Independent Sets in a Graph
// by Graph Coloring
// Importing input output classes
import java.io.*;
// Importing utility classes from java.util package
import java.util.*;
// Class 1
// Helper class
class GFGUTIL {
// Method 1
// Utility function to label maximum vertices with
// 0,that can be included in the set
public static void
Util(Vector > adjacency_list,
Vector color)
{
int a = 0;
// Condition check
while (a != -1) {
a = remove_all(adjacency_list, color);
if (a != -1)
color.set(a, 0);
}
}
// Method 2
// This method that tries whether it is possible to
// remove any adjacent vertex of any removed vertex
public static void
Util2(Vector > adjacency_list,
Vector color, int j)
{
int cnt = 0;
Vector tmp_color = new Vector();
for (int g = 0; g < color.size(); ++g)
tmp_color.add(color.get(g));
for (int i = 0; i < color.size(); ++i) {
if (tmp_color.get(i) == 1) {
int sum = 0;
int idx = -1;
for (int g = 0; g < adjacency_list.get(i).size(); ++g)
if (tmp_color.get(adjacency_list.get(i).get(g)) == 0) {
idx = g;
sum++;
}
if (sum == 1 && color.get(adjacency_list.get(i).get(idx))== 0) {
tmp_color.set(adjacency_list.get(i).get(idx), 1);
tmp_color.set(i, 0);
Util(adjacency_list, tmp_color);
++cnt;
}
if (cnt > j)
break;
}
}
for (int g = 0; g < color.size(); ++g)
color.set(g, tmp_color.get(g));
}
// Method 3
// Returning the number of vertices
// that can't be included in the set
public static int Util3(Vector color)
{
int cnt = 0;
for (int i = 0; i < color.size(); i++)
if (color.get(i) == 1)
++cnt;
return cnt;
}
// Method 4
// Returning the index of the vertex
public static int
remove_all(Vector > adjacency_list, Vector color)
{
int a = -1, max = -1;
for (int i = 0; i < color.size(); ++i) {
if (color.get(i) == 1 && can_remove(adjacency_list.get(i), color) == 1) {
Vector tmp_color = new Vector();
for (int j = 0; j < color.size(); ++j)
tmp_color.add(color.get(j));
tmp_color.set(i, 0);
int sum = 0;
for (int j = 0; j < tmp_color.size(); ++j)
if (tmp_color.get(j) == 1 && can_remove(adjacency_list.get(j), tmp_color) == 1)
++sum;
if (sum > max) {
max = sum;
a = i;
}
}
}
// Index of the vertex
return a;
}
// Method 5
// To check whether a vertex can be removed or not
public static int can_remove(Vector adj_list, Vector color)
{
int check = 1;
for (int i = 0; i < adj_list.size(); ++i)
if (color.get(adj_list.get(i)) == 0)
check = 0;
return check;
}
}
// Class 2
// Main class
public class GFG {
// Main driver method
public static void main(String[] args) throws Exception
{
// inputting the graph and forming it's adjacency
// list.
// Display message for better readibility
System.out.println("The number of vertices in the graph is taken as 4");
// Custom input is taken here
int n = 4;
// Creating a vector object for adjacency matrix.
Vector > adjacency_matrix = new Vector >(n, (n));
// Input matrix is
// 0111
// 1011
// 1101
// 1110
// Nested for loops for iterations
for (int i = 0; i < n; ++i) {
Vector adj = new Vector(n);
for (int j = 0; j < n; ++j)
if (i == j)
adj.add(0);
else
adj.add(1);
adjacency_matrix.add(adj);
}
// Creating a vector object for adjacency list
Vector > adjacency_list
= new Vector >();
// Nested for loops for iterations
for (int i = 0; i < n; ++i) {
Vector adj_list = new Vector();
for (int j = 0; j < n; ++j) {
if (adjacency_matrix.get(i).get(j) == 1)
adj_list.add(j);
}
adjacency_list.add(adj_list);
}
// Display message only for
// taking the minimum size of the set required.
System.out.println("The minimum size of the set required is taken as 2");
// Declaring and initializing variable with
// least size of the set required
int x = 2;
// Complement of the size
int y = n - x;
int found = 0;
int size = 0;
int min = n + 1;
// Creating a set found vector to
// store all the possible set
Vector > set_found = new Vector >();
// Display message
System.out.println("Searching for the set");
for (int i = 0; i < n; ++i) {
// If set is found
if (found == 1)
// Hault the further execution of Program
break;
// Cover vector to have the state of all the
// vertices initially
Vector color = new Vector(n);
for (int j = 0; j < n; ++j)
color.add(1);
// Starting by putting the ith node in set
color.set(i, 0);
// then finding all the nodes to be pushed
GFGUTIL.Util(adjacency_list, color);
// Finding the number of those which cannot be
// pushed in set
size = GFGUTIL.Util3(color);
if (size < min)
min = size;
// If the number of elements in set are more or
// equal
if (size <= y) {
// Print and display the size
System.out.println("Independent set of size " + (n - size) + "found");
for (int j = 0; j < n; ++j)
if (color.get(j) == 0)
System.out.print(j + 1 + " ");
System.out.println();
set_found.add(color);
// Set flaf to 1
found = 1;
// Hault the further execution of Program
break;
}
// If sufficient nodes are not found then
// we call util2 function
for (int j = 0; j < x; ++j)
GFGUTIL.Util2(adjacency_list, color, j);
size = GFGUTIL.Util3(color);
if (size < min)
min = size;
System.out.println("Independent set of size " + (n - size) + "found");
for (int j = 0; j < n; ++j)
if (color.get(j) == 0)
System.out.print(j + 1 + " ");
System.out.println();
set_found.add(color);
if (size <= y) {
found = 1;
break;
}
}
int r = set_found.size();
// Now searching pairwise and
// repeating same procedure as above discussed
for (int a = 0; a < r; ++a) {
if (found == 1)
break;
for (int b = a + 1; b < r; ++b) {
if (found == 1)
break;
Vector color = new Vector(n);
for (int j = 0; j < n; ++j)
color.add(1);
for (int c = 0; c < n; ++c)
if (set_found.get(a).get(c) == 0
&& set_found.get(b).get(c) == 0)
color.set(c, 0);
GFGUTIL.Util(adjacency_list, color);
size = GFGUTIL.Util3(color);
if (size < min)
min = size;
if (size <= y) {
System.out.println("Independent set of size" + (n - size));
for (int j = 0; j < n; ++j)
if (color.get(j) == 0)
System.out.print(j + 1 + " ");
System.out.println();
found = 1;
break;
}
for (int j = 0; j < y; ++j)
GFGUTIL.Util2(adjacency_list, color, j);
size = GFGUTIL.Util3(color);
if (size < min)
min = size;
System.out.println("Independent set of size " + (n - size) + "found");
for (int j = 0; j < n; ++j)
if (color.get(j) == 0)
System.out.print(j + 1 + " ");
System.out.println();
if (size <= y) {
found = 1;
break;
}
}
}
// If found
if (found == 1)
// Display command
System.out.println("Found the set of given least possible size");
else
// Display command
System.out.println("Couldn't find the set of least size given");
}
}
The number of vertices in the graph is taken as 4
The minimum size of the set required is taken as 2
Searching for the set
Independent set of size 1found
1
Independent set of size 1found
2
Independent set of size 1found
2
Independent set of size 1found
2
Independent set of size 1found
1
Independent set of size 1found
1
Independent set of size 1found
1
Independent set of size 1found
2
Independent set of size 1found
2
Independent set of size 1found
2
Couldn't find the set of least size given
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。