C/C++程序之根据有向图、无向图求通路、回路、可达矩阵

7 篇文章 0 订阅

前言

最近《离散数学》老师突发奇想,让我们用程序完成课本作业……总体而言,其实蛮简单,只要理清解题过程即可,根本没用到什么特殊的算法……无非也就动态分配数组。

要算的,就算出不同长度下的通路、回路个数,或者可达矩阵,如果后期要再加上什么,我会再补充修改的。

!!! 注意,一定要看变量或函数的英文意思,因为有时候我写多了,感觉注释太多就删掉了注释,英文名是最好的注释!! TK

有几个变量通常不会改变,比如**matrixArray,指的是设置的矩阵,matrixSize指的是矩阵的阶数。

题目分析

题目就一个有向图、无向图,那么怎么计算通路或回路个数呢?很简单。

  1. 对于有向图,假设从a点到c点有一条指向的单一通路,那么对于坐标(a,c)就是1,若c到a也有一条单一指向的通路,那么对于坐标(c,a)也是1,若没有,就是0;
  2. 对于无向图,也是如此,不同点在于,因为无向图没有指向,所以对于a点到c点是1,假设又有一条路从c到a(不是上一条路),即a点和c点处于一个圆上,那么这(a,c)为2,且(c,a)也为2;
  3. 下面拿个例子分析,具体的自己找规律:
    无向图
    如图为一个无向图,(a,b) = 1, (b,a) = 1, (b,b) = 1, (b,c) = 1, (c,b) = 1, (c,d) = 2, (d,c) = 2, (d,e) = 1, (e,d) = 1,所以得到的邻接矩阵如下:
    _ | a | b | c | d | e | f
    a-| 0 | 1 | 0 | 0 | 0 | 0
    b-| 1 | 1 | 1 | 0 | 0 | 0
    c-| 0 | 1 | 0 | 2 | 0 | 0
    d-| 0 | 0 | 2 | 0 | 1 | 0
    e-| 0 | 0 | 0 | 1 | 0 | 0
    f -| 0 | 0 | 0 | 0 | 0 | 0
  4. 假设矩阵如上所示,则无向图中的b点到c点的通路就是矩阵(b,c) = 1,而回路个数则是无向图中的某点到自身的值,即(b,b) = 1。
  5. 长度,最简单的说,就是矩阵自乘多少次,n个长度的(i,j)点通路,就是该矩阵A的n次方后,(i,j)的值是多少就是多少。
  6. 可达矩阵,求法就是在邻接矩阵的基础上不断将每个长度的矩阵求和,最后对角线全部置1,非对角线上的每个非0元素置1。假设可达矩阵R,矩阵阶数为n,则Rt = A ^1 + A ^2 + A ^3 + … + A ^(n-1),然后再把Rt的对角线每个点置1,非对角线每个非零元素置1,即可得到可达矩阵R。
  7. 题目中有几个问题,一个是求a点到d点长度分别为1,2,3,4,5的通路各有多少,一个是求a点到d点长度小于等于3的通路有多少条。可知,前一个求的必须是个数组,返回不同的结果的数组,而后者则是每个长度下的矩阵的那个(a,d)的值之和,返回一个int。

流程图

程序流程图
说是这么说,实际我并不全这么写,比如为了省事,我把“再次选择计算方式”的循环去掉了。

另外,为什么所有计算方法都指向一个矩阵乘积的函数呢?
因为,这个函数决定了绝大部分的内容,不同的计算方式都通过该函数得到想要的那个长度下的矩阵,接着才对得到的矩阵进行求和、统计、拆分之类的功能。

为什么矩阵乘积函数返回的是空值void?
因为在几乎每个计算函数里面都初始化了一个二维指针数组,这个是临时的指针,动态分配的数组,这个指针用于传递给矩阵乘积函数,矩阵乘积函数直接就可以修改指针指向的值,而不需要返回任何东西,所以这个矩阵乘积函数的返回值是void。同样的,有的函数甚至还设置了接收指针,这些指针的作用也是一样的,或者说是类似的,凑合着听懂就行。

函数方法分析

主函数:没啥用(其实用处SuperSuper大),略过。

其实,就是用于设置循环啊、矩阵阶数等一些最基本的东西。

设置初始矩阵的函数setMatrixArray()

