在不確定圖(uncertain graph)中結(jié)合Bron-Kerbosch算法和MULE算法尋找極大團(tuán)(maximal clique)

參考資料:
MULE算法
不確定圖上的枚舉算法研究
Bron-Kerbosch算法視頻介紹
Bron-Kerbosch算法
MULE(Maximal Uncertain CLique Enumeration )算法的論文原文是 Mining Maximal Cliques from an Uncertain Graph

論文作者:Arko Provo Mukherjee  ,Pan Xu,Srikanta Tirthapura
發(fā)表時(shí)間:2015 IEEE 31st International Conference on Data Engineering

Bron-Kerbosch算法是在確定圖上找出極大團(tuán),MULE算法是在不確定圖上找出極大團(tuán)。
??我們現(xiàn)在的目的,是要在不確定圖上找出極大團(tuán),現(xiàn)有的不確定圖上極大團(tuán)枚舉算法中,基于頂點(diǎn)編號(hào)升序的典型算法—MULE 算法性能較好,其時(shí)間復(fù)雜度為 O(n·2n)。但是MULE 算法的時(shí)間代價(jià)會(huì)隨著不確定圖頂點(diǎn)規(guī)模的增大而急劇上升,而隨著大數(shù)據(jù)和互聯(lián)網(wǎng)技術(shù)的發(fā)展,不確定圖的頂點(diǎn)規(guī)模越來越大,那么 MULE 算法也將難以滿足實(shí)際應(yīng)用的需求。
因此,通過將原圖劃分為子圖,過濾掉其中絕對(duì)不可能成為 α-極大團(tuán)的頂點(diǎn)集合,提高算法的計(jì)算效率,從而達(dá)到優(yōu)化時(shí)間性能的目的。
算法的主要思想:
先不考慮原圖中邊上的概率,通過Bron-Kerbosch算法在原圖中,找到一個(gè)個(gè)極大團(tuán)子圖。再對(duì)這每一個(gè)極大團(tuán)子圖,使用MULE算法,找出我們所需要的不確定圖中的極大團(tuán)。

原不確定圖

??例如這是原不確定圖,在不考慮概率的情況下,我們利用Bron-Kerbosch算法可以得到5個(gè)極大團(tuán)子圖,分別是{1,2,3}、{2,3,5}、{3,4,5}、{5,6}、{6,7,8,9}。
??接下來對(duì)每一個(gè)極大團(tuán)子圖調(diào)用 MULE 算法,枚舉其中的 α-極大團(tuán)(這里給定α=0.1,團(tuán)概率大于等于0.1的就是α-極大團(tuán),團(tuán)概率就是團(tuán)中每條邊上權(quán)值的乘積)對(duì)于頂點(diǎn)集合{1,2,3}所代表的極大團(tuán)子圖,調(diào)用 MULE 算法,可得頂點(diǎn)集合{1,2,3}本身就是一個(gè) α-極大團(tuán);對(duì)于頂點(diǎn)集合{2,3,5}所代表的極大團(tuán)子圖,調(diào)用 MULE 算法,可得頂點(diǎn)集合{2,3}、{2,5}以及{3,5}是 α-極大團(tuán);對(duì)于頂點(diǎn)集合{3,4,5}所代表的極大團(tuán)子圖,調(diào)用 MULE 算法,可得頂點(diǎn)集合{3,4}、{3,5}以及{4,5}是 α-極大團(tuán);對(duì)于頂點(diǎn)集合{5,6}所代表的極大團(tuán)子圖,調(diào)用 MULE 算法,可得頂點(diǎn)集合{5,6}本身就是一個(gè) α-極大團(tuán);對(duì)于頂點(diǎn)集合{6,7,8,9}所代表的極大團(tuán)子圖,調(diào)用 MULE 算法,可得頂點(diǎn)集合{6,7,8,9}本身就是一個(gè) α-極大團(tuán)。因此,在對(duì)每一個(gè)極大團(tuán)子圖調(diào)用 MULE 算法后,得到的所有 α-極大團(tuán)為{1,2,3}、{2,3}、{2,5}、{3,5}、{3,4}、{3,5}、{4,5}、{5,6}以及{6,7,8,9}共計(jì) 9 個(gè) α-極大團(tuán)。
??在原圖中,給定 α = 0.1,那么不確定圖 G 中的 α-極大團(tuán)分別為頂點(diǎn)集合{1,2,3}、{2,5}、{3,4}、{3,5}、{4,5}、{5,6}以及{6,7,8,9},共 7 個(gè) α-極大團(tuán)??墒乾F(xiàn)在有了9個(gè),多出了兩個(gè),這多出的兩個(gè),可以通過驗(yàn)證算法去掉,以后再詳細(xì)介紹,這里不考慮,我只需要求出最后的9個(gè)極大團(tuán),就算完成任務(wù)。
下面是代碼:
頭文件:

Vertex_Value.h
#pragma once
#include <iostream>
using namespace std;
//這個(gè)相當(dāng)于臨接表中的邊界點(diǎn)
class Vertex_Value
{
public:
    Vertex_Value(void);
    ~Vertex_Value(void);
    Vertex_Value(int x, float y);

public:
    int vertex;  //鄰接表中邊結(jié)點(diǎn)的編號(hào)
    float val;    //結(jié)點(diǎn)之間的概率
};
node.h
#pragma once
#include "Vertex_Value.h"
#include <vector>
using namespace std;
//相當(dāng)于頭結(jié)點(diǎn)
class node
{
public:
    int vertex;    //頭節(jié)點(diǎn)的結(jié)點(diǎn)編號(hào)
    vector<Vertex_Value> vec;  //這里用vector動(dòng)態(tài)數(shù)組來放邊結(jié)點(diǎn),Vertex_Value表示邊結(jié)點(diǎn),其中有結(jié)點(diǎn)編號(hào),以及邊上的概率
};
UDG.h
#pragma once
#include "Vertex_Value.h"
#include <vector>
using namespace std;
//相當(dāng)于頭結(jié)點(diǎn)
class node
{
#pragma once
#include "node.h"

class UDG
{
public:
    int vernum, arcnum;
    node *AdjVector;//是鄰接vector的形式 一個(gè)數(shù)組名字叫AdjVector,數(shù)組里面存放的是node形式的的數(shù)據(jù)
};
ReadFile.h
#pragma once
#include "UDG.h"

#define path "F:\\c++_code\\test2.txt"
//讀取文件
class ReadFile
{
public:
    ReadFile(void);
    ~ReadFile(void);
    void CreateUdg(UDG &g); //讀取文件后,構(gòu)建出不確定圖出來
};
BasicFunctions.h
#pragma once
#include <vector>
#include "UDG.h"
#include "Vertex_Value.h"
using namespace std;

#define $ 0.1 //概率閾值,極大團(tuán)的團(tuán)概率要大于這個(gè)值
class BasicFunctions
{
public:
    BasicFunctions(void);
    ~BasicFunctions(void);

    vector<UDG> Bron_Kerbosch(const UDG g);//把不確定圖作為確定圖來看待,得到所有的極大團(tuán)子圖

    void MULE(const UDG g);//在不確定圖g中,找到所有團(tuán)概率大于閾值的極大團(tuán)

    void EnumUncertainMC(vector<int> C, float q, vector<Vertex_Value> I, vector<Vertex_Value>& X, UDG g);//在MULE算法中枚舉圖中的極大團(tuán)

    vector<Vertex_Value> GenerateI(vector<int> C, float q, vector<Vertex_Value> I, UDG g);//在MULE算法中,用來更新I集合

    vector<Vertex_Value> GenerateX(vector<int> C, float q, vector<Vertex_Value> X, UDG g);//在MULE算法中,用來更新X集合

