分治算法
来源:互联网 发布:diy婚庆域名 编辑:程序博客网 时间:2024/06/05 16:26
一、基本概念
将一个复杂的问题分解为多个相同或相似的子问题,通过递归的方式,将子问题继续分解,直到子问题容易解决。
二、特征
1.分治法所能解决的问题一般具有以下几个特征:
1. 该问题的规模缩小到一定的程度就可以容易地解决2. 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。3. 利用该问题分解出的子问题的解可以合并为该问题的解;4. 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
2.特征解释
1. 第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;2. 第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归;3. 第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法;4. 第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
三、使用场景
问题规模线性增长,带动的计算量为非线性增长,且满足分治算法的三个特征(2、3、4),则可使用分支算法。
四、矩阵乘法
1.矩阵乘法公式
2. 是否符合分治算法
1.条件(1)显然满足2.条件(2)(3)满足,证明如下:
3. 使用分治算法的思想
将N
4. C# 代码实现
/// <summary>/// 直接求两个矩阵的乘积/// C[i,j] = Sum(A[i,k] * B[k,j]) (k = 1~n)/// </summary>/// <param name="p"></param>/// <param name="q"></param>/// <returns></returns>int[,] DirectMultiplication(int[,] p,int[,] q){ /// p的列数 == q的行数 才能相乘 if (p.GetLength(1) != q.GetLength(0)) { return null; } int[,] result = new int[p.GetLength(0),q.GetLength(1)]; for (int i = 0; i < p.GetLength(0); i++) { for (int j = 0; j < q.GetLength(1); j++) { result[i,j] = 0; for (int k = 0; k < p.GetLength(1); k++) { result[i,j] += p[i,k] * q[k,j]; } } } return result;}/// <summary>/// 递归计算矩阵相乘/// </summary>/// <param name="p"></param>/// <param name="q"></param>/// <param name="n"></param>/// <returns></returns>int[,] DivideAndConquer(int[,] p, int[,] q, int n){ if (!IsPowerValueOfTwo(n)) { return DirectMultiplication(p, q); } else { if (n == 2) { return DirectMultiplication(p, q); } if (n > 2) { int[,] result = new int[n,n]; int[][,] pMatrix = PartitionMatrix(p, n); int[][,] qMatrix = PartitionMatrix(q, n); int[][,] rMatrix = PartitionMatrix(result, n); /// 核心 /// A[0] * B[0] + A[1] * B[2] /// A[0] * B[1] + A[1] * B[3] /// A[2] * B[0] + A[3] * B[2] /// A[2] * B[1] + A[3] * B[3] for (int i = 0; i < rMatrix.GetLength(0); i++) { int row = 2 * (i / 2); int col = i % 2; rMatrix[i] = AddMatrix(DivideAndConquer(pMatrix[row], qMatrix[col], n / 2), DivideAndConquer(pMatrix[row + 1], qMatrix[col + 2], n / 2), n / 2); } /// 合并矩阵 result = MergeMatrix(rMatrix, n / 2); return result; } else { return null; } }}/// <summary>/// 是否为2的幂次方/// </summary>/// <param name="n"></param>/// <returns></returns>bool IsPowerValueOfTwo(int n){ while (true) { if (n == 1) return true; if (n % 2 == 1) return false; else n = n / 2; }}/// <summary>/// 矩阵加法/// </summary>/// <param name="p"></param>/// <param name="q"></param>/// <param name="n"></param>/// <returns></returns>int[,] AddMatrix(int[,] p, int[,] q, int n){ int[,] result = new int[n,n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { result[i,j] = p[i,j] + q[i,j]; } } return result;}/// <summary>/// 分解矩阵/// </summary>/// <param name="matrix"></param>/// <param name="n"></param>/// <returns></returns>int[][,] PartitionMatrix(int[,] matrix,int n){ int newLen = n/2; /// 初始化数组 int[][,] pMatrix = new int[4][,]; for (int i = 0; i < 4; i++) { pMatrix[i] = new int[newLen, newLen]; } for (int k = 0; k < 4; k++) { int startRow = (k / 2) * newLen; int startCol = (k % 2) * newLen; for (int i = 0; i < newLen; i++) { for (int j = 0; j < newLen; j++) { pMatrix[k][i,j] = matrix[i + startRow,j + startCol]; } } } return pMatrix;}/// <summary>/// 合并矩阵/// </summary>/// <param name="rMatrix"></param>/// <param name="n"></param>/// <returns></returns>int[,] MergeMatrix(int[][,] rMatrix,int n){ int[,] matrix = new int[2 * n,2 * n]; for (int k = 0; k < rMatrix.GetLength(0); k++) { int startRow = (k / 2) * n; int startCol = (k % 2) * n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { matrix[i + startRow,j + startCol] = rMatrix[k][i,j]; } } } return matrix;}
阅读全文
0 0
- 分治算法
- 分治算法
- 分治算法?
- 【算法】分治
- 【算法】分治
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- 分治算法
- Mac 安装mysql问题
- CSS块级元素和行内元素
- MySQL-查询MySQL最后几条数据-不依赖其它字段
- Centos7搭建git服务器和gitblit管理工具
- PHP+TP框架实现使用微信图像接口
- 分治算法
- Mac 里自带的邮件客户端如何备份和恢复邮件
- discuz为何添加新分区,在前台却不显示?
- android选择本地相册或拍照更换软件背景图片
- JAVA-super关键字
- 《Effective C++》第四章:设计与声明
- jvm
- Spring中bean的作用域及Spring容器初始化的相关问题
- upstream sent too big header while reading response header from upstream