📜  使用图形着色在图形中查找独立集的Java程序

📅  最后修改于: 2021-10-25 05:16:26             🧑  作者: Mango

独立集是一组顶点或边,其中任意两个顶点或边的对彼此不相邻。假设独立集意味着独立的顶点集,我们必须找到一组这样的顶点,其中任意两对顶点彼此不相邻。

使用图形着色 我们可以解决这个问题。我们将修改图形着色方法,因为我们将只使用两种颜色,即 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 个”顶点为“0”的每个第 i 个颜色向量,这些方法试图找到可以从图中删除的顶点数(指定为“0”)。因此,在调用此 Util() 方法后,颜色向量将被修改,并且可以分配为“0”的顶点数被赋予该值。
  • 现在因为颜色向量被修改了,所以我们必须计算分配为’0’的顶点的数量(这意味着可以包含在集合中的顶点)。如果计数大于所需的大小,那么我们已经找到了解决方案,并且 found 变量被设置为 true 并且输出完成并且循环中断,否则它将继续尝试下一个颜色向量并删除下一个顶点。计数由 Util3() 方法完成。

但是我们忘记了一种情况,如下图所示:

Java-Program-to-Find-Independent-Sets-in-a-Graph-using-Graph-Coloring

这里不是给第一个图中的第二个着色顶点着色,我们将为其相邻的一个顶点着色,如第二个图所示。这样做我们将在集合中得到许多顶点。因此,对于每个颜色向量,我们将调用 Util2() 方法。只有当某个顶点的值为“1”(未着色)并且只有一个着色的相邻顶点时才会出现这种情况,如上所示。

  • Util2() 方法基本上检查每个未被移除的顶点(具有“1”),该顶点是否只有一个相邻的顶点着色(值“1”)。如果找到任何这样的顶点,则此方法将在顶点之间交换颜色并调用 Util() 方法以刷新颜色向量。这可以很容易地证明,该方法将始终增加带有“0”的顶点的数量,或者数量将保持不变。它永远不会减少彩色顶点的数量。因此,这种方法证明对我们的方法特别有益。
  • 到目前为止,如果我们有任何解决方案,那么我们将设置 found true 否则将保存颜色向量的配置以供进一步使用。所有这些都是针对循环中的每个“第 i 个”顶点完成的,修改后的颜色向量存储在程序中名为 set_found 的向量向量中。
  • 如果到目前为止还没有找到所需的大小,那么我们将尝试我们将执行所有生成的配置集的成对交集的最后一种情况。

在此,我们将再次从颜色向量开始并保持生成的配置重复相同的过程。唯一的区别是我们不会从将“0”分配给第 i 个顶点开始。取而代之的是,我们将检查那些标有“0”并且对两个集合都通用的顶点的配置对(在 set_found 中)。它们将在颜色向量中标记为“0”,对于其余部分,上述过程将相同,以检查可能的最大集合大小和上述情况。

执行:

Java
// Java Program to Find Independent Sets
// in a Graph using Graph Coloring
 
import java.io.*;
import java.util.*;
 
// save file with the name "GFG2.java"
 
public class GFG2 {
   
    // main class
    public static void main(String[] args) throws Exception
    {
        // inputting the graph and forming it's adjacency
        // list.
 
        System.out.println("The number of vertices in the graph is taken as 4");
       
        int n = 4;
        Vector > adjacency_matrix
            = new Vector >(n, (n));
       
        /* the input matrix is
           0111
           1011
           1101
           1110
        */
       
        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);
        }
       
        Vector > adjacency_list  = new Vector >();
 
        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);
        }
       
        // taking the minimum size of the set required.
        System.out.println("The minimum size of the set required is taken as 2");
       
        // the 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;
       
        // making a set_found vector to store all the
        // possible sets .
        Vector > set_found
            = new Vector >();
 
        System.out.println("Searching for the set");
 
        for (int i = 0; i < n; ++i) {
           
            // if set is found
            if (found == 1)
                break;
           
            // a 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 in
            // the set by calling function
            Util(adjacency_list, color);
           
            // finding the number of those which cannot be
            // pushed in set
            size = Util3(color);
           
            if (size < min)
                min = size;
           
            // if the number of elements in set are more or
            // equal to the amount required.
            if (size <= y) {
               
                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);
                found = 1;
                break;
            }
           
            // not sufficient nodes found
            // calling util2 function
            // main aim of calling this function 'x' times
            // is that for any undirected graph the maximum
            // number of edges with x nodes is x(x+1)/2; so
            // we are trying for each possible edge .
            for (int j = 0; j < x; ++j)
                Util2(adjacency_list, color, j);
           
            // repeating same procedure as discussed above
            size = 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();
       
        // searching pairwise.
        // repeating same procedure as above
        // this time taking those set which have common
        // vertices in them and again trying for uncommon
        // ones.
 
        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);
               
                Util(adjacency_list, color);
               
                size = 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)
                    Util2(adjacency_list, color, j);
               
                size = 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)
            System.out.println(
                "Found the set of given least possible size");
        else
            System.out.println(
                "Couldn't find the set of least size given");
    }
   
    // utility function to label maximum vertices with
    // 0,that can be included in the set. It takes the
    // maximum number of vertices which can be removed each
    // time.
    public static void Util(Vector > adjacency_list,
         Vector color)
    {
        int a = 0;
        while (a != -1) {
            a = remove_all(adjacency_list, color);
            if (a != -1)
                color.set(a, 0);
        }
    }
   
    // This method tries whether it is possible to
    // remove any adjacent vertex of any removed vertex if
    // yes then it will remove that and call Util again and
    // modify the set.
    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));
    }
   
    // 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;
    }
   
    // returns the index of the vertex whose removal will
    // give more vertex to be removed. This is basically a
    // greedy approach to get the maximum possible set size.
    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;
                }
            }
        }
        return a;
    }
   
    // checking that 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;
    }
}


输出
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 现场工作专业课程学生竞争性编程现场课程