C++程序设计02

该程序使用C++编程,通过Bron-Kerbosch算法解决图的最大团问题。它首先从CSV文件中读取数据,构造冲突矩阵,然后执行算法找到最大团,并输出结果。若最大团数目超过某一阈值,则表明存在资源冲突。
摘要由CSDN通过智能技术生成
///冲突检测代码准确:BK2-5-7
#include "stdc++.h"
#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "ctime"
#include "fstream"
#include "sstream"
#include "vector"
//int x0[999];
//int q0[999];

int p[999];
int q[999];
using namespace std;

int m[101][101];//有向图的邻接矩阵
int x[101];//当前团的解
int bestx[101];//最优解
int n;//表示图的顶点数
int cn = 0;//当前团的大小
int bestn;//当前最优值

void BronKerbosch(int i)///自定义B-K算法void BronKerbosch函数用来求解最大团
{
    //printf("求最优解1\n");
    if (i > n) {//递归出口,到根节点时,更新最优值和最优解,返回
        bestn = cn;//更新最优值
        for (int j = 1; j <= n; j++)
            bestx[j] = x[j];
        return;//返回
    }
    x[i] = 1;//先假定x[i]=0;
    for (int j = 1; j < i; j++) {
        if (x[j] == 1 && m[i][j] == 0) {
            x[i] = 0;//如果该点与已知解中的点无边相邻
            break;//则不遍历左子树
        }
    }
    if (x[i] == 1) {//当且仅当x[i]==1时,遍历左子树
        cn++;//该点加入当前解
        BronKerbosch(i + 1);//递归调用
        cn--;//还原当前解
    }
    x[i] = 0;//假定x[i]==0
    if (cn + n - i > bestn) {//如果当前值+右子树可能选择的节点<当前最优解,不遍历左子树
        x[i] = 0;
        BronKerbosch(i + 1);
    }
    return;
}


int main()
{
    time_t begin, end;计算程序运行时长
    double ret;
    begin = clock();计时开始

    cout << "将读取CSV文件的数据保存在数组n1中" << endl;
    //读取文件中的数据
    ifstream ifs;                                //创建流对象

    ifs.open("./testdataSS03.csv", ios::in);    //打开文件

    if (!ifs.is_open())                            //判断文件是否打开
    {
        cout << "打开文件失败!!!";
        return 0;
    }

    vector<string> item;        //用于存放文件中的一行数据

    string temp;                //临时存储文件中的一行数据

    while (getline(ifs, temp))  //利用 getline()读取文件中的每一行,并放入到 item 中
    {
        item.push_back(temp);
    }
    int i = 0; int j = 0;
    
    for (auto it = item.begin(); it != item.end(); it++)//遍历文件中的每一行数据
    {
        string str;

        //其作用是把字符串分解为单词(在此处就是把一行数据分为单个数据)
        istringstream istr(*it);

        //将字符串流 istr 中的字符读入到 str 字符串中,读取方式是以逗号为分隔符 
        getline(istr, str, ',');
        //cout << str << "\t";            // str 对应第一列数据

        //atoi(str.c_str())该函数将字符转化为 int 数据            
        p[i] = atoi(str.c_str());
        i++;

        //getline(istr, str, ',');
        //cout << str << "\t";            // str 对应第二列数据 

        //getline(istr, str, ',');
        //cout << str << "\t";            // str 对应第三列数据   

        //getline(istr, str, ',');
        //cout << str << "\t";            // str 对应第四列数据 

        //getline(istr, str, ',');
        //cout << str << "\t";            // str 对应第五列数据 

        getline(istr, str, ',');
        //cout << str << endl;   
        //cout << endl;
        q[j] = atoi(str.c_str());
        j++;// str 对应第六列数据    

    }


    int n1[51][2] = { 0 };

    for (i = 0; i < 51; i++)
    {
        n1[i][0] = p[i];

    }

    for (i = 0; i < 51; i++)
    {
        n1[i][1] = q[i];

    }

    int num = sizeof(n1) / sizeof(n1[0]);
    n = num;

    printf("输出矩阵n1\n");
    for (int i = 0; i < num; i++)
    {
        for (int j = 0; j < 2; j++)
        {
            cout << n1[i][j] << " ";
        };
        cout << endl;
    }
    cout << endl;


    //printf("读取CSV表格中数据构造冲突矩阵M\n");
    //int n1[10][2] = { 100,200,1,70,1,8,1,13,1,8,1,9,1,10,1,6,1,7,3,70 };
    //int n2[10][2] = {1,6,2,7,3,8,8,13,3,8,4,9,5,10,1,6,2,7,5,10};
    
    
    cout<< "输入图的顶点数n:" <<num<<endl;

    for (int i = 0; i < num; i++)//有逻辑问题得到改正
    {
        for (int j = i + 1; j < num; j++)
            //if (((n1[j][0] <= n1[i][0]) && (n1[i][0] <= n1[j][1])) || ((n1[j][0] <= n1[i][1]) && (n1[i][1] <= n1[j][1])) ||
            //    ((n1[j][0] <= n1[i][0]) && (n1[i][1] <= n1[j][1])) || ((n1[i][0] <= n1[j][0]) && (n1[j][1] <= n1[i][1])))
            if (((n1[j][0] < n1[i][0]) && (n1[i][0] < n1[j][1])) || ((n1[j][0] < n1[i][1]) && (n1[i][1] < n1[j][1])) ||
                ((n1[j][0] < n1[i][0]) && (n1[i][1] < n1[j][1])) || ((n1[i][0] < n1[j][0]) && (n1[j][1] < n1[i][1])) ||
                ((n1[j][0] = n1[i][0]) && (n1[i][1] = n1[j][1])))
            {
                m[i+1][j+1] = 1;
                m[j+1][i+1] = 1;
            };
    }
    cout << endl;

    printf("输出冲突矩阵M\n");
    for (int a = 1; a < num+1; a++)
    {
        for (int b = 1; b < num+1; b++)
        {
            cout << m[a][b] << " ";
        };
        cout << endl;
    }
    cout << endl;
    
    //printf("求最优解\n");
    BronKerbosch(1);//求最优解

    printf("输出SS链序号构成最大团的数目:");
    cout << bestn << endl;//输出最优值
    
    printf("输出构成最大团的SS链序号:");
    for (int i = 1; i <= num; i++)//输出
        if (bestx[i])
            cout << i << " ";//输出最优解
    cout << endl;


    if (bestn >= 8)
    {
        printf("共享WQSS链数目为超过最大通道容量,该WQ发生了资源冲突");
    }
    else
    {
        printf("该WQ无资源冲突");
    }
    cout << endl;

    end = clock();计时结束
    ret = double(end - begin) / CLOCKS_PER_SEC;//计算程序运行时长
    cout << "程序运行时间为:" << ret << "s" << endl;
    return 0;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值