/*
* @description 初始化矩阵
* @param matrixArray 初始矩阵,调用方指针、接收结果矩阵的调用方指针
* @param matrixSize 矩阵尺度
*/
void setMatrixArray(int** matrixArray, int matrixSize);
void setMatrixArray(int** matrixArray, int matrixSize)
{
	std::cout << "Please input matrix: (Space off) " << std::endl;
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			scanf_s("%d", &matrixArray[i][j]);
		}
	}
}

矩阵乘积函数multiplicineMatrixCalculate()

/*
* @description 矩阵乘积计算
* @param **matrixArray 调用方矩阵
* @param **aheadMatrixArray 前矩阵
* @param **afterMatrixArray 后矩阵
* @param matrixSize 矩阵尺度
* @param **acceptCalculateMatrix 接收矩阵的调用方指针
*/
void multiplicineMatrixCalculate(int** aheadMatrixArray, int** afterMatrixArray, int matrixSize, int** acceptCalculateMatrix);

void multiplicineMatrixCalculate(int** aheadMatrixArray, int** afterMatrixArray, int matrixSize, int** acceptCalculateMatrix)
{
	// 前行×后列之和
	int mulOrderSum = 0;
	int** calculateTemporMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}

	// 矩阵阶乘
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			mulOrderSum = 0;
			for (int k = 0; k < matrixSize; k++)
			{
				mulOrderSum = mulOrderSum + aheadMatrixArray[i][k] * afterMatrixArray[k][j];
				calculateTemporMatrix[i][j] = mulOrderSum;
			}
		}
	}

	// 传递计算结果值给调用方指针
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			acceptCalculateMatrix[i][j] = calculateTemporMatrix[i][j];
		}
	}

	// Free
	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrix[i]);
	}
	free(calculateTemporMatrix);
}

获得指定长度的矩阵multiplicineMatrixResult()

注意,使用该函数会直接改变传入的矩阵指针。

/*
* @description 计算某个距离长度的矩阵(注意该方法会直接修改传入的矩阵)
* @param **matrixArray 初始矩阵、接收矩阵的调用方指针
* @param matrixSize 矩阵尺度
* @param setLength 距离长度
*/
void multiplicineMatrixResult(int** matrixArray, int matrixSize, int setLength);
void multiplicineMatrixResult(int** matrixArray, int matrixSize, int setLength)
{
	int** calculatedMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculatedMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculatedMatrix[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 0; i < setLength - 1; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculatedMatrix, matrixSize, calculatedMatrix);
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			matrixArray[i][j] = calculatedMatrix[i][j];
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculatedMatrix[i]);
	}
	free(calculatedMatrix);
}

求可达矩阵getReachableMatrix()

/*
* @description 根据有向图、无向图计算可达矩阵
* @param **matrixArray 初始普通矩阵
* @param matrixSize 矩阵尺度
* @param reachableMatrix 调用方接收的可达矩阵指针
*/
void getReachableMatrix(int** matrixArray, int matrixSize, int** reachableMatrix);
void getReachableMatrix(int** matrixArray, int matrixSize, int** reachableMatrix)
{
	int** calculatedMatrix = (int**)malloc(matrixSize * sizeof(int*));
	int** temporMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculatedMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
		temporMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculatedMatrix[i][j] = matrixArray[i][j];
			temporMatrix[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < matrixSize - 1; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculatedMatrix, matrixSize, calculatedMatrix);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				temporMatrix[m][n] = temporMatrix[m][n] + calculatedMatrix[m][n];
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			if (j == i)
			{
				temporMatrix[i][j] = 1;
			}
			else if (temporMatrix[i][j] != 0)
			{
				temporMatrix[i][j] = 1;
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			reachableMatrix[i][j] = temporMatrix[i][j];
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(temporMatrix[i]);
		free(calculatedMatrix[i]);
	}
	free(temporMatrix);
	free(calculatedMatrix);
}

求某长度某点的值getPointSetLength()

/*
* @description 求某个点某长度的值(即通路或回路数)
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param setLength 自定义长度
* @param pointRow 自定义点横坐标
* @param pointLine 自定义点的纵坐标
* @param pointValue 某个点某长度的值(即通路或回路数)
*/
int getPointSetLength(int** matrixArray, int matrixSize, int setLength, int pointRow, int pointLine);
int getPointSetLength(int** matrixArray, int matrixSize, int setLength, int pointRow, int pointLine)
{
	int pointValue = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < setLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
	}
	pointValue = calculateTemporMatrixArray[pointRow - 1][pointLine - 1];

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);
	return pointValue;
}

