原创声明:本文系作者原创,转载请写明出处。

一、前言

      前几天由于科研需要,一直在搞矩阵的稀疏表示的乘法,不过最近虽然把程序写出来了,还是无法处理大规模的矩阵(虽然已经是稀疏了)。原因可能是结果不够稀疏。或者相乘的矩阵本来也不稀疏。

     还是把实现的程序放在这里。以供以后研究使用。

二、程序实现功能
    首先封装稀疏矩阵为三元组形式。
    程序的主要功能有:
稀疏矩阵的转置
稀疏矩阵的乘法
稀疏矩阵的加法
以及相应的导入文本文件(矩阵)等。
三、代码展示
以下程序由eclipse下编写的java
  1. package others;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.File;
  5. import java.io.FileOutputStream;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.util.ArrayList;
  9. import java.util.HashMap;
  10. import java.util.Iterator;
  11. import java.util.Map;
  12. import java.util.Map.Entry;
  13.  
  14. import weka.clusterers.SimpleKMeans;
  15. import weka.core.DistanceFunction;
  16. import weka.core.Instances;
  17. import weka.core.converters.ArffLoader;
  18. import Jama.Matrix;
  19. /*
  20. * 本类可实现稀疏矩阵三元组表示下的矩阵乘法和矩阵加法,以及矩阵转置等。结果也是三元组存储。
  21. * 但是当数据量非常庞大时,乘积的结果无法存储,会出现内存溢出的现象。
  22. */
  23. public class SMatrix {
  24.  
  25. public Map<ArrayList<Integer>,Integer> Triples;//矩阵的三元组表示
  26. public int rowNum;//矩阵行数
  27. public int colNum;//矩阵列数
  28.  
  29. public int getRowNum() {
  30. return rowNum;
  31. }
  32.  
  33. public void setRowNum(int rowNum) {
  34. this.rowNum = rowNum;
  35. }
  36.  
  37. public int getColNum() {
  38. return colNum;
  39. }
  40.  
  41. public void setColNum(int colNum) {
  42. this.colNum = colNum;
  43. }
  44.  
  45. /*
  46. * 构造函数1
  47. */
  48. public SMatrix(){
  49.  
  50. }
  51.  
  52. /*
  53. * 构造函数2
  54. */
  55. public SMatrix(Map<ArrayList<Integer>, Integer> triples, int rowNum, int colNum) {
  56.  
  57. Triples = triples;
  58. this.rowNum = rowNum;
  59. this.colNum = colNum;
  60. }
  61.  
  62. /*
  63. * 构造函数3
  64. */
  65. public SMatrix(Map<ArrayList<Integer>, Integer> triples) {
  66.  
  67. Triples = triples;
  68. }
  69.  
  70. /*
  71. * 稀疏矩阵相乘函数
  72. */
  73. public SMatrix Multiply(SMatrix M,SMatrix N){
  74. if(M.colNum != N.rowNum){
  75. System.out.println("矩阵相乘不满足条件");
  76. return null;
  77. }
  78.  
  79. Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
  80. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it1 = M.Triples.entrySet().iterator();
  81.  
  82. int iter = 0;
  83. while(it1.hasNext()){
  84. iter++;
  85. // System.out.println("迭代次数:"+iter);
  86. Entry<ArrayList<Integer>, Integer> entry = it1.next();
  87. ArrayList<Integer> position = entry.getKey();
  88. // System.out.println("检查程序:" + position);
  89. int value = entry.getValue();
  90. int flag = 0;
  91. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it2 = N.Triples.entrySet().iterator();
  92. while(it2.hasNext()){
  93. Entry<ArrayList<Integer>,Integer> entry2 = it2.next();
  94. ArrayList<Integer> position2 = entry2.getKey();
  95. int value2 = entry2.getValue();
  96.  
  97. if(position.get(1) == position2.get(0)){
  98. flag = 1;
  99. ArrayList<Integer> temp = new ArrayList<Integer>();
  100. temp.add(position.get(0));
  101. temp.add(position2.get(1));
  102. int v = value * value2;
  103. if(triples.containsKey(temp)){
  104. triples.put(temp, triples.get(temp) + v);
  105. System.out.println(temp+ "\t"+(triples.get(temp) + v));
  106.  
  107. }
  108. else{
  109. triples.put(temp, v);
  110. System.out.println(temp + "\t" + v);
  111. }
  112. }
  113.  
  114. }
  115. }
  116. SMatrix s = new SMatrix(triples,M.rowNum,N.colNum);
  117. return s;
  118. }
  119.  
  120. /*
  121. * 稀疏矩阵相加函数
  122. */
  123. public static SMatrix Add(SMatrix M,SMatrix N){
  124. if(M.colNum != N.colNum || M.rowNum != N.rowNum){
  125. System.out.println("矩阵相加不满足条件");
  126. return null;
  127. }
  128. SMatrix s = new SMatrix();
  129. Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
  130. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it1 = M.Triples.entrySet().iterator();
  131. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it2 = N.Triples.entrySet().iterator();
  132.  
  133. while(it1.hasNext()){
  134. Entry<ArrayList<Integer>, Integer> entry = it1.next();
  135. ArrayList<Integer> position = entry.getKey();
  136. int value = entry.getValue();
  137. if(triples.containsKey(position)){
  138. triples.put(position, triples.get(position) + value);
  139. }else{
  140. triples.put(position, value);
  141. }
  142.  
  143. }
  144.  
  145. while(it2.hasNext()){
  146. Entry<ArrayList<Integer>,Integer> entry = it2.next();
  147. ArrayList<Integer> position = entry.getKey();
  148. int value = entry.getValue();
  149. if(triples.containsKey(position)){
  150. triples.put(position, triples.get(position) + value);
  151. }else{
  152. triples.put(position, value);
  153. }
  154.  
  155. }
  156. return s;
  157. }
  158.  
  159. /*
  160. * 稀疏矩阵求转置矩阵函数
  161. */
  162. public SMatrix Transposition(){
  163.  
  164. Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
  165. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it = this.Triples.entrySet().iterator();
  166. while(it.hasNext()){
  167. Entry<ArrayList<Integer>, Integer> entry = it.next();
  168. ArrayList<Integer> position = entry.getKey();
  169. int value = entry.getValue();
  170. ArrayList<Integer> transP = new ArrayList<Integer>();
  171. transP.add(position.get(1));
  172. transP.add(position.get(0));
  173.  
  174. triples.put(transP, value);
  175.  
  176. }
  177. SMatrix s = new SMatrix(triples,this.colNum,this.rowNum);
  178. return s;
  179. }
  180.  
  181. /*
  182. * 加载文本数据为稀疏矩阵三元组形式的函数
  183. */
  184. public SMatrix Load(String file, String delimeter){
  185.  
  186. Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
  187.  
  188. try{
  189. File f = new File(file);
  190. FileReader fr = new FileReader(f);
  191. BufferedReader br = new BufferedReader(fr);
  192.  
  193. String line;
  194.  
  195. while((line = br.readLine()) != null){
  196. String[] str = line.trim().split(delimeter);
  197.  
  198. ArrayList<Integer> s = new ArrayList<Integer>();
  199. for(int i = 0;i < str.length - 1; i++){
  200. s.add(Integer.parseInt(str[i]));
  201. }
  202.  
  203. triples.put(s, Integer.parseInt(str[str.length - 1]));
  204.  
  205. }
  206.  
  207. br.close();
  208. fr.close();
  209.  
  210. }catch(IOException e){
  211. e.printStackTrace();
  212. }
  213. SMatrix sm = new SMatrix(triples);
  214. return sm;
  215. }
  216. /*
  217. * 打印稀疏矩阵(三元组形式)
  218. */
  219. public void Print(){
  220. Map<ArrayList<Integer>, Integer> triples = this.Triples;
  221. Iterator<Map.Entry<ArrayList<Integer>, Integer>> it = triples.entrySet().iterator();
  222. int num = 0;
  223. while(it.hasNext()){
  224. Entry<ArrayList<Integer>, Integer> entry = it.next();
  225. ArrayList<Integer> position = entry.getKey();
  226. num++;
  227. System.out.print(num+":");
  228. for(Integer in:position){
  229. System.out.print(in + "\t");
  230. }
  231.  
  232. System.out.println(entry.getValue());
  233. }
  234.  
  235. }
  236.  
  237. public static void main(String[] args){
  238.  
  239. /*
  240. * 测试程序
  241.  
  242. String testS = "data/me";
  243. int k = 3;
  244. SMatrix te = new SMatrix();
  245. te = te.Load(testS,"\t");
  246. te.rowNum = 4;
  247. te.colNum = 6;
  248. System.out.println("打印原矩阵");
  249. te.Print();
  250. System.out.println("打印原矩阵的转置矩阵");
  251. te.Transposition().Print();
  252.  
  253. System.out.println("打印乘积矩阵");
  254. SMatrix A2 = new SMatrix();
  255.  
  256. A2 = te.Multiply(te, te.Transposition());
  257. A2.Print();
  258. */
  259.  
  260. long start = System.currentTimeMillis();
  261.  
  262. String file1 = "data/AT.txt";//author to term 的稀疏矩阵
  263. String file2 = "data/CA.txt";//conference to author 的稀疏矩阵
  264. String delimeter = " ";
  265. int k = 11;
  266. SMatrix M = new SMatrix();
  267. SMatrix MT = new SMatrix();
  268.  
  269. SMatrix N = new SMatrix();
  270. SMatrix NT = new SMatrix();
  271. SMatrix P = new SMatrix();
  272. SMatrix Q = new SMatrix();
  273.  
  274. M = M.Load(file1, delimeter);
  275. M.colNum = 9225;
  276. M.rowNum = 6456;
  277. System.out.println("打印矩阵M");
  278. M.Print();
  279. MT = M.Transposition();
  280. System.out.println("打印矩阵MT");
  281. MT.Print();
  282.  
  283. System.out.println("计算M和MT的乘积");
  284. System.out.println(M.rowNum);
  285. P = M.Multiply(M, MT);
  286. System.out.println("打印矩阵M与矩阵M转置的乘积");
  287. P.Print();
  288.  
  289. N = N.Load(file2, delimeter);
  290. N.colNum = 6456;
  291. N.rowNum = 20;
  292. System.out.println("打印矩阵N");
  293. N.Print();
  294. NT = N.Transposition();
  295.  
  296. System.out.println("打印矩阵NT:");
  297. NT.Print();
  298.  
  299. System.out.println("计算NT 和 N的乘积");
  300. System.out.println(NT.colNum);
  301. System.out.println(N.rowNum);
  302. Q = M.Multiply(NT, N);
  303. Q.Print();
  304.  
  305. SMatrix A = new SMatrix();
  306. A = A.Load("data/AA.txt"," ");
  307.  
  308. SMatrix A1 = new SMatrix();
  309. SMatrix A2 = new SMatrix();
  310. System.out.println("计算矩阵A1=P+Q:");
  311. A1 = SMatrix.Add(Q, P);
  312.  
  313. System.out.println("打印矩阵A1:");
  314. A1.Print();
  315. A2 = SMatrix.Add(A1, A);//得到了比较全面的author to author 矩阵三元组
  316.  
  317. A2.Print();
  318.  
  319. double[][] matrix = new double[A2.rowNum][A2.colNum];
  320.  
  321. for(int i = 0;i < A2.rowNum;i++){
  322. for (int j = 0; j < A2.colNum; j++) {
  323.  
  324. ArrayList<Integer> list = new ArrayList<Integer>();
  325. list.add(i);
  326. list.add(j);
  327.  
  328. if (A2.Triples.containsKey(list)) {
  329. matrix[i][j] = A2.Triples.get(list);
  330. }
  331. else{
  332. matrix[i][j] = 0;
  333. }
  334.  
  335. }
  336. }
  337.  
  338. for(int i = 0;i<A2.rowNum;i++){
  339. for(int j = 0;j < A2.colNum;j++){
  340. System.out.print(matrix[i][j]+"\t");
  341. }
  342. System.out.println();
  343. }
  344. Matrix Author = new Matrix(matrix);
  345.  
  346. //第二步:求矩阵的特征值eigValue及其相应的特征向量矩阵,取前K个(最大的)
  347. Matrix diagA = Author.eig().getD();
  348.  
  349. diagA.print(4, 2);
  350. int m = diagA.getRowDimension();
  351. int n = diagA.getColumnDimension();
  352.  
  353. Matrix eigVector = Author.eig().getV();
  354.  
  355. eigVector.print(eigVector.getRowDimension(),4);
  356.  
  357. //将特征向量输出到文本中。
  358. String outFile = "data/eigenVector.txt";
  359. try{
  360. File f = new File(outFile);
  361. FileOutputStream fout = new FileOutputStream(f);
  362.  
  363. fout.write("@RELATION\teigenVector\n".getBytes());
  364. for(int i = n-k;i<n;i++){
  365. fout.write(("@ATTRIBUTE\t"+i + "\tREAL\n").getBytes());
  366. }
  367. fout.write("@DATA\n".getBytes());
  368. if(k <= n){
  369. for(int i = 0;i < m;i++){
  370. for(int j = n-k;j<n;j++){
  371. Double temp = new Double(eigVector.getArray()[i][j]);
  372. String tem = temp.toString();
  373. fout.write((tem + "\t").getBytes());
  374.  
  375. }
  376. fout.write(("\n").getBytes());
  377. }
  378. }
  379. }
  380. catch(IOException e){
  381. e.printStackTrace();
  382. }
  383. //第三步:对特征向量矩阵进行kmeans聚类
  384. Instances ins = null;
  385.  
  386. SimpleKMeans KM = null;
  387.  
  388. // 目前没有使用到,但是在3.7.10的版本之中可以指定距离算法
  389. // 默认是欧几里得距离
  390. DistanceFunction disFun = null;
  391.  
  392. try {
  393. // 读入样本数据
  394. File file = new File("data/eigenVector.txt");
  395. ArffLoader loader = new ArffLoader();
  396. loader.setFile(file);
  397. ins = loader.getDataSet();
  398.  
  399. // 初始化聚类器 (加载算法)
  400. KM = new SimpleKMeans();
  401. KM.setNumClusters(2); //设置聚类要得到的类别数量
  402.  
  403. KM.setMaxIterations(100);
  404. KM.buildClusterer(ins); //开始进行聚类
  405. System.out.println(KM.preserveInstancesOrderTipText());
  406. // 打印聚类结果
  407. System.out.println(KM.toString());
  408.  
  409. // for(String option : KM.getOptions()) {
  410. // System.out.println(option);
  411. // }
  412. // System.out.println("CentroIds:" + tempIns);
  413. } catch(Exception e) {
  414. e.printStackTrace();
  415. }
  416.  
  417. System.out.println("程序正常结束");
  418.  
  419. long end = System.currentTimeMillis();
  420. System.out.println(end - start);
  421.  
  422. }
  423.  
  424. }

