1.接上篇的类的设计
#ifndef PATHARRAY4SIMPLEGRAPH_H
#define PATHARRAY4SIMPLEGRAPH_H
#include <iostream>
#include <vector>
using namespace std;
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;
class PathArray4SimpleGraph
{
public:
PathArray4SimpleGraph(const GRAPH_ADJ adjgraph);
PathArray4SimpleGraph operator*(const PathArray4SimpleGraph rc);
private:
GRAPH_ADJ m_srcAdjArray;
SINGLE_PATH_ARRAY m_srcPathArray;
MULTI_PATHS_ARRAY m_multiPathsArray;
private:
void printAdjArray(const GRAPH_ADJ &adjArray);
void printPathArray(const SINGLE_PATH_ARRAY &pathArray);
void printPathsArray(const MULTI_PATHS_ARRAY &pathsArray);
public:
void adjArray2PathArray(const GRAPH_ADJ &srcAdjArray, SINGLE_PATH_ARRAY &dstPathArray);
void pathArray2PathsArray(const SINGLE_PATH_ARRAY &pathArray, MULTI_PATHS_ARRAY &pathsArray);
void help();
PathArray4SimpleGraph* clone() const { return new PathArray4SimpleGraph( *this );}
};
#endif // PATHARRAY4SIMPLEGRAPH_H
2.乘法设计
#include "patharray4simplegraph.h"
#include <iostream>
#include<QRandomGenerator>
const int MAXRANDOM=1000;
PathArray4SimpleGraph::PathArray4SimpleGraph(const GRAPH_ADJ adjgraph):
m_srcAdjArray(adjgraph)
{
adjArray2PathArray(m_srcAdjArray,m_srcPathArray);
pathArray2PathsArray(m_srcPathArray, m_multiPathsArray);
}
//print the source adjacency matrices to debug
void PathArray4SimpleGraph::printAdjArray(const GRAPH_ADJ &adjArray)
{
if(adjArray.size() == 0)
{
cout << "Adjacency Array vector is null\n";
return;
}
for (auto& line : adjArray) {
for (const auto& v : line) {
cout << v << " ";
}
cout << endl;
}
}
//print the source path Array to debug
void PathArray4SimpleGraph::printPathArray(const SINGLE_PATH_ARRAY &pathArray)
{
if(pathArray.size() == 0)
{
cout << "Path Array vector is null\n";
return;
}
for (auto& line : pathArray) {
for (const auto& path : line) {
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 << endl;
}
}
//print the source paths Array to debug
void PathArray4SimpleGraph::printPathsArray(const MULTI_PATHS_ARRAY &pathsArray)
{
if(pathsArray.size() == 0)
{
cout << "Paths Array vector is null\n";
return;
}
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;
}
}
void PathArray4SimpleGraph::help()
{
printPathsArray(m_multiPathsArray);
}
void PathArray4SimpleGraph::adjArray2PathArray(const GRAPH_ADJ &srcAdjArray, SINGLE_PATH_ARRAY &dstPathArray)
{
dstPathArray.resize(srcAdjArray.size());
for (int i = 0; i < srcAdjArray.size(); ++i){
dstPathArray[i].resize(srcAdjArray.size());
}
for (int i = 0; i < srcAdjArray.size(); ++i){
for(int j= 0; j< srcAdjArray.size(); ++j)
{
if(srcAdjArray[i][j] == 0)
{
dstPathArray[i][j].push_back(0);
} else {
dstPathArray[i][j].push_back(i);
dstPathArray[i][j].push_back(j);
}
}
}
}
void PathArray4SimpleGraph::pathArray2PathsArray(const SINGLE_PATH_ARRAY &pathArray, MULTI_PATHS_ARRAY &pathsArray)
{
pathsArray.resize(pathArray.size());
for (int i = 0; i < pathArray.size(); ++i){
pathsArray[i].resize(pathArray.size());
}
for (int i = 0; i < pathArray.size(); ++i){
for(int j= 0; j< pathArray.size(); ++j)
{
pathsArray[i][j].resize(1);
pathsArray[i][j][0]=pathArray[i][j];
}
}
}
PathArray4SimpleGraph PathArray4SimpleGraph::operator*(const PathArray4SimpleGraph pathArrayG)
{
PathArray4SimpleGraph retgraph(pathArrayG.m_srcAdjArray);
retgraph.m_multiPathsArray.clear();
MULTI_PATHS_ARRAY retPathsArr;
//initialize the retPathArray
retPathsArr.resize(this->m_multiPathsArray.size());
for (int i=0; i < this->m_multiPathsArray.size(); ++i) {
retPathsArr[i].resize(this->m_multiPathsArray.size());
}
for (int i = 0; i < this->m_multiPathsArray.size(); ++i){
for(int j= 0; j< this->m_multiPathsArray.size(); ++j)
{
PATHS retPaths;
for (int k=0; k < this->m_multiPathsArray.size(); ++k) {
//if one of path is [0], the result is 0
if(((this->m_multiPathsArray[i][k].size() == 1) && (this->m_multiPathsArray[i][k][0].size() == 1))
|| ((pathArrayG.m_multiPathsArray[k][j].size() == 1) && (pathArrayG.m_multiPathsArray[k][j][0].size() == 1)))
{
continue;
}
for (int x = 0; x < this->m_multiPathsArray[i][k].size(); ++x){
for(int y= 0; y< pathArrayG.m_multiPathsArray[k][j].size(); ++y)
{
PATH tempPath;
PATH op1path = this->m_multiPathsArray[i][k][x];
PATH op2path = pathArrayG.m_multiPathsArray[k][j][y];
bool bFlagCross = false;
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;
}
}
}
if( !bFlagCross ){
tempPath = op1path;
for(int n=1; n< op2path.size(); ++n)
{
tempPath.push_back(op2path[n]);
}
}
}
retPaths.push_back(tempPath);
}
}
}
retPathsArr[i][j].assign(retPaths.begin(),retPaths.end());
//if the path is null, fill it with zero
if(retPathsArr[i][j][0].size() == 0)
{
retPathsArr[i][j].resize(1);
retPathsArr[i][j][0].push_back(0);
}
}
}
retgraph.m_multiPathsArray.assign(retPathsArr.begin(),retPathsArr.end());
return retgraph;
}
3.测试程序;
#include "patharray4simplegraph.h"
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[])
{
/*
(0)--(1)--(2)
| / \ |
| / \ |
| / \ |
(3)-------(4)
*/
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}
};
cout << "G1" << endl;
PathArray4SimpleGraph* G1 = new PathArray4SimpleGraph(graph);
G1->help();
cout << "G2" << endl;
PathArray4SimpleGraph* G2 = G1->clone();
G2->help();
cout << "G3 = G1*G2" << endl;
PathArray4SimpleGraph G3 = (*G1) * (*G2);
G3.help();
return 1;
}
4.实验结果
5. 说明
1)这一版的构造函数,参数不是顶点个数(维数),由随机数生成邻接矩阵,而是直接用邻接矩阵作为参数,便于后续批处理;
2)显示函数单独出来,不需要在构造函数里面打印。