求多个长度的通路数getArrayCustomMultiLength()

/*
* @description 计算自定义距离长度下矩阵的自定义点通路或回路个数,当且仅当pointRow == pointLine
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param *customLengthArray 自定义长度数组
* @param getLenArraySize 自定义长度尺度
* @param pointRow 自定义点横坐标
* @param pointLine 自定义点的纵坐标
* @param *acceptResultArray 自定义长度的自定义点通路或回路个数、调用方接收结果数组的指针
*/
void getArrayCustomMultiLength(int** matrixArray, int matrixSize, int* customLengthArray, int customLengthSize, int pointRow, int pointLine, int* acceptResultArray);

void getArrayCustomMultiLength(int** matrixArray, int matrixSize, int* customLengthArray, int customLengthSize, int pointRow, int pointLine, int* acceptResultArray)
{
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	// 获取自定义长度数组里面最长的长度 -- 获取到最大长度后只需要不断阶乘到该长度,获取想要的序号即可
	int maxCustomLength = 1;
	for (int i = 0; i < customLengthSize; i++)
	{
		if (maxCustomLength < customLengthArray[i])
		{
			maxCustomLength = customLengthArray[i];
		}
	}
	int* calculateTemporLengthArray = (int*)malloc(customLengthSize * sizeof(int));

	for (int i = 0; i < maxCustomLength; i++)
	{
		calculateTemporLengthArray[i] = calculateTemporMatrixArray[pointRow - 1][pointLine - 1];
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
	}

	// 遍历用户自定义长度数组 -- 并把calculateTemporLengthArray[customLengthArray[i]]传给acceptResultArray[i]
	for (int i = 0; i < customLengthSize; i++)
	{
		acceptResultArray[i] = calculateTemporLengthArray[customLengthArray[i] - 1];
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);
	free(calculateTemporLengthArray);
}

求某范围内的某点的通路数getCountPointRangeLength()

/*
* @description 统计某范围长度内自定义点的通路或回路之和,当且仅当pointRow == pointLine
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @param pointRow 自定义点的横坐标
* @param pointLine 自定义点的纵坐标
* @return sumRangeLengthArray 某范围长度内自定义点的通路或回路之和
*/
int getCountPointRangeLength(int** matrixArray, int matrixSize, int maxLength, int pointRow, int pointLine);

int getCountPointRangeLength(int** matrixArray, int matrixSize, int maxLength, int pointRow, int pointLine)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[pointRow - 1][pointLine - 1];
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}

求范围内所有点的通路数(包括回路)getAllPointRangeLengthAccess_HaveLoop()

/*
* @description 求某长度内所有点即通路和回路之和
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有点即通路和回路之和
*/
int getAllPointRangeLengthAccess_HaveLoop(int** matrixArray, int matrixSize, int maxLength);
int getAllPointRangeLengthAccess_HaveLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}

求范围内所有点的通路数(不包括回路)getAllPointRangeLengthAccess_NotLoop()

/*
* @description 求某长度内所有通路之和(不包括回路)
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有通路之和(不包括回路)
*/
int getAllPointRangeLengthAccess_NotLoop(int** matrixArray, int matrixSize, int maxLength);
int getAllPointRangeLengthAccess_NotLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			if (n != m)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				if (n != m)
				{
					sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
				}
				
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}

求范围内所有点的回路数getAllPointRangeLengthLoop()

/*
* @description 求某长度内所有回路之和
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有回路之和
*/
int getAllPointRangeLengthLoop(int** matrixArray, int matrixSize, int maxLength);
int getAllPointRangeLengthLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			if (n == m)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				if (n == m)
				{
					sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
				}

			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}

总代码

CalculateGraphicMatrix.h

/**************************************************************************
//
// Copyright:THDMI
//
// Author: HDM
//
// Date:2020-05-24
//
// Description:Calculate the Graphic according with Matrix and Length
//
**************************************************************************/

#pragma once

/*
* @description 求某个点某长度的值(即通路或回路数)
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param setLength 自定义长度
* @param pointRow 自定义点横坐标
* @param pointLine 自定义点的纵坐标
* @param pointValue 某个点某长度的值(即通路或回路数)
*/
int getPointSetLength(int** matrixArray, int matrixSize, int setLength, int pointRow, int pointLine);