    void fuzhufunction(vector<int> C, float q, vector<Vertex_Value> I, vector<Vertex_Value>& X, int i, UDG g);//在MULE算法中的輔助函數(shù)

    bool IfConnect(int u, int v, UDG g);  //判斷在圖g中,結(jié)點(diǎn)u和結(jié)點(diǎn)v是否連接

    void Enum_Deterministic(vector <int> all, vector <int> some, vector <int> none, UDG g);//用在Bron_Kerbosch算法中,枚舉圖中的極大團(tuán)

    vector<int> GenerateSome(vector <int> all, vector <int> some, UDG g);//用在Enum_Deterministic中,更新其中的some集合

    vector<int> GenerateNone(vector <int> all, vector <int> none, UDG g);//用在Enum_Deterministic中,更新其中的none集合

    int MaxC(vector<int> C);//找當(dāng)前團(tuán)C中的最大頂點(diǎn)編號(hào)

    vector<int> AdjVertex(int m, UDG g);//找到圖g中,m結(jié)點(diǎn)的所有鄰接點(diǎn)

    vector<int> mixede(vector<int> A, vector<int> B);//求兩個(gè)vector的交集

    bool isbelongto(int m, vector<int> S1);//檢測(cè)m頂點(diǎn)是否屬于S1;

    float FindValue(int u, int v, UDG g);//給定頂點(diǎn)對(duì),找權(quán)值

    float clq(vector<int> C, float q, Vertex_Value D, int m, UDG g);//求當(dāng)前團(tuán)加入一個(gè)頂點(diǎn)后的團(tuán)概率

    vector<int> AdjVertex_MULE(int m, UDG g);//在MULE中使用,找到m的所有鄰居結(jié)點(diǎn)

