0) 工程文件
QT -= gui
CONFIG += c++11 console
CONFIG -= app_bundle
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += WIN32
DEFINES += _WINDOWS
DEFINES += NDEBUG
DEFINES += BLOCKING_MODE
DEFINES += NO_DEFAULT_MAPPING
DEFINES += _WIN64
DEFINES += _AMD64_
DEFINES += NOMINMAX
DEFINES += USE_CMAKE_CONFIG
DEFINES += _CRT_SECURE_NO_WARNINGS
DEFINES += CMAKE_INTDIR="Release"
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
INCLUDEPATH += $$PWD/../../fastflow
1)源码
#include <QCoreApplication>
#include <ff/pipeline.hpp>
#include <iostream>
#include <vector>
using namespace std;
using namespace ff;
typedef vector<int> PATH;
typedef vector<PATH> PATHS;
typedef vector<vector<bool> > GRAPH_ADJ;
typedef vector<vector<PATH> > SINGLE_PATH_ARRAY;
typedef vector<vector<PATHS> > MULTI_PATHS_ARRAY;
struct Task
{
MULTI_PATHS_ARRAY mpa;
};
typedef Task myTask;
static myTask simpleGraph;
MULTI_PATHS_ARRAY pathArrayMultiply(const MULTI_PATHS_ARRAY m_multiPathsArray, const MULTI_PATHS_ARRAY pathArrayG, MULTI_PATHS_ARRAY& retPathsArr)
{
//initialize the retPathArray
retPathsArr.resize(pathArrayG.size());
for (int i=0; i < pathArrayG.size(); ++i) {
retPathsArr[i].resize(pathArrayG.size());
}
for (int i = 0; i < pathArrayG.size(); ++i){
for(int j= 0; j< pathArrayG.size(); ++j)
{
PATHS retPaths;
for (int k=0; k < pathArrayG.size(); ++k) {
//if one of path is [0], the result is 0
if(((m_multiPathsArray[i][k].size() == 1) && (m_multiPathsArray[i][k][0].size() == 1))
|| ((pathArrayG[k][j].size() == 1) && (pathArrayG[k][j][0].size() == 1)))
{
continue;
}
for (int x = 0; x < m_multiPathsArray[i][k].size(); ++x){
for(int y= 0; y< pathArrayG[k][j].size(); ++y)
{
PATH tempPath;
PATH op1path = m_multiPathsArray[i][k][x];
PATH op2path = pathArrayG[k][j][y];
bool bFlagCross = false;
int nCrossCount = 0;
if(op1path[op1path.size() -1] == op2path[0])
{
for (int m = 0; m < op1path.size() - 1; ++m) {
for (int n=0; n < op2path.size(); ++n) {
if (op1path[m] == op2path[n]){
bFlagCross = true;
nCrossCount ++;
}
}
}
if((op1path[0] == op2path[op2path.size() -1]) && (nCrossCount == 1))
{
if(m_multiPathsArray.size() == op1path.size() + op2path.size() - 2)
bFlagCross = false;
}
if( !bFlagCross ){
tempPath = op1path;
for(int n=1; n< op2path.size(); ++n)
{
tempPath.push_back(op2path[n]);
}
}
}
retPaths.push_back(tempPath);
}
}
}
for (const auto& path: retPaths) {
if (path.size() !=0){
retPathsArr[i][j].push_back(path);
}
}
//if the path is null, fill it with zero
if(retPathsArr[i][j].size() == 0)
{
retPathsArr[i][j].resize(1);
retPathsArr[i][j][0].push_back(0);
}
}
}
return retPathsArr;
}
bool isZero(MULTI_PATHS_ARRAY m_multiPathsArray)
{
bool bRet = true;
for (int i = 0; i < m_multiPathsArray.size(); ++i){
for(int j= 0; j< m_multiPathsArray.size(); ++j)
{
if (!((m_multiPathsArray[i][j].size() == 1) && (m_multiPathsArray[i][j][0][0] == 0)
|| (m_multiPathsArray[i][j].size() ==0)))
return false;
}
}
return bRet;
}
struct firstStage: ff_node_t<myTask>{
myTask *svc(myTask*){
std::cout << "hello, I am stage" << get_my_id() + 1 << std::endl;
vector<vector<bool>> graph = {
{0, 1, 0, 1, 0},
{1, 0, 1, 1, 1},
{0, 1, 0, 0, 1},
{1, 1, 0, 0, 1},
{0, 1, 1, 1, 0}
};
SINGLE_PATH_ARRAY singlePathArray;
singlePathArray.resize(graph.size());
for (int i = 0; i < graph.size(); ++i){
singlePathArray[i].resize(graph.size());
}
for (int i = 0; i < graph.size(); ++i){
for(int j= 0; j< graph.size(); ++j)
{
if(graph[i][j] == 0)
{
singlePathArray[i][j].push_back(0);
} else {
singlePathArray[i][j].push_back(i);
singlePathArray[i][j].push_back(j);
}
}
}
MULTI_PATHS_ARRAY& pathsArray = simpleGraph.mpa;
pathsArray.resize(singlePathArray.size());
for (int i = 0; i < singlePathArray.size(); ++i){
pathsArray[i].resize(singlePathArray.size());
}
for (int i = 0; i < singlePathArray.size(); ++i){
for(int j= 0; j< singlePathArray.size(); ++j)
{
pathsArray[i][j].resize(1);
pathsArray[i][j][0]=singlePathArray[i][j];
}
}
ff_send_out(new myTask(simpleGraph));
return EOS;
}
};
struct secondStage: ff_node_t<myTask>{
myTask *svc(myTask* t){
std::cout << "hello, I am stage" << get_my_id() + 1 << std::endl;
myTask* productTask = new myTask();
pathArrayMultiply(t->mpa, simpleGraph.mpa, productTask->mpa);
if (t != NULL){
delete t;
t = NULL;
}
return productTask;
}
};
struct thirdStage: ff_node_t<myTask>{
myTask *svc(myTask* t){
std::cout << "hello, I am stage" << get_my_id() + 1 << std::endl;
myTask* productTask = new myTask();
pathArrayMultiply(t->mpa, simpleGraph.mpa, productTask->mpa);
if (t != NULL){
delete t;
t = NULL;
}
return productTask;
}
};
struct forthStage: ff_node_t<myTask>{
myTask *svc(myTask* t){
std::cout << "hello, I am stage" << get_my_id() + 1 << std::endl;
myTask* productTask = new myTask();
pathArrayMultiply(t->mpa, simpleGraph.mpa, productTask->mpa);
if (t != NULL){
delete t;
t = NULL;
}
return productTask;
}
};
struct fifthStage: ff_node_t<myTask>{
myTask *svc(myTask* task){
std::cout << "hello, I am stage" << get_my_id() + 1 << std::endl;
myTask* productTask = new myTask();
pathArrayMultiply(task->mpa, simpleGraph.mpa, productTask->mpa);
if (task != NULL){
delete task;
task = NULL;
}
MULTI_PATHS_ARRAY pathsArray = productTask->mpa;
if (isZero(pathsArray)){
error("Not a Hamilton Graph");
}
else {
if(pathsArray.size() == 0)
{
cout << "Paths Array vector is null\n";
return GO_ON;
}
std::cout << "This is a Hamilton Graph. Path is shown in following Array Diagonal" << std::endl;
for (auto& line : pathsArray) {
for (const auto& column : line) {
cout << "[";
for (const auto& path: column) {
if (path.size() == 1){
cout << "[0]";
continue;
}
cout << "[";
for (size_t i = 0; i < path.size(); ++i) {
cout << path[i];
if (i != path.size() - 1)
cout << "->";
}
cout << "]";
}
cout << "]";
}
cout << endl;
}
}
std::cout << std::endl;
if (productTask != NULL){
delete productTask;
productTask = NULL;
}
return GO_ON;
}
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
firstStage _1;
secondStage _2;
thirdStage _3;
forthStage _4;
fifthStage _5;
ff_Pipe<> pipe(_1, _2, _3, _4, _5);
if(pipe.run_and_wait_end() <0) {
error("running pipe");
}
return a.exec();
}
2)运行结果