/*
* @description 计算自定义距离长度下矩阵的自定义点通路或回路个数,当且仅当pointRow == pointLine
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param *customLengthArray 自定义长度数组
* @param getLenArraySize 自定义长度尺度
* @param pointRow 自定义点横坐标
* @param pointLine 自定义点的纵坐标
* @param *acceptResultArray 自定义长度的自定义点通路或回路个数、调用方接收结果数组的指针
*/
void getArrayCustomMultiLength(int** matrixArray, int matrixSize, int* customLengthArray, int customLengthSize, int pointRow, int pointLine, int* acceptResultArray);



/*
* @description 统计某范围长度内自定义点的通路或回路之和,当且仅当pointRow == pointLine
* @param **matrixArray 初始矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @param pointRow 自定义点的横坐标
* @param pointLine 自定义点的纵坐标
* @return sumRangeLengthArray 某范围长度内自定义点的通路或回路之和
*/
int getCountPointRangeLength(int** matrixArray, int matrixSize, int maxLength, int pointRow, int pointLine);



/*
* @description 求某长度内所有点即通路和回路之和
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有点即通路和回路之和
*/
int getAllPointRangeLengthAccess_HaveLoop(int** matrixArray, int matrixSize, int maxLength);



/*
* @description 求某长度内所有通路之和(不包括回路)
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有通路之和(不包括回路)
*/
int getAllPointRangeLengthAccess_NotLoop(int** matrixArray, int matrixSize, int maxLength);



/*
* @description 求某长度内所有回路之和
* @param **matrixArray 调用方矩阵指针
* @param matrixSize 矩阵尺度
* @param maxLength 最大距离长度
* @return sumRangeLengthArray 某长度内所有回路之和
*/
int getAllPointRangeLengthLoop(int** matrixArray, int matrixSize, int maxLength);



/*
* @description 初始化矩阵
* @param matrixArray 初始矩阵,调用方指针、接收结果矩阵的调用方指针
* @param matrixSize 矩阵尺度
*/
void setMatrixArray(int** matrixArray, int matrixSize);



/*
* @description 矩阵乘积计算
* @param **matrixArray 调用方矩阵
* @param **aheadMatrixArray 前矩阵
* @param **afterMatrixArray 后矩阵
* @param matrixSize 矩阵尺度
* @param **acceptCalculateMatrix 接收矩阵的调用方指针
*/
void multiplicineMatrixCalculate(int** aheadMatrixArray, int** afterMatrixArray, int matrixSize, int** acceptCalculateMatrix);



/*
* @description 计算某个距离长度的矩阵(注意该方法会直接修改传入的矩阵)
* @param **matrixArray 初始矩阵、接收矩阵的调用方指针
* @param matrixSize 矩阵尺度
* @param setLength 距离长度
*/
void multiplicineMatrixResult(int** matrixArray, int matrixSize, int setLength);



/*
* @description 根据有向图、无向图计算可达矩阵
* @param **matrixArray 初始普通矩阵
* @param matrixSize 矩阵尺度
* @param reachableMatrix 调用方接收的可达矩阵指针
*/
void getReachableMatrix(int** matrixArray, int matrixSize, int** reachableMatrix);

CalculateGraphicMatrix.cpp

/**************************************************************************
//
// Copyright:THDMI
//
// Author: HDM
//
// Date:2020-05-24
//
// Description:Calculate the Graphic according with Matrix and Length
//
**************************************************************************/

#include "CalculateGraphicMatrix.h"
#include <malloc.h>
#include <iostream>


/************************************* 已验证 ****************************************/

int getPointSetLength(int** matrixArray, int matrixSize, int setLength, int pointRow, int pointLine)
{
	int pointValue = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < setLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
	}
	pointValue = calculateTemporMatrixArray[pointRow - 1][pointLine - 1];

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);
	return pointValue;
}


/************************************* 已验证 ****************************************/

void getArrayCustomMultiLength(int** matrixArray, int matrixSize, int* customLengthArray, int customLengthSize, int pointRow, int pointLine, int* acceptResultArray)
{
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	// 获取自定义长度数组里面最长的长度 -- 获取到最大长度后只需要不断阶乘到该长度,获取想要的序号即可
	int maxCustomLength = 1;
	for (int i = 0; i < customLengthSize; i++)
	{
		if (maxCustomLength < customLengthArray[i])
		{
			maxCustomLength = customLengthArray[i];
		}
	}
	int* calculateTemporLengthArray = (int*)malloc(customLengthSize * sizeof(int));

	for (int i = 0; i < maxCustomLength; i++)
	{
		calculateTemporLengthArray[i] = calculateTemporMatrixArray[pointRow - 1][pointLine - 1];
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
	}

	// 遍历用户自定义长度数组 -- 并把calculateTemporLengthArray[customLengthArray[i]]传给acceptResultArray[i]
	for (int i = 0; i < customLengthSize; i++)
	{
		acceptResultArray[i] = calculateTemporLengthArray[customLengthArray[i] - 1];
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);
	free(calculateTemporLengthArray);
}


