第十章分治算法(矩阵相乘)

矩阵乘法问题:strassen算法
Strassen算法的基本思想是把每一个矩阵都分为4块
在这里插入图片描述

在求C = AB,设7个矩阵变量。
M1 = (A12-A22)(B21+B22)
M2 = (A11+A22)(B11+B22)
M3 = (A11-A21)(B11+B12)
M4 = (A11+A12)B22
M5 = A11(B12-B11)
M6 = A22(B21-B11)
M7 = (A21+A22)B11。
则 C可以通过这7个变量算出。
C11 = M1+M2-M4+M6。
C12 = M4+N5。
C21 = M6+M7。
C22 = M2-M3+M5-M7。
就可以求出C。

主函数

int main() {
	int **A, **B, **C;
	int n;
	cout<<"请输入矩阵的规模,将自动产生矩阵:";
	cin >> n;
	A = initMatrix(n);			//初始化A,申请空间
	randomMatrix(A, n);			//A矩阵内容随机产生
	B = initMatrix(n);
	randomMatrix(B, n);
	C = initMatrix(n);			//矩阵C申请空间
	printfMatrix(A, n);			//打印输出矩阵
	printfMatrix(B, n);
	StrassenMatrix(A, B,C, n);	//求C,C=AB,n为矩阵的规模
	printfMatrix(C, n);			//打印C
	return 0;
}

功能函数

int** initMatrix(int n) {
	int **Matrix = new int *[n];
	for (int i = 0; i < n; i++) {
		Matrix[i] = new int[n];
	}
	return Matrix;
}
void randomMatrix(int** Matrix,int n) {
	srand(time(NULL));
	Sleep(1000);
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			Matrix[i][j] = rand() % 10;
		}
	}
}
void printfMatrix(int** Matrix,int n) {
	for (int i = 0; i < n;i++) {
		for (int j = 0; j < n; j++) {
			cout << Matrix[i][j] << " ";
		}
		cout << endl;
	}
}
//求两个矩阵相加结果
void AddMatrix(int** m1, int** m2, int** result, int n) {
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			result[i][j] = m1[i][j] + m2[i][j];
		}
	}
}
//求两个矩阵相减结果
void SubMatrix(int** m1, int** m2, int ** result, int n) {
	//矩阵m1-m2
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			result[i][j] = m1[i][j] - m2[i][j];
		}
	}
}

Strassen算法

