【算法导论】--分治策略Strassen算法(运用下标运算)【c++】
由于偷懒不想用泛型,所以直接用了整型来写了一份
①首先你得有一个矩阵的class Matrix
②Matrix为了方便用下标进行运算,
Matrix的结构如图:(我知道我的字丑。。。)
Matrix.h代码如下:(个人并不喜欢把代码全写在一块,对于阅读者是相当巨大的负担,其实自己受不了(逃))
#pragma once
#include<vector>
using namespace std;
class Matrix
{
public:
vector<vector<int>> nums;
int x0, y0; int size;
Matrix();
~Matrix();
Matrix(int size, int x0, int y0);
Matrix(Matrix input, int x0, int y0, int size);
Matrix(vector<vector<int>>input);
void Display();
static void MatrixMultiInit(Matrix &A, Matrix &B);
static Matrix MatrixMulti(Matrix A, Matrix B);
static Matrix MatrixAdd(Matrix A, Matrix B);
static Matrix MatrixSub(Matrix A, Matrix B);
};
Matrix.cpp对类的实现
一,构造,析构函数
Matrix::Matrix()
{
} Matrix::~Matrix()
{
} Matrix::Matrix(int size, int x0, int y0)
{
vector<vector<int>> temp(size, *new vector<int>(size));
for (int i = ; i < size; i++)
for (int j = ; j < size; j++)
temp[i][j] = ;
this->nums = temp;
this->x0 = x0;
this->y0 = y0;
this->size = size; } Matrix::Matrix(Matrix input, int x0, int y0, int size)
{
this->nums = input.nums;
this->x0 = x0;
this->y0 = y0;
this->size = size;
} Matrix::Matrix(vector<vector<int>> input)
{
this->nums = input;
this->x0 = ;
this->y0 = ;
this->size = input.size();
}
二,A+B,A-B实现
Matrix Matrix::MatrixAdd(Matrix A, Matrix B)
{
Matrix result(A.size, , );
for (int i = ; i < result.nums.size(); i++)
for (int j = ; j < result.nums.size(); j++)
result.nums[i][j] = A.nums[A.x0 + i][A.y0 + j] + B.nums[B.x0 + i][B.y0 + j];
return result;
} Matrix Matrix::MatrixSub(Matrix A, Matrix B)
{ Matrix result(A.size, , );
for (int i = ; i < result.nums.size(); i++)
for (int j = ; j < result.nums.size(); j++)
result.nums[i][j] = A.nums[A.x0 + i][A.y0 + j] - B.nums[B.x0 + i][B.y0 + j];
return result;
}
三,A*B的实现
Matrix Matrix::MatrixMulti(Matrix A, Matrix B)
{
int n = A.size;
int halfsize =n / ;
Matrix result(n, , );
if (n == )
result.nums[][] = A.nums[A.x0][A.y0] * B.nums[B.x0][B.y0];
else
{
Matrix tempS[];
for (int i = ; i < ; i++)
{
tempS[i] = *new Matrix(halfsize, , );
} //00-- A.x0,A.y0,halfsize
//01-- A.x0,A.y0+halfsize,halfsize
//10-- A.x0+halfsize,A.y0,halfsize
//11-- A.x0+halfsize,A.y0+halfsize,halfsize //00-- B.x0,B.y0,halfsize
//01-- B.x0,B.y0+halfsize,halfsize
//10-- B.x0+halfsize,B.y0,halfsize
//11-- B.x0+halfsize,B.y0+halfsize,halfsize
tempS[] = tempS[].MatrixSub(*new Matrix(B, B.x0, B.y0 + halfsize, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//01-11 B
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0, A.y0 + halfsize, halfsize));//00+01 A
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0 + halfsize, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//10+11 A
tempS[] = tempS[].MatrixSub(*new Matrix(B, B.x0 + halfsize, B.y0, halfsize), *new Matrix(B, B.x0, B.y0, halfsize));//10-00 B
tempS[] = tempS[].MatrixAdd(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//00+11 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0, B.y0, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//00+11 B
tempS[] = tempS[].MatrixSub(*new Matrix(A, A.x0, A.y0 + halfsize, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize));//01-11 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0 + halfsize, B.y0, halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));//10+11 B
tempS[] = tempS[].MatrixSub(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(A, A.x0 + halfsize, A.y0, halfsize));//00-10 A
tempS[] = tempS[].MatrixAdd(*new Matrix(B, B.x0, B.y0, halfsize), *new Matrix(B, B.x0, B.y0 + halfsize, halfsize));//00+01 B Matrix tempP[];
for (int i = ; i < ; i++)
{
tempP[i] = *new Matrix(n / , , );
}
tempP[] = tempP[].MatrixMulti(*new Matrix(A, A.x0, A.y0, halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , ,halfsize), *new Matrix(B, B.x0 + halfsize, B.y0 + halfsize, halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(B, B.x0, B.y0, halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(A, A.x0 + halfsize, A.y0 + halfsize, halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize));
tempP[] = tempP[].MatrixMulti(*new Matrix(tempS[], , , halfsize), *new Matrix(tempS[], , , halfsize)); Matrix result00 = result00.MatrixAdd(tempP[], tempP[]);
result00 = result00.MatrixSub(result00, tempP[]);
result00 = result00.MatrixAdd(result00, tempP[]);
Matrix result01 = result01.MatrixAdd(tempP[], tempP[]);
Matrix result10 = result10.MatrixAdd(tempP[], tempP[]);
Matrix result11 = result11.MatrixAdd(tempP[], tempP[]);
result11 = result11.MatrixSub(result11, tempP[]);
result11 = result11.MatrixSub(result11, tempP[]); if (n == ) {
for(int i=;i<n/+;i++)
for (int j = ; j < n / + ; j++) { result.nums[i][j]= result00.nums[i][j];
result.nums[i][j+n/+] = result01.nums[i][j];
result.nums[i+n/+][j] = result10.nums[i][j];
result.nums[i+n/+][j+n/+] = result11.nums[i][j];
}
} for(int i=;i<n/;i++)
for (int j = ; j < n / ; j++) { result.nums[i][j]= result00.nums[i][j];
result.nums[i][j+n/] = result01.nums[i][j];
result.nums[i+n/][j] = result10.nums[i][j];
result.nums[i+n/][j+n/] = result11.nums[i][j];
} }
return result;
}
四,防止size%2!=0的处理函数(即矩阵的行列数为奇数)
void Matrix::MatrixMultiInit(Matrix &A, Matrix &B) { if (A.nums.size() % != )
{
for (int i = ; i < A.nums.size(); i++)
A.nums[i].push_back();
for (int i = ; i < B.nums.size(); i++)
B.nums[i].push_back();
A.nums.push_back(*new vector<int>(A.nums[].size(), ));
B.nums.push_back(*new vector<int>(B.nums[].size(), ));
A.size++;
B.size++;
}
}
五,输出函数(这个读者随意)
void Matrix::Display()
{
for (int i = ; i < this->nums.size(); i++) { cout << "||";
for (int j = ; j < this->nums[i].size(); j++) {
cout << this->nums[i][j] << " ";
}
cout << "||" << endl; }
}
六,测试函数
#include <iostream>
#include"Matrix.h"
int main()
{
vector<vector<int>> input = {
{,,},
{,,},
{,,},
};
Matrix test0 (input);
Matrix test1 (input);
Matrix test2;
test2.MatrixMultiInit(test0, test1);
test2= test2.MatrixMulti(test0, test1);
test2.Display(); }
本人比较愚笨,耗时一天半才完成,不知道是不是天气热的原因,人太燥了,沉不下心来思考bug。
A*B有一点需要注意的是分块的逻辑应该怎么表示,一开始我用了两个顶点来表示一个矩阵的分块,如图:
然后halfsize还得一个一个的算,然后自己敲错的几率还会加大,并且还不一定表示正确每个分块,然后就逼疯自己了。
感觉这两天被这一堆bug都弄自闭了。。。。
幸好还是撑过来了,这算是我啃算法导论的第一个坎吧。
幸好第二天在csdn里面看到了别人怎么分块的。看到了一个变量halfsize,于是才开始改自己Matrix的构造。
虽然一开始不愿意,但是改完之后,竟然一次过了!woc!
给我了一个教训,以后能“少”一个变量尽量“少”一个变量。
【算法导论】--分治策略Strassen算法(运用下标运算)【c++】的更多相关文章
- 算法导论-矩阵乘法-strassen算法
目录 1.矩阵相乘的朴素算法 2.矩阵相乘的strassen算法 3.完整测试代码c++ 4.性能分析 5.参考资料 内容 1.矩阵相乘的朴素算法 T(n) = Θ(n3) 朴素矩阵相乘算法,思想明了 ...
- 基于visual Studio2013解决算法导论之008快速排序算法
题目 快速排序 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <malloc.h> #in ...
- 《算法导论》——MaximumSubArray
今天我们讨论的算法是最大子数组问题. 首先我定义了一个类用来保存最大子数组的开始位置索引.结束位置索引和该数组的和.代码如下: class MaximumSubArray { private: int ...
- "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)
本文兼参考自<算法导论>及<算法>. 以前一直不能够理解深度优先搜索和广度优先搜索,总是很怕去碰它们,但经过阅读上边提到的两本书,豁然开朗,马上就能理解得更进一步. 下文将会用 ...
- 《算法导论》——MergeSort
前言: 在今后的日子里,我将持续更新博客,讨论<算法导论>一书中的提到的各算法的C++实现.初来乍到,请多指教. 今日主题: 今天讨论<算法导论>第二章算法基础中的归并排序算法 ...
- 第四章 分治策略 4.2 矩阵乘法的Strassen算法
package chap04_Divide_And_Conquer; import static org.junit.Assert.*; import java.util.Arrays; import ...
- 【技术文档】《算法设计与分析导论》R.C.T.Lee等·第4章 分治策略
分治策略有一种“大事化小,小事化了”的境界,它的思想是将原问题分解成两个子问题,两个子问题的性质和原问题相同,因此这两个子问题可以再用分治策略求解,最终将两个子问题的解合并成原问题的解.有时,我们会有 ...
- 【从零学习经典算法系列】分治策略实例——高速排序(QuickSort)
在前面的博文(http://blog.csdn.net/jasonding1354/article/details/37736555)中介绍了作为分治策略的经典实例,即归并排序.并给出了递归形式和循环 ...
- 【算法导论C++代码】Strassen算法
简单方阵矩乘法 SQUARE-MATRIX-MULTIPLY(A,B) n = A.rows let C be a new n*n natrix to n to n cij = to n cij=ci ...
随机推荐
- - The superclass "javax.servlet.http.HttpServlet" was not found on the Java
网上有很多解决方法,如这种 下面是具体的解决方法:1.右击web工程->属性或Build Path->Java Build Path->Libraries-> Add Libr ...
- python numpy的基本操作
站长资讯平台:文章目录0.NumPy 与 ndarry1.数组属性查看:类型.尺寸.形状.维度2.numpy元素中数据存储方式,数据类型,类型转换2.1 查看元素数据存储类型2.2 元素数据存储类型转 ...
- React中生命周期
1.过时的生命周期(v16.3之前) 1.当前组件初次渲染: 绿色表示执行顺序. constructor(): 如果不需要初始化,可以直接省略,会自动补全该函数. 可以在这个方法中初始化this.st ...
- Oracle 后台进程(六)PMON进程
一.PMON简介 二.PMON的工作内容如下: 1.监控后台进程运行状况 2.如果某些进程异常中断,PMON去释放会话资源以及占用的锁LOCK 3.更新事务表的标志以及清除事务XID的标记 4.清除异 ...
- Oracle shell监控小脚本
cat dba_cpu_monitor.sh ##CPU Monitorh=`hostname`cpu_used=`top -b -d 1 -n 2 | grep Cpu | awk 'NR> ...
- 053_修改 Linux 系统的最大打开文件数量
#!/bin/bash#往/etc/security/limits.conf 文件的末尾追加两行配置参数,修改最大打开文件数量为 65536 cat >> /etc/security/li ...
- [Luogu] 矩阵加速(数列)
题面:https://www.luogu.org/problemnew/show/P1939 题解:https://www.zybuluo.com/wsndy-xx/note/1153810
- Process 'xx' Is Running
最近在试着使用idea,工具快捷键和设置都不太熟,今天遇到进程占用问题,感觉有必要总结一下,避免下次遇到同样问题. 常用快捷键: ctrl+n 搜索 ctrl+Shift+n 全部搜索 Ctrl+Al ...
- Servlet中接收和返回数据
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest re ...
- django中安装pillow ValueError: zlib is required unless explicitly disabled using --disable-zlib, aborting
在windows系统上,使用 pip install pillow安装pillow时 报错 在使用 easy_install Pillow 方式安装成功,默认是最高版本 如果需要在安装时,指定安装版 ...