Thursday 23 November 2017

C++ Program to Find the Largest clique in a Planar Graph


Code:

#include    iostream
#include    fstream
#include    string
#include    vector
using namespace std;

bool removable(vector neighbor, vector cover);
int max_removable(vector > neighbors, vector cover);
vector procedure_1(vector > neighbors, vector cover);
vector procedure_2(vector > neighbors, vector cover,
        int k);
int cover_size(vector cover);
ifstream infile("graph.txt");
ofstream outfile("cliques.txt");

int main()
{
    //Read Graph (note we work with the complement of the input graph)
    cout << "Clique Algorithm." << endl;
    int n, i, j, k, K, p, q, r, s, min, edge, counter = 0;
    infile >> n;
    vector > graph;
    for (i = 0; i < n; i++)
    {
        vector row;
        for (j = 0; j < n; j++)
        {
            infile >> edge;
            if (edge == 0)
                row.push_back(1);
            else
                row.push_back(0);
        }
        graph.push_back(row);
    }
    //Find Neighbors
    vector > neighbors;
    for (i = 0; i < graph.size(); i++)
    {
        vector neighbor;
        for (j = 0; j < graph[i].size(); j++)
            if (graph[i][j] == 1)
                neighbor.push_back(j);
        neighbors.push_back(neighbor);
    }
    cout << "Graph has n = " << n << " vertices." << endl;
    //Read maximum size of Clique wanted
    cout << "Find a Clique of size at least k = ";
    cin >> K;
    k = n - K;
    //Find Cliques
    bool found = false;
    cout << "Finding Cliques..." << endl;
    min = n + 1;
    vector > covers;
    vector allcover;
    for (i = 0; i < graph.size(); i++)
        allcover.push_back(1);
    for (i = 0; i < allcover.size(); i++)
    {
        if (found)
            break;
        counter++;
        cout << counter << ". ";
        outfile << counter << ". ";
        vector cover = allcover;
        cover[i] = 0;
        cover = procedure_1(neighbors, cover);
        s = cover_size(cover);
        if (s < min)
            min = s;
        if (s <= k)
        {
            outfile << "Clique (" << n - s << "): ";
            for (j = 0; j < cover.size(); j++)
                if (cover[j] == 0)
                    outfile << j + 1 << " ";
            outfile << endl;
            cout << "Clique Size: " << n - s << endl;
            covers.push_back(cover);
            found = true;
            break;
        }
        for (j = 0; j < n - k; j++)
            cover = procedure_2(neighbors, cover, j);
        s = cover_size(cover);
        if (s < min)
            min = s;
        outfile << "Clique (" << n - s << "): ";
        for (j = 0; j < cover.size(); j++)
            if (cover[j] == 0)
                outfile << j + 1 << " ";
        outfile << endl;
        cout << "Clique Size: " << n - s << endl;
        covers.push_back(cover);
        if (s <= k)
        {
            found = true;
            break;
        }
    }
    //Pairwise Intersections
    for (p = 0; p < covers.size(); p++)
    {
        if (found)
            break;
        for (q = p + 1; q < covers.size(); q++)
        {
            if (found)
                break;
            counter++;
            cout << counter << ". ";
            outfile << counter << ". ";
            vector cover = allcover;
            for (r = 0; r < cover.size(); r++)
                if (covers[p][r] == 0 && covers[q][r] == 0)
                    cover[r] = 0;
            cover = procedure_1(neighbors, cover);
            s = cover_size(cover);
            if (s < min)
                min = s;
            if (s <= k)
            {
                outfile << "Clique (" << n - s << "): ";
                for (j = 0; j < cover.size(); j++)
                    if (cover[j] == 0)
                        outfile << j + 1 << " ";
                outfile << endl;
                cout << "Clique Size: " << n - s << endl;
                found = true;
                break;
            }
            for (j = 0; j < k; j++)
                cover = procedure_2(neighbors, cover, j);
            s = cover_size(cover);
            if (s < min)
                min = s;
            outfile << "Clique (" << n - s << "): ";
            for (j = 0; j < cover.size(); j++)
                if (cover[j] == 0)
                    outfile << j + 1 << " ";
            outfile << endl;
            cout << "Clique Size: " << n - s << endl;
            if (s <= k)
            {
                found = true;
                break;
            }
        }
    }
    if (found)
        cout << "Found Clique of size at least " << K << "." << endl;
    else
        cout << "Could not find Clique of size at least " << K << "." << endl
                << "Maximum Clique size found is " << n - min << "." << endl;
    cout << "See cliques.txt for results." << endl;
    return 0;
}

bool removable(vector neighbor, vector cover)
{
    bool check = true;
    for (int i = 0; i < neighbor.size(); i++)
        if (cover[neighbor[i]] == 0)
        {
            check = false;
            break;
        }
    return check;
}

int max_removable(vector > neighbors, vector cover)
{
    int r = -1, max = -1;
    for (int i = 0; i < cover.size(); i++)
    {
        if (cover[i] == 1 && removable(neighbors[i], cover) == true)
        {
            vector temp_cover = cover;
            temp_cover[i] = 0;
            int sum = 0;
            for (int j = 0; j < temp_cover.size(); j++)
                if (temp_cover[j] == 1 && removable(neighbors[j], temp_cover)
                        == true)
                    sum++;
            if (sum > max)
            {
                max = sum;
                r = i;
            }
        }
    }
    return r;
}

vector procedure_1(vector > neighbors, vector cover)
{
    vector temp_cover = cover;
    int r = 0;
    while (r != -1)
    {
        r = max_removable(neighbors, temp_cover);
        if (r != -1)
            temp_cover[r] = 0;
    }
    return temp_cover;
}

vector procedure_2(vector > neighbors, vector cover,
        int k)
{
    int count = 0;
    vector temp_cover = cover;
    int i = 0;
    for (int i = 0; i < temp_cover.size(); i++)
    {
        if (temp_cover[i] == 1)
        {
            int sum = 0, index;
            for (int j = 0; j < neighbors[i].size(); j++)
                if (temp_cover[neighbors[i][j]] == 0)
                {
                    index = j;
                    sum++;
                }
            if (sum == 1 && cover[neighbors[i][index]] == 0)
            {
                temp_cover[neighbors[i][index]] = 1;
                temp_cover[i] = 0;
                temp_cover = procedure_1(neighbors, temp_cover);
                count++;
            }
            if (count > k)
                break;
        }
    }
    return temp_cover;
}

int cover_size(vector cover)
{
    int count = 0;
    for (int i = 0; i < cover.size(); i++)
        if (cover[i] == 1)
            count++;
    return count;
}


Output:

graph.txt:
4
0 1 1 1
1 0 1 1
1 1 0 1
1 1 1 0

cliques.txt:
Clique ( 4 ): 1 2 3 4
------------------
(program exited with code: 0)
Press return to continue



More C++ Programs:
















100+ Best Home Decoration Ideas For Christmas Day 2019 To Make Home Beautiful

Best gifts for Christmas Day | Greeting cards for Christmas Day | Gift your children a new gift on Christmas day This Christmas d...