Hamiton图系列文章 (4) :Hamilton图判定充要条件优化与实现

在前三篇系列文章中,判定算法是基于图用邻接矩阵的表示,道路矩阵也是如此。事实上,因为邻接矩阵总是对称的,用一个上三角矩阵也可以表示。本文针对用上三角矩阵的表示法对原算法进行优化与实现。运算次数减少近一半。

1.源码:

1)优化的道路矩阵类头文件

#ifndef PATHARRAYOPTIMIZED_H
#define PATHARRAYOPTIMIZED_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 PathArrayOptimized
{
public:
    PathArrayOptimized(const GRAPH_ADJ adjgraph);
    PathArrayOptimized operator*(const PathArrayOptimized rc);

    static vector<int> globalOffset;
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);
    PATH reversePath(PATH path);

public:
    void adjArray2PathArray(const GRAPH_ADJ &srcAdjArray, SINGLE_PATH_ARRAY &dstPathArray);
    void pathArray2PathsArray(const SINGLE_PATH_ARRAY &pathArray, MULTI_PATHS_ARRAY &pathsArray);
    bool isZero();


    void help();

    PathArrayOptimized* clone() const { return new PathArrayOptimized( *this );}

};

#endif // PATHARRAYOPTIMIZED_H

2)优化的道路矩阵类实现文件

#include "patharrayoptimized.h"

vector<int> PathArrayOptimized::globalOffset = {0,1,2,3,4};

PathArrayOptimized::PathArrayOptimized(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 PathArrayOptimized::printAdjArray(const GRAPH_ADJ &adjArray)
{
    if(adjArray.size() == 0)
    {
        cout << "Adjacency Array vector is null\n";
        return;
    }

    int i = 0;
    for (auto& line : adjArray) {
        for (int j=0; j< i; j++) {
            cout << "  ";
        }
        for (const auto& v : line) {
            cout << v << " ";
        }
        cout << endl;
        i++;
    }
}

//print the source path Array to debug
void PathArrayOptimized::printPathArray(const SINGLE_PATH_ARRAY &pathArray)
{
    if(pathArray.size() == 0)
    {
        cout << "Path Array vector is null\n";
        return;
    }

    int i = 0;
    for (auto& line : pathArray) {
        for (int j=0; j< i; j++) {
            cout << "   ";
        }

        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;
        i++;
    }
}

//print the source paths Array to debug
void PathArrayOptimized::printPathsArray(const MULTI_PATHS_ARRAY &pathsArray)
{
    if(pathsArray.size() == 0)
    {
        cout << "Paths Array vector is null\n";
        return;
    }

    int i = 0;
    for (auto& line : pathsArray) {
        for (int j=0; j< i; j++) {
            cout << "     ";
        }

        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;

        i++;
    }
}

void PathArrayOptimized::help()
{
    printPathsArray(m_multiPathsArray);
}

void PathArrayOptimized::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[i].size());
    }

    for (int i = 0; i < srcAdjArray.size(); ++i){
        for(int j= 0; j< srcAdjArray[i].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 + globalOffset[i]);
            }

        }
    }
}

void PathArrayOptimized::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[i].size());
    }

    for (int i = 0; i < pathArray.size(); ++i){
        for(int j= 0; j< pathArray[i].size(); ++j)
        {
            pathsArray[i][j].resize(1);
            pathsArray[i][j][0]=pathArray[i][j];
        }
    }
}