    float FindValue_MULE(int u, int v, UDG g);//在MULE中使用,找到結(jié)點(diǎn)u和結(jié)點(diǎn)v之間的權(quán)值
};

下面是cpp文件:

Vertex_Value.cpp
#include "Vertex_Value.h"

Vertex_Value::Vertex_Value(void)
{
}

Vertex_Value::~Vertex_Value(void)
{
}
Vertex_Value::Vertex_Value(int x, float y)
{
    vertex = x;
    val = y;
}
ReadFile.cpp
#include "ReadFile.h"
#include <fstream>
#include <iostream>
using namespace std;

ReadFile::ReadFile(void)
{
}

ReadFile::~ReadFile(void)
{
}
void ReadFile::CreateUdg(UDG &g)
{
    ifstream infile(path);      //讀取path里面的文本
    cout << "開始讀入文件!" << endl;
    infile >> g.vernum >> g.arcnum;   //infile在這里就類似cin操作,cin是讀取鍵盤輸入,而infile是讀取文件輸入 >> 操作返回的是左操作數(shù),也就是給g.vernum和g.arcnum賦值了
    cout << "頂點(diǎn)個(gè)數(shù)和邊數(shù)為:" << endl;
    cout << g.vernum << ' ' << g.arcnum << endl;
    g.AdjVector = new node[g.vernum + 1];//0號(hào)不存結(jié)點(diǎn),能儲(chǔ)存g.vernum個(gè)結(jié)點(diǎn)的數(shù)組AdjVector,g.AdjVector[0]中不存放數(shù)據(jù)
    cout << "開始讀入邊,建立鄰接vector!" << endl;
    int i;
    for (i = 0; i < g.arcnum; i++)
    {
        int head, tail;
        float val;
        infile >> head >> tail >> val;  //文本里讀取文件到空格結(jié)束,循環(huán)結(jié)束以后進(jìn)入到下一行
        g.AdjVector[head].vertex = head;   //這樣可以完成順序存放,這樣g.AdjVector[1]中,存放的是頭節(jié)點(diǎn)為1的結(jié)點(diǎn),其他結(jié)點(diǎn)也都是對(duì)應(yīng)的
        Vertex_Value temp;
        temp.vertex = tail;
        temp.val = val;
        g.AdjVector[head].vec.push_back(temp);
    }
}
BasicFunctions.cpp

#include<algorithm>
#include <iterator> 
#include "UDG.h"
#include "BasicFunctions.h"

vector<UDG> Amc;//用來裝Bron_Kerbosch算法產(chǎn)生的極大團(tuán)子圖


BasicFunctions::BasicFunctions(void)
{
}

BasicFunctions::~BasicFunctions(void)
{
}


//***********************************************************************
//判斷在圖g中結(jié)點(diǎn)u和結(jié)點(diǎn)v是否相連
bool BasicFunctions::IfConnect(int u, int v, UDG g)
{
    int i;
    unsigned int j;
    for (i = 1; i <= g.vernum; i++)
    {
        if (g.AdjVector[i].vertex == u)
        {
            break;
        }
    }

    for (j = 0; j < g.AdjVector[i].vec.size(); j++)
    {
        if (v == g.AdjVector[i].vec[j].vertex)
        {
            //cout << "結(jié)點(diǎn)" << u << "和結(jié)點(diǎn)" << v << "相連" << endl;
            return true;
        }
    }
    //cout << "結(jié)點(diǎn)" << u << "和結(jié)點(diǎn)" << v << "不相連" << endl;
    return false;
}


//***********************************************************************
//檢測(cè)m頂點(diǎn)是否屬于S1;
bool BasicFunctions::isbelongto(int m, vector<int> S1)
{
    for (unsigned int i = 0; i < S1.size(); i++)
    {
        if (m == S1[i])
        {
            return true;
        }
    }
    return false;
}


//***********************************************************************
//求兩個(gè)vector的交集
vector<int> BasicFunctions::mixede(vector<int> A, vector<int> B)
{
    vector<int> v;
    sort(A.begin(), A.end());
    sort(B.begin(), B.end());
    set_intersection(A.begin(), A.end(), B.begin(), B.end(), back_inserter(v));//求交集 ,必須引入<algorithm>、<iterator>才能使用這些函數(shù)
    return v;

}


//***********************************************************************
//找當(dāng)前團(tuán)C中的最大頂點(diǎn)編號(hào)
int BasicFunctions::MaxC(vector<int> C)
{
    if (C.empty())
    {
        return 0;
    }
    int max = 1;
    unsigned int i;
    for (i = 0; i < C.size(); i++)
    {
        if (max < C[i])
        {
            max = C[i];
        }
    }
    return max;
}

//***********************************************************************
//找到圖g中,m結(jié)點(diǎn)的所有鄰接點(diǎn)
vector<int> BasicFunctions::AdjVertex(int m, UDG g)
{
    vector<int> C;
    unsigned int i;
    for (i = 0; i < g.AdjVector[m].vec.size(); i++)
    {
        C.push_back(g.AdjVector[m].vec[i].vertex);
    }
    return C;
}


//***********************************************************************
//找到圖g中,m結(jié)點(diǎn)的所有鄰接點(diǎn)
vector<int> BasicFunctions::AdjVertex_MULE(int m, UDG g)
{
    vector<int> C;
    int i;
    unsigned int j;
    for (i = 1; i <= g.vernum; i++)
    {
        if (g.AdjVector[i].vertex == m) break;
    }
    for (j = 0; j < g.AdjVector[i].vec.size(); j++)
    {
        C.push_back(g.AdjVector[i].vec[j].vertex);
    }
    return C;
}

//***********************************************************************

float BasicFunctions::FindValue_MULE(int u, int v, UDG g)
{
    unsigned int i;
    int j;
    for (j = 1; j <= g.vernum; j++)
    {
        if (g.AdjVector[j].vertex == u) break;
    }

    for (i = 0; i < g.AdjVector[j].vec.size(); i++)
    {
        if (g.AdjVector[j].vec[i].vertex == v)
        {
            return g.AdjVector[j].vec[i].val;
        }
    }
    return 0;
}

//***********************************************************************
//找到圖g中,結(jié)點(diǎn)u和結(jié)點(diǎn)v之間的權(quán)值
float BasicFunctions::FindValue(int u, int v, UDG g)
{
    unsigned int i;

    for (i = 0; i < g.AdjVector[u].vec.size(); i++)
    {
        if (g.AdjVector[u].vec[i].vertex == v)
        {
            return g.AdjVector[u].vec[i].val;
        }
    }
    return 0;
}
//***********************************************************************
//這個(gè)是求,如果將結(jié)點(diǎn)D加入加入極大團(tuán)C后,團(tuán)概率會(huì)變成什么值
float BasicFunctions::clq(vector<int> C, float q, Vertex_Value D, int m, UDG g)
{
    float temp;
    temp = FindValue_MULE(D.vertex, m, g);
    return q * D.val * temp;
}


//***********************************************************************
//在MULE算法中,用來更新X集合
vector<Vertex_Value> BasicFunctions::GenerateX(vector<int> C, float q, vector<Vertex_Value> X, UDG g)
{
    if (X.empty())
    {
        return X;
    }
    int m = MaxC(C);
    vector<int> S2 = AdjVertex_MULE(m, g);
    vector<Vertex_Value> _X;
    vector<int> S1;
    unsigned int i;
    for (i = 0; i < X.size(); i++)
    {
        S1.push_back(X[i].vertex);
    }
    S1 = mixede(S1, S2);
    unsigned int j;
    for (i = 0, j = 0; i < X.size(); i++)
    {
        if (isbelongto(X[i].vertex, S1))
        {
            if (clq(C, q, X[i], m, g) >= $)
            {
                _X.push_back(X[i]);
                _X[j].val = _X[j].val * FindValue_MULE(_X[j].vertex, m, g);
                j++;
            }
        }
    }
    return _X;
}


//***********************************************************************
//在MULE算法中,用來更新I集合
vector<Vertex_Value> BasicFunctions::GenerateI(vector<int> C, float q, vector<Vertex_Value> I, UDG g)
{
    int m = MaxC(C);    //找到C中編號(hào)最大的點(diǎn)
    vector<int> S2 = AdjVertex_MULE(m, g); //在圖g中找到m的鄰居接點(diǎn)
    vector<Vertex_Value> _I;
    vector<int> S1;
    unsigned int i;
    for (i = 0; i < I.size(); i++)
    {
        S1.push_back(I[i].vertex);
    }
    S1 = mixede(S1, S2);
    unsigned int j = 0;
    for (i = 0, j; i < I.size(); i++)
    {
        if (I[i].vertex > m && isbelongto(I[i].vertex, S1))
        {
            if (clq(C, q, I[i], m, g) >= $)
            {
                _I.push_back(I[i]);
                _I[j].val = _I[j].val * FindValue_MULE(_I[j].vertex, m, g);
                j++;
            }
        }
    }
    return _I;
}


//***********************************************************************
//EnumUncertainMC中的輔助函數(shù)
void BasicFunctions::fuzhufunction(vector<int> C, float q, vector<Vertex_Value> I, vector<Vertex_Value>& X, int i, UDG g)
{
    C.push_back(I[i].vertex);
    q = q * I[i].val;
    vector<Vertex_Value> _I = GenerateI(C, q, I, g);
    vector<Vertex_Value> _X = GenerateX(C, q, X, g);
    EnumUncertainMC(C, q, _I, _X, g);
    X.push_back(I[i]);
}


//***********************************************************************
//在MULE算法中,找到滿足要求的極大團(tuán)
void BasicFunctions::EnumUncertainMC(vector<int> C, float q, vector<Vertex_Value> I, vector<Vertex_Value>& X, UDG g)
{
    unsigned int i;
    if (I.empty() && X.empty())
    {
        cout << "通過MULE算法產(chǎn)生一個(gè)極大團(tuán)!" << endl;
        for (i = 0; i < C.size(); i++)
        {
            cout << C[i] << ' ';
        }
        cout << endl;
        return;
    }
    vector<int> Ctemp(C);
    for (i = 0; i < I.size(); i++)
    {
        fuzhufunction(Ctemp, q, I, X, i, g);
    }
}

//***********************************************************************
//用在Enum_Deterministic中,更新其中的none集合
vector<int> BasicFunctions::GenerateNone(vector <int> all, vector <int> none, UDG g)
{

    int m = MaxC(all);    //找到C中編號(hào)最大的點(diǎn)
    vector<int> S2 = AdjVertex(m, g); //在圖g中找到m的鄰居接點(diǎn)
    vector<int> _none;
    vector<int> S1;
    unsigned int i;
    for (i = 0; i < none.size(); i++)
    {
        S1.push_back(none[i]);
    }
    S1 = mixede(S1, S2);   //保證some中放的結(jié)點(diǎn),都是和all中所有結(jié)點(diǎn)連接的


    for (i = 0; i < none.size(); i++)
    {
        if (isbelongto(none[i], S1))
        {
            _none.push_back(none[i]);
        }
    }
    return _none;


}

//***********************************************************************
//用在Enum_Deterministic中,更新其中的some集合
vector<int> BasicFunctions::GenerateSome(vector <int> all, vector <int> some, UDG g)
{


    int m = MaxC(all);    //找到all中編號(hào)最大的點(diǎn)
    vector<int> S2 = AdjVertex(m, g); //在圖g中找到m的鄰居接點(diǎn)
    vector<int> _some;
    vector<int> S1;
    unsigned int i;
    for (i = 0; i < some.size(); i++)
    {
        S1.push_back(some[i]);
    }
    S1 = mixede(S1, S2);   //保證some中放的結(jié)點(diǎn),都是和all中所有結(jié)點(diǎn)連接的


    for (i = 0; i < some.size(); i++)
    {
        if (some[i] > m && isbelongto(some[i], S1))
        {
            _some.push_back(some[i]);
        }
    }
    return _some;

}


//***********************************************************************
//用在Bron_Kerbosch算法中,枚舉圖中的極大團(tuán)
void BasicFunctions::Enum_Deterministic(vector <int> all, vector <int> some, vector <int> none, UDG g)
{
    unsigned int i;
    if (some.empty() && none.empty())    //兩者都為空,則找到極大團(tuán)
    {
        UDG g_t;
        g_t.vernum = all.size();
        g_t.arcnum = (all.size()*(all.size()-1));
        g_t.AdjVector = new node[all.size() + 1];
        cout << "通過Bron_Kerbosch算法產(chǎn)生一個(gè)極大團(tuán)子圖!" << endl;
        for (i = 0; i < all.size(); i++)
        {
            cout << all[i] << ' ';
            g_t.AdjVector[i + 1] = g.AdjVector[all[i]];
        }
        cout << endl;
        Amc.push_back(g_t);
        return;
    }

    vector<int> allTemp(all);   //將all中的所有值,都賦給allTemp,allTemp用來遞歸到下一層(去放置極大團(tuán))
    for (i = 0; i < some.size(); i++)
    {


        allTemp.push_back(some[i]);//更新下一層中的allTemp
        vector<int> _some = GenerateSome(allTemp, some, g);//產(chǎn)生新的some集合。要保證新的some集合,要和allTemp集合中的所有結(jié)點(diǎn)都連接
        vector<int> _none = GenerateNone(allTemp, none, g);//產(chǎn)生新的none集合。要保證新的none集合,要和allTemp集合中的所有結(jié)點(diǎn)都連接
        Enum_Deterministic(allTemp, _some, _none, g);   //帶著新的all,some,none集合進(jìn)入到下一層中

        none.push_back(some[i]);//將some[i]放入none中,表示在這一層里面,由some[i]開始的極大團(tuán),已經(jīng)探索過了

        allTemp.pop_back(); //將some[i]從allTemp中拿出,開始下一輪的for循環(huán),在下一輪的for循環(huán)中,放入新的some[i]

    }

}



//***********************************************************************
//總算法的第一步,從原圖中得到所有的極大團(tuán)子圖
vector<UDG> BasicFunctions::Bron_Kerbosch(const UDG g)
{


    vector <int> some(g.vernum);//聲明一個(gè)初始大小為g.vernum的Vertex_Value類型的向量_I,_I中存放的結(jié)點(diǎn),就是預(yù)備要放入C中的
    vector<int> all;       //聲明一個(gè)int型向量all,就是極大團(tuán)
    vector<int> none;   //聲明一個(gè)Vertex_Value型向量X ,X存放已經(jīng)探索過的某結(jié)點(diǎn)。
    int i = 1;
    for (i; i <= g.vernum; i++)
    {
        some[i - 1] = i;   //將所有的結(jié)點(diǎn)編號(hào)存放在some中
    }
    Enum_Deterministic(all, some, none, g);

    return Amc;
}


//***********************************************************************
//總算法的第二步,從每個(gè)極大團(tuán)子圖中,找到滿足概率閾值的極大團(tuán)
void BasicFunctions::MULE(const UDG g)
{
    vector <Vertex_Value> _I(g.vernum);//聲明一個(gè)初始大小為g.vernum的Vertex_Value類型的向量_I,_I中存放的結(jié)點(diǎn),就是預(yù)備要放入C中的
    vector<int> C;       //聲明一個(gè)int型向量C
    vector<Vertex_Value> X;   //聲明一個(gè)Vertex_Value型向量X ,X存放已經(jīng)探索過的某結(jié)點(diǎn)。
    int i = 1;
    for (i; i <= g.vernum; i++)   //先初始化_I,其中存放(u,r),其中u就是Vertex_Value中的vertex(表示結(jié)點(diǎn)的編號(hào)),r就是Vertex_Value中的val(表示將該節(jié)點(diǎn)加入到極大團(tuán)C后,所要乘上的概率)
    {
        _I[i - 1].vertex = g.AdjVector[i].vertex;
        _I[i - 1].val = 1;   //最開始都賦值為1
    }
    float j = 1;
    EnumUncertainMC(C, j, _I, X, g);
}

下面是主函數(shù):

#include <tchar.h>
#include "ReadFile.h"
#include "BasicFunctions.h"
#include <iostream>
using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    UDG g;  
    ReadFile A;
    vector<UDG> Amc;
    A.CreateUdg(g);
    BasicFunctions BF;
    Amc = BF.Bron_Kerbosch(g);
    unsigned int i;

    for (i = 0; i < Amc.size(); i++)
    {
        BF.MULE(Amc[i]);
    }
    
    system("pause"); //暫停黑窗口
    return 0;

}

test2.txt如下:
9表示結(jié)點(diǎn)數(shù),28表示邊數(shù)(這里的1 2和2 1算不同的邊)
第一位數(shù)字是頭結(jié)點(diǎn),第二位數(shù)字是邊結(jié)點(diǎn),第三個(gè)數(shù)字是邊上的概率

9 28
1 2 0.6
1 3 0.5
2 1 0.6
2 3 0.4
2 5 0.7
3 1 0.5
3 2 0.4
3 4 0.5
3 5 0.1
4 3 0.5
4 5 0.2
5 2 0.7
5 3 0.1
5 4 0.2
5 6 0.4
6 5 0.4
6 7 0.7
6 8 0.9
6 9 0.8
7 6 0.7
7 8 0.7
7 9 0.6
8 6 0.9
8 7 0.7
8 9 0.6
9 6 0.8
9 7 0.6
9 8 0.6

實(shí)驗(yàn)結(jié)果:


實(shí)驗(yàn)結(jié)果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容