QT = core
CONFIG += c++17 cmdline
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
simplegraph.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += \
commondatastructure.h \
simplegraph.h
#include "simplegraph.h"
using namespace std;
int main(int argc, char *argv[])
{
/*
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4)
*/
GRAPH_ADJARRAY_VECTOR graph = {
{0, 1, 0, 1, 0},
{0, 1, 1, 1},
{0, 0, 1},
{0, 1},
{0}
};
cout << "G Upper Triangle Matrix" << endl;
SimpleGraph G(graph);
G.help();
cout << "Computing Min Vertex Cover..." << endl;
VERTEXCOVER coverSet = G.getVertexCover();
cout << "Print Min Vertex Cover..." << endl;
SimpleGraph::printVertexSet(coverSet);
cout << "Finish!!!" << endl;
}
#ifndef COMMONDATASTRUCTURE_H
#define COMMONDATASTRUCTURE_H
#include
#include
#include
#include
#include
#ifndef SIMPLEGRAPH_H
#define SIMPLEGRAPH_H
#include "commondatastructure.h"
class SimpleGraph
{
public:
SimpleGraph(const GRAPH_ADJARRAY_VECTOR adjgraph);
VERTEXCOVER getVertexCover();
void help(); //print adj array
void print(); //print adj list
void inc(int keyVertex, int targetVertex);
void dec(int keyVertex, int targetVertex);
static void printVertexSet(VERTEXCOVER s);
static OFFSET_VECTOR globalOffset;
private:
GRAPH_ADJLIST_MAP m_dstAdjList;
GRAPH_ADJARRAY_VECTOR m_srcAdjArray;
void adjArray2adjList(const GRAPH_ADJARRAY_VECTOR &srcAdjArray, GRAPH_ADJLIST_MAP &dstAdjList);
};
#endif // SIMPLEGRAPH_H
#include "simplegraph.h"
#define PRINTINFO 1
OFFSET_VECTOR SimpleGraph::globalOffset = \
{ \
0,1,2,3,4,5,6,7,8,9 \
,10,11,12,13,14,15,16,17,18,19 \
,20,21,22,23,24,25,26,27,28,29 \
,30,31,32,33,34,35,36,37,38,39 \
};
SimpleGraph::SimpleGraph(const GRAPH_ADJARRAY_VECTOR adjgraph)
:m_srcAdjArray(adjgraph)
{
adjArray2adjList(m_srcAdjArray,m_dstAdjList);
}
void SimpleGraph::adjArray2adjList(const GRAPH_ADJARRAY_VECTOR &srcAdjArray, GRAPH_ADJLIST_MAP &dstAdjList)
{
int ncount;
assert( srcAdjArray.size() < MAXVERTEX);
for (int i = 0; i < srcAdjArray.size(); ++i){
ADJPOINTSSET s;
ncount = 0;
for(int j= 0; j< srcAdjArray[i].size(); ++j)
{
if(srcAdjArray[i][j] != 0)
{
s.insert(j + globalOffset[i]);
ncount ++;
}
}
ADJPOINTSPAIR adjPointsPair(ncount,s);
dstAdjList.insert(make_pair(i,adjPointsPair));
}
GRAPH_ADJLIST_MAP::iterator it;
for(it = m_dstAdjList.begin(); it != m_dstAdjList.end(); it++)
{
ADJPOINTSSET s = it->second.second;
ADJPOINTSSET::iterator adjset_it;
for(adjset_it = s.begin(); adjset_it != s.end(); adjset_it++) {
if(*adjset_it > it->first)
{
inc(*adjset_it, it->first);
}
}
}
}
VERTEXCOVER SimpleGraph::getVertexCover()
{
VERTEXCOVER s;
ADJPOINTSSET tmps;
ADJPOINTSSET::iterator adjset_it;
#if PRINTINFO
cout << "====================================================" << endl;
cout << "v d s" << endl;
cout << "-----" << endl;
print();
#endif
//1.put the highest degree vertex in the cover set
GRAPH_ADJLIST_MAP::iterator it, it_target;
while (1) {
#if PRINTINFO
cout << "step1.put the highest degree vertex in the cover set" << endl;
#endif
int nMaxDegree = 0;
it_target = m_dstAdjList.begin();
for(it = m_dstAdjList.begin(); it != m_dstAdjList.end(); it++)
{
// cout << it->first << " " << it->second.first << endl;
if(nMaxDegree < it->second.first)
{
nMaxDegree = it->second.first;
it_target = it;
}
}
#if PRINTINFO
cout << "it_target is " << it_target->first << " " << it_target->second.first << endl;
#endif
if(it_target->second.first == 0) break;
s.insert(it_target->first);
#if PRINTINFO
cout << "one of highest degree vertex is vertex: " << it_target->first << endl;
SimpleGraph::printVertexSet(s);
cout << "step2.update the degree of vertexes in the list.if 0, remove it." << endl;
#endif
//2.update the degree of vertexes in the list.if 0, remove it.
tmps= it_target->second.second;
for(adjset_it = tmps.begin(); adjset_it != tmps.end(); adjset_it++) {
dec(*adjset_it, it_target->first);
}
it_target->second.first = 0;
it_target->second.second.clear();
#if PRINTINFO
SimpleGraph::print();
#endif
}
#if PRINTINFO
cout << "step3.Exit the loop,get the one of cover set" << endl;
#endif
return s;
}
void SimpleGraph::help()
{
if(m_srcAdjArray.size() == 0)
{
cout << "Adjacency Array vector is null\n";
return;
}
int i = 0;
for (auto& line : m_srcAdjArray) {
for (int j=0; j< i; j++) {
cout << " ";
}
for (const auto& v : line) {
cout << v << " ";
}
cout << endl;
i++;
}
}
void SimpleGraph::printVertexSet(VERTEXCOVER s)
{
#if 1
ADJPOINTSSET::iterator adjset_it;
cout << "{";
for(adjset_it = s.begin(); adjset_it != s.end(); adjset_it++) {
cout << *adjset_it << " ";
}
cout << "}" << endl;
#endif
}
void SimpleGraph::print()
{
#if 1
GRAPH_ADJLIST_MAP::iterator it;
for(it = m_dstAdjList.begin(); it != m_dstAdjList.end(); it++)
{
//输出Node的key值,度数值 和相邻顶点集合
cout << it->first << " " << it->second.first << " ";
SimpleGraph::printVertexSet(it->second.second);
}
#endif
}
void SimpleGraph::inc(int keyVertex, int targetVertex)
{
m_dstAdjList.at(keyVertex).first += 1;
m_dstAdjList.at(keyVertex).second.insert(targetVertex);
}
void SimpleGraph::dec(int keyVertex, int targetVertex)
{
m_dstAdjList.at(keyVertex).first -= 1;
m_dstAdjList.at(keyVertex).second.erase(targetVertex);
}