稀疏矩阵乘法加法等的java实现的更多相关文章

  1. poj 3735 Training little cats 矩阵快速幂+稀疏矩阵乘法优化

    题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮, ...

  2. 【老鸟学算法】大整数乘法——算法思想及java实现

    算法课有这么一节,专门介绍分治法的,上机实验课就是要代码实现大整数乘法.想当年比较混,没做出来,颇感遗憾,今天就把这债还了吧! 大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整型甚至长整型的最大 ...

  3. 九九乘法表的实现--JAVA基础

    JAVA算法实现:输出九九乘法表 Jiujiu.java: package com.qkys.www; public class Jiujiu { public static void main(St ...

  4. 稀疏矩阵的加法(用十字链表实现A=A+B)

    描写叙述: 输入两个稀疏矩阵A和B,用十字链表实现A=A+B,输出它们相加的结果. 输入: 第一行输入四个正整数,各自是两个矩阵的行m.列n.第一个矩阵的非零元素的个数t1和第二个矩阵的非零元素的个数 ...

  5. 稀疏矩阵乘法 · Sparse Matrix Multiplication

    [抄题]: 给定两个 稀疏矩阵 A 和 B,返回AB的结果.您可以假设A的列数等于B的行数. [暴力解法]: 时间分析: 空间分析: [思维问题]: [一句话思路]: 如果为零则不相乘,优化常数的复杂 ...

  6. 【[Offer收割]编程练习赛13 D】骑士游历(矩阵模板,乘法,加法,乘方)

    [题目链接]:http://hihocoder.com/problemset/problem/1504 [题意] [题解] 可以把二维的坐标转成成一维的; 即(x,y)->(x-1)*8+y 然 ...

  7. python 多线程稀疏矩阵乘法

    import threading, time import numpy as np res = [] class MyThread(threading.Thread): def __init__(se ...

  8. 【HDOJ】2424 Gary's Calculator

    大数乘法加法,直接java A了. import java.util.Scanner; import java.math.BigInteger; public class Main { public ...

  9. Java for LeetCode 043 Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

随机推荐

  1. C#本地时间和GMT(UTC)时间的转换

    /// <summary> /// 本地时间转成GMT时间 /// </summary> 4 public static string ToGMTString(DateTime ...

  2. SDC文件模版

    # 1. Define clock create_clock -name "clk_in" -period 20ns [get_ports {clk_in}] # 2. tco c ...

  3. golang的ssh例子

    package main import ( "github.com/dynport/gossh" "log" ) func MakeLogger(prefix ...

  4. iphone dev 入门实例5:Get the User Location & Address in iPhone App

    Create the Project and Design the Interface First, create a new Xcode project using the Single View ...

  5. MVC 模型

    dbcontent var ALLALBUMS=from album in db.albums orderby album.title ascending select album; storeman ...

  6. python 读取sqlite3 数据库

    import sqlite3 name = "tom" age = 30 con = sqlite3.connect("d:\\test.db") cur = ...

  7. 执行sh文件 进行MongoDB的业务逻辑导入

    将从HDFS中的数据转化为Json格式写入文件后,十个文件的文件名为 文件名_01 ...._02 ....03格式. 编写个简单的sh文件 通过for do循环让i+1 文件名对应上就可以的- -执 ...

  8. HUST 1010 The Minimum Length(KMP,最短循环节点,即i-Next[i])

    题意: 有一个字符串A,假设A是“abcdefg”,  由A可以重复组成无线长度的AAAAAAA,即“abcdefgabcdefgabcdefg.....”. 从其中截取一段“abcdefgabcde ...

  9. CF 15/09/23

    CF580A 给出一个数列,求最长不下降子序列(连续) 直接DP,O(n) CF580B 主人公有n个朋友,每一个朋友有2个属性:m,sat 现在他想邀请部分朋友,邀请的人满足MAX_M-MIN_M& ...

  10. [物理学与PDEs]书中出现的向量公式汇总

    P 11 1. $\rot (\phi{\bf A})=\n \phi\times{\bf A}+\phi\ \rot{\bf A}$. 2. $-\lap {\bf A}=\rot\rot {\bf ...