PathArrayOptimized PathArrayOptimized::operator*(const PathArrayOptimized pathArrayG)
{
    PathArrayOptimized 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[i].size());
    }

    for (int i = 0; i < this->m_multiPathsArray.size(); ++i){
        for(int j1= 0; j1< this->m_multiPathsArray[i].size(); ++j1)
        {
            int j = j1 + globalOffset[i];
            PATHS retPaths;

            for (int k=0; k < this->m_multiPathsArray.size(); ++k) {
                //if one of path is [0], the result is 0
                if (k<i) {
                    if((this->m_multiPathsArray[k][i-globalOffset[k]].size() == 1) && (this->m_multiPathsArray[k][i-globalOffset[k]][0].size() == 1))
                    {
                        continue;
                    }
                } else {
                    if((this->m_multiPathsArray[i][k - globalOffset[i]].size() == 1) && (this->m_multiPathsArray[i][k - globalOffset[i]][0].size() == 1))
                    {
                        continue;
                    }
                }

                if (j<k) {
                    if((pathArrayG.m_multiPathsArray[j][k - globalOffset[j]].size() == 1) && (pathArrayG.m_multiPathsArray[j][k - globalOffset[j]][0].size() == 1))
                    {
                        continue;
                    }
                } else {
                    if((pathArrayG.m_multiPathsArray[k][j - globalOffset[k]].size() == 1) && (pathArrayG.m_multiPathsArray[k][j - globalOffset[k]][0].size() == 1))
                    {
                        continue;
                    }
                }

                if(k< i) {
                    for (int x = 0; x < this->m_multiPathsArray[k][i - globalOffset[k]].size(); ++x){
                        if (j<k) {
                            for(int y= 0; y< pathArrayG.m_multiPathsArray[j][k - globalOffset[j]].size(); ++y)
                            {
                                PATH tempPath;
                                PATH inversePath1;
                                PATH inversePath2;

                                inversePath1 = reversePath(this->m_multiPathsArray[k][i-globalOffset[k]][x]);
                                inversePath2 = reversePath(pathArrayG.m_multiPathsArray[j][k-globalOffset[j]][y]);
                                PATH op1path = inversePath1;
                                PATH op2path = inversePath2;
                                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(this->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);

                            }
                        } else {
                            for(int y= 0; y< pathArrayG.m_multiPathsArray[k][j-globalOffset[k]].size(); ++y)
                            {
                                PATH tempPath;
                                PATH inversePath1;
                                inversePath1 = reversePath(this->m_multiPathsArray[k][i-globalOffset[k]][x]);
                                PATH op1path = inversePath1;
                                PATH op2path = pathArrayG.m_multiPathsArray[k][j-globalOffset[k]][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(this->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);

                            }
                        }
                    }
                } else {
                    for (int x = 0; x < this->m_multiPathsArray[i][k-globalOffset[i]].size(); ++x){
                        if (j<k) {
                            for(int y= 0; y< pathArrayG.m_multiPathsArray[j][k-globalOffset[j]].size(); ++y)
                            {
                                PATH tempPath;

                                PATH inversePath2;
                                inversePath2 = reversePath(pathArrayG.m_multiPathsArray[j][k-globalOffset[j]][y]);

                                PATH op1path = this->m_multiPathsArray[i][k-globalOffset[i]][x];
                                PATH op2path = inversePath2;
                                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(this->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);

                            }
                        } else {
                            for(int y= 0; y< pathArrayG.m_multiPathsArray[k][j-globalOffset[k]].size(); ++y)
                            {
                                PATH tempPath;
                                PATH op1path = this->m_multiPathsArray[i][k-globalOffset[i]][x];
                                PATH op2path = pathArrayG.m_multiPathsArray[k][j-globalOffset[k]][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(this->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][j1].push_back(path);
                }
            }

            //if the path is null, fill it with zero
            if(retPathsArr[i][j1].size() == 0)
            {
                retPathsArr[i][j1].resize(1);
                retPathsArr[i][j1][0].push_back(0);
            }
        }
    }

    retgraph.m_multiPathsArray.assign(retPathsArr.begin(),retPathsArr.end());

    return retgraph;
}

PATH PathArrayOptimized::reversePath(PATH path){
    PATH pathRet = path;
    reverse(pathRet.begin(), pathRet.end());
    return pathRet;
}

bool PathArrayOptimized::isZero()
{
    bool bRet = true;
    for (int i = 0; i < m_multiPathsArray.size(); ++i){
        for(int j= 0; j< m_multiPathsArray[i].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;
}


3)测试主程序

#include "patharrayoptimized.h"
using namespace std;

int main(int argc, char *argv[])
{
    /*
    (0)--(1)--(2)
    |   / \   |
    |  /   \  |
    | /     \ |
    (3)-------(4)
    */
    vector<vector<bool>> graph = {
            {0, 1, 0, 1, 0},
               {0, 1, 1, 1},
                  {0, 0, 1},
                     {0, 1},
                        {0}
                                };

    cout << "G1" << endl;
    PathArrayOptimized G1(graph);
    G1.help();

    PathArrayOptimized G = G1;

    for (int i=0; i<4; i++) {
        G = G * G1;
        cout << "G" << i+2 << endl;
        G.help();
    }


    if(G.isZero()){
        cout << "G does not have Hamilton circle\n";
    } else {
        cout << "G is Hamilton Graph with hamilton circle\n";
    }

    return 1;
}

2.执行结果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值