void StrassenMatrix(int** A,int** B,int** C,int n) {
	//C=AB; n为矩阵的规模
	if (n==1) {
		C[0][0] = A[0][0] * B[0][0];
	}
	else {
		int m = n / 2;				//缩小问题规模
		//将ABC矩阵分块
		int **A_11 = new int *[m];
		int **A_12 = new int *[m];
		int **A_21 = new int *[m];
		int **A_22 = new int *[m];
		int **B_11 = new int *[m];
		int **B_12 = new int *[m];
		int **B_21 = new int *[m];
		int **B_22 = new int *[m];
		int **C_11 = new int *[m];
		int **C_12 = new int *[m];
		int **C_21 = new int *[m];
		int **C_22 = new int *[m];
		//定义7个变量
		int **M1 = new int *[m];
		int **M2 = new int *[m];
		int **M3 = new int *[m];
		int **M4 = new int *[m];
		int **M5 = new int *[m];
		int **M6 = new int *[m];
		int **M7 = new int *[m];
		int **t1 = new int *[m];
		int **t2 = new int *[m];
		//分配存储空间
		for (int i = 0; i < m; i++)
		{
			A_11[i] = new int[m];
			A_12[i] = new int[m];
			A_21[i] = new int[m];
			A_22[i] = new int[m];
			B_11[i] = new int[m];
			B_12[i] = new int[m];
			B_21[i] = new int[m];
			B_22[i] = new int[m];
			C_11[i] = new int[m];
			C_12[i] = new int[m];
			C_21[i] = new int[m];
			C_22[i] = new int[m];
			M1[i] = new int[m];
			M2[i] = new int[m];
			M3[i] = new int[m];
			M4[i] = new int[m];
			M5[i] = new int[m];
			M6[i] = new int[m];
			M7[i] = new int[m];
			t1[i] = new int[m];
			t2[i] = new int[m];
		}
		//将A,B分块
		for (int i = 0; i < m; i++)
		{
			for (int j = 0; j < m; j++)
			{
				A_11[i][j] = A[i][j];
				A_12[i][j] = A[i][j + m];
				A_21[i][j] = A[i + m][j];
				A_22[i][j] = A[i + m][j + m];
				B_11[i][j] = B[i][j];
				B_12[i][j] = B[i][j + m];
				B_21[i][j] = B[i + m][j];
				B_22[i][j] = B[i + m][j + m];
			}
		}
		//M1 = (A12 - A22)(B21 + B22)
		SubMatrix(A_12, A_22, t1, m);
		AddMatrix(B_21, B_22, t2, m);
		StrassenMatrix(t1, t2, M1, m);
		//M2 = (A11 + A22)(B11 + B22)
		AddMatrix(A_11, A_22, t1, m);
		AddMatrix(B_11, B_22, t2, m);
		StrassenMatrix(t1, t2, M2, m);
		//M3 = (A11 - A21)(B11 + B12)
		SubMatrix(A_11, A_21, t1, m);
		AddMatrix(B_11, B_12, t2, m);
		StrassenMatrix(t1, t2, M3, m);
		//M4 = (A11 + A12)B22
		AddMatrix(A_11, A_12, t1, m);
		StrassenMatrix(t1, B_22, M4, m);
		//M5 = A11(B12 - B22)
		SubMatrix(B_12, B_22, t1, m);
		StrassenMatrix(t1, A_11, M5, m);
		//M6 = A22(B21 - B11),
		SubMatrix(B_21, B_11, t1, m);
		StrassenMatrix(A_22, t1, M6, m);
		//M7 = (A21 + A22)B11。
		AddMatrix(A_21, A_22, t1, m);
		StrassenMatrix(t1, B_11, M7, m);
		//根据M1到M7,求C_11,C_12,C_21,C_22
		//C11 = M1 + M2 - M4 + M6。
		AddMatrix(M1, M2, t1, m);
		AddMatrix(t1, M6, t2, m);
		SubMatrix(t2, M4, C_11, m);
		//C12 = M4 + M5。
		AddMatrix(M4, M5, C_12, m);
		//C21 = M6 + M7。
		AddMatrix(M6, M7, C_21, m);
		//C22 = M2 - M3 + M5 - M7。
		SubMatrix(M2, M3, t1, m);
		SubMatrix(M5, M7, t2, m);
		AddMatrix(t1, t2, C_22, m);
		//求出C11,C12,C21,C22后拼接回C;
		for (int i = 0; i < m;i++) {
			for (int j = 0; j < m;j++) {
				C[i][j] = C_11[i][j];
				C[i][j + m] = C_12[i][j];
				C[i + m][j] = C_21[i][j];
				C[i + m][j + m] = C_22[i][j];
			}
		}
		//释放所有申请的空间
		for (int i = 0; i < m; i++)
		{
			delete[] A_11[i];
			delete[] A_12[i];
			delete[] A_21[i];
			delete[] A_22[i];
			delete[] B_11[i];
			delete[] B_12[i];
			delete[] B_21[i];
			delete[] B_22[i];
			delete[] C_11[i];
			delete[] C_12[i];
			delete[] C_21[i];
			delete[] C_22[i];
			delete[] M1[i];
			delete[] M2[i];
			delete[] M3[i];
			delete[] M4[i];
			delete[] M5[i];
			delete[] M6[i];
			delete[] M7[i];
			delete[] t1[i];
			delete[] t2[i];
		}
		delete[] A_11;
		delete[] A_12;
		delete[] A_21;
		delete[] A_22;
		delete[] B_11;
		delete[] B_12;
		delete[] B_21;
		delete[] B_22;
		delete[] C_11;
		delete[] C_12;
		delete[] C_21;
		delete[] C_22;
		delete[] M1;
		delete[] M2;
		delete[] M3;
		delete[] M4;
		delete[] M5;
		delete[] M6;
		delete[] M7;
		delete[] t1;
		delete[] t2;
	}	
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<h3>回答1:</h3><br/>以下是使用Python编写的K-means算法数据挖掘第十章习题的代码: ``` import numpy as np from matplotlib import pyplot as plt from sklearn.cluster import KMeans %matplotlib inline # 生成随机数据 num_points = 200 num_clusters = 4 x, y = [], [] for i in range(num_points): if np.random.random() > 0.5: x.append(np.random.normal(0.0, 0.9)) y.append(np.random.normal(0.0, 0.9)) else: x.append(np.random.normal(3.0, 0.5)) y.append(np.random.normal(1.0, 0.5)) data = np.column_stack((x, y)) # 执行k-means算法 kmeans = KMeans(n_clusters=num_clusters, init='k-means++', max_iter=100, n_init=1, verbose=0) kmeans.fit(data) # 绘制聚类结果 colors = ['b', 'g', 'r', 'c', 'm', 'y', 'k'] for i in range(num_points): plt.scatter(data[i, 0], data[i, 1], s=30, color=colors[kmeans.labels_[i]]) plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], marker='x', s=200, linewidths=3, color='k') plt.show() ``` 该代码用于生成随机数据,并执行K-means算法进行聚类。最终绘制聚类结果,并以黑色十字形显示聚类中心点。可以通过修改随机数据的生成方式、聚类数目、算法参数等,来测试不同的聚类效果。 <h3>回答2:</h3><br/>K-means算法是一种常用的基于聚类的数据挖掘算法,可以对无标签数据进行聚类分析,本章中介绍了K-means算法的原理及其python代码实现。代码如下: ``` python import numpy as np import pandas as pd import matplotlib.pyplot as plt # 生成数据集 def create_datset(k, n): data = [] for i in range(k): init_center = np.random.randint(0, 30, size=2) x = np.random.normal(init_center[0], 1, size=(n, 2)) data.append(x) return np.vstack(data) # 计算欧氏距离 def distance(x, center): diffs = x - center return np.sqrt(np.sum(diffs ** 2, axis=1)) # k-means算法 def k_means(data, k, max_iter=100): # 随机初始化k个中心点 centers = data[np.random.choice(data.shape[0], k, replace=False)] for i in range(max_iter): # 计算每个样本距离最近的中心点 labels = np.argmin([distance(data, center) for center in centers], axis=0) # 更新中心点位置 new_centers = [data[labels == j].mean(axis=0) for j in range(k)] # 判断聚类是否已经收敛,如果已经收敛则退出循环 if np.all(centers == new_centers): break centers = new_centers return centers, labels # 显示聚类结果 def plot_clusters(data, labels, centers): plt.scatter(data[:, 0], data[:, 1], c=labels, s=50, alpha=0.5) plt.scatter(centers[:, 0], centers[:, 1], marker='*', c='r', s=100, alpha=0.5) plt.show() if __name__ == '__main__': data = create_datset(k=3, n=100) centers, labels = k_means(data, k=3) plot_clusters(data, labels, centers) ``` 代码中首先生成了一个带有3个簇的数据集,然后通过k_means()函数实现了K-means算法的聚类过程,最后使用plot_clusters()函数将聚类结果可视化展示了出来。 K-means算法的python实现代码较为简单,但需要注意一些细节问题。例如,在实现距离计算时,我们可以使用numpy中的sum()函数,但此时需要指定axis参数,否则无法正确计算每个样本距离每个中心点的距离;在更新中心点位置时,需要注意对样本进行筛选以避免无效计算;同时,在K-means算法的循环过程中,需要判断聚类是否已经收敛,并根据需要设置收敛的迭代次数。 <h3>回答3:</h3><br/>k-means算法是一种常用的聚类算法,在数据挖掘中得到广泛应用。它的原理简单,是一种迭代算法,不断将数据点分配到离它最近的中心点所在的簇,然后重新计算每个簇的中心点,直到满足停止条件为止。以下是k-means算法的python代码。 首先,需要导入必要的库和数据集。常用的数据集有iris、wine、digits等。在这里以iris数据集为例。代码如下: ```python from sklearn.datasets import load_iris from sklearn.cluster import KMeans iris = load_iris() X = iris.data ``` 确定簇的个数k,本例中将k设为3。 ```python k = 3 ``` 实例化k-means算法模型,并设置参数。n_clusters为簇的个数,init表示初始化的方法,k-means++为默认值,max_iter表示最大的迭代次数,n_init为选取不同的初始化方式运行k-means算法的次数,verbose表示是否输出冗长的进度信息。 ```python kmeans = KMeans(n_clusters=k, init='k-means++', max_iter=100, n_init=10, verbose=0) ``` 训练模型并进行预测。 ```python pred = kmeans.fit_predict(X) ``` 最后,可视化聚类结果。 ```python import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D # 以三个特征为坐标轴画图 fig = plt.figure(1, figsize=(8, 6)) ax = Axes3D(fig, elev=-150, azim=110) ax.scatter(X[:, 0], X[:, 1], X[:, 2], c=pred, cmap=plt.cm.Set1, edgecolor='k', s=40) ax.set_title("iris 3D clustering") ax.set_xlabel("feature 1") ax.w_xaxis.set_ticklabels([]) ax.set_ylabel("feature 2") ax.w_yaxis.set_ticklabels([]) ax.set_zlabel("feature 3") ax.w_zaxis.set_ticklabels([]) plt.show() ``` 以上是k-means算法的python代码,在实际应用中,可以根据数据集的特点选择合适的簇数和参数,得到更好的聚类效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值