/************************************* 已验证 ****************************************/

int getCountPointRangeLength(int** matrixArray, int matrixSize, int maxLength, int pointRow, int pointLine)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[pointRow - 1][pointLine - 1];
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}


/************************************* 已验证 ****************************************/

int getAllPointRangeLengthAccess_HaveLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}


/************************************* 已验证 ****************************************/

int getAllPointRangeLengthAccess_NotLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			if (n != m)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				if (n != m)
				{
					sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
				}
				
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}


/************************************* 已验证 ****************************************/

int getAllPointRangeLengthLoop(int** matrixArray, int matrixSize, int maxLength)
{
	int sumRangeLengthArray = 0;
	int** calculateTemporMatrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculateTemporMatrixArray[i][j] = matrixArray[i][j];
		}
	}

	for (int m = 0; m < matrixSize; m++)
	{
		for (int n = 0; n < matrixSize; n++)
		{
			if (n == m)
			{
				sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
			}
		}
	}
	for (int i = 1; i < maxLength; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculateTemporMatrixArray, matrixSize, calculateTemporMatrixArray);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				if (n == m)
				{
					sumRangeLengthArray = sumRangeLengthArray + calculateTemporMatrixArray[m][n];
				}

			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrixArray[i]);
	}
	free(calculateTemporMatrixArray);

	return sumRangeLengthArray;
}


/************************************* 已验证 ****************************************/

void setMatrixArray(int** matrixArray, int matrixSize)
{
	std::cout << "Please input matrix: (Space off) " << std::endl;
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			scanf_s("%d", &matrixArray[i][j]);
		}
	}
}


/************************************* 已验证 ****************************************/

void multiplicineMatrixCalculate(int** aheadMatrixArray, int** afterMatrixArray, int matrixSize, int** acceptCalculateMatrix)
{
	// 前行×后列之和
	int mulOrderSum = 0;
	int** calculateTemporMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculateTemporMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}

	// 矩阵阶乘
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			mulOrderSum = 0;
			for (int k = 0; k < matrixSize; k++)
			{
				mulOrderSum = mulOrderSum + aheadMatrixArray[i][k] * afterMatrixArray[k][j];
				calculateTemporMatrix[i][j] = mulOrderSum;
			}
		}
	}

	// 传递计算结果值给调用方指针
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			acceptCalculateMatrix[i][j] = calculateTemporMatrix[i][j];
		}
	}

	// Free
	for (int i = 0; i < matrixSize; i++)
	{
		free(calculateTemporMatrix[i]);
	}

	free(calculateTemporMatrix);
}


/************************************* 已验证 ****************************************/

void multiplicineMatrixResult(int** matrixArray, int matrixSize, int setLength)
{
	int** calculatedMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculatedMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculatedMatrix[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 0; i < setLength - 1; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculatedMatrix, matrixSize, calculatedMatrix);
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			matrixArray[i][j] = calculatedMatrix[i][j];
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(calculatedMatrix[i]);
	}
	free(calculatedMatrix);
}


/************************************* 已验证 ****************************************/

void getReachableMatrix(int** matrixArray, int matrixSize, int** reachableMatrix)
{
	int** calculatedMatrix = (int**)malloc(matrixSize * sizeof(int*));
	int** temporMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		calculatedMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
		temporMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			calculatedMatrix[i][j] = matrixArray[i][j];
			temporMatrix[i][j] = matrixArray[i][j];
		}
	}

	for (int i = 1; i < matrixSize - 1; i++)
	{
		multiplicineMatrixCalculate(matrixArray, calculatedMatrix, matrixSize, calculatedMatrix);
		for (int m = 0; m < matrixSize; m++)
		{
			for (int n = 0; n < matrixSize; n++)
			{
				temporMatrix[m][n] = temporMatrix[m][n] + calculatedMatrix[m][n];
			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			if (j == i)
			{
				temporMatrix[i][j] = 1;
			}
			else if (temporMatrix[i][j] != 0)
			{
				temporMatrix[i][j] = 1;
			}
			{

			}
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			reachableMatrix[i][j] = temporMatrix[i][j];
		}
	}

	for (int i = 0; i < matrixSize; i++)
	{
		free(temporMatrix[i]);
		free(calculatedMatrix[i]);
	}
	free(temporMatrix);
	free(calculatedMatrix);
}

/*
  a b c d e f
a 0 1 0 0 0 0
b 1 1 1 0 0 0
c 0 1 0 2 0 0
d 0 0 2 0 1 0
e 0 0 0 1 0 0
f 0 0 0 0 0 0
*/

/*
				a     b     c     d     e
		  a   (1,1) (1,2) (1,3) (1,4) (1,5)
		  b   (2,1) (2,2) (2,3) (2,4) (2,5)
		  c   (3,1) (3,2) (3,3) (3,4) (3,5)
		  d   (4,1) (4,2) (4,3) (4,4) (4,5)
		  e   (5,1) (5,2) (5,3) (5,4) (5,5)
*/
int main(int argc, char** argv[], char** env[])
{
	// -------------------------- 设置矩阵阶数 -------------------------- //
	int matrixSize = 0;
	std::cout << "设置矩阵的阶数:";
	scanf_s("%d", &matrixSize);

	// -------------------------- 初始化矩阵数组(动态分配二维数组) -------------------------- //
	int** matrixArray = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		matrixArray[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	setMatrixArray(matrixArray, matrixSize);

	// ---------------------------------------- Test:求长度为3的矩阵 ---------------------------------------- //
	//multiplicineMatrixResult(matrixArray, matrixSize, 2);

	// ---------------------------------------- Test:求长度范围为0-3,点(1,4)的通路之和 ---------------------------------------- //
	std::cout << getCountPointRangeLength(matrixArray, matrixSize, 3, 1, 4) << std::endl;

	// ---------------------------------------- Test:求长度为3的通路(即某点的值) ---------------------------------------- //
	std::cout << getPointSetLength(matrixArray, matrixSize, 3, 1, 4) << std::endl;

	// ---------------------------------------- Test:求自定义的多个长度的通路或回路 ---------------------------------------- //
	int testLengthSize = 4;
	int testLength[4] = { 1,2,3,4 };
	int* acceptArray = (int*)malloc(testLengthSize * sizeof(int));	
	getArrayCustomMultiLength(matrixArray, matrixSize, testLength, testLengthSize, 1, 1, acceptArray);
	for (int i = 0; i < testLengthSize; i++)
	{
		std::cout << i << ":" << acceptArray[i] << std::endl;;
	}
	free(acceptArray);

	// ---------------------------------------- Test:求长度内所有通路或回路(包括或不包括回路) ---------------------------------------- //
	std::cout << "Access of Include Loop: " << getAllPointRangeLengthAccess_HaveLoop(matrixArray, matrixSize, 5) << std::endl;

	std::cout << "Access of Not Include Loop: " << getAllPointRangeLengthAccess_NotLoop(matrixArray, matrixSize, 5) << std::endl;
	
	std::cout << "All of Loop : " << getAllPointRangeLengthLoop(matrixArray, matrixSize, 5) << std::endl;

	// ---------------------------------------- Test:求某个矩阵的可达矩阵 ---------------------------------------- //
	std::cout << std::endl;
	int** testResultMatrix = (int**)malloc(matrixSize * sizeof(int*));
	for (int i = 0; i < matrixSize; i++)
	{
		testResultMatrix[i] = (int*)malloc(matrixSize * sizeof(int));
	}
	getReachableMatrix(matrixArray, matrixSize, testResultMatrix);
	for (int i = 0; i < matrixSize; i++)
	{
		for (int j = 0; j < matrixSize; j++)
		{
			std::cout << testResultMatrix[i][j] << " ";
		}
		printf("\n");
	}
	for (int i = 0; i < matrixSize; i++)
	{
		free(testResultMatrix[i]);
	}
	free(testResultMatrix);

	// ----------------------------- Free ----------------------------- //
	for (int i = 0; i < matrixSize; i++)
	{
		free(matrixArray[i]);
	}
	free(matrixArray);

	return 0;
}

Github

工程下载:
https://github.com/sks853/GraphicMatrix
工程配置:VS 2019 Pro

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值