稀疏矩阵乘法加法等的java实现
原创声明:本文系作者原创,转载请写明出处。
一、前言
package others; import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry; import weka.clusterers.SimpleKMeans;
import weka.core.DistanceFunction;
import weka.core.Instances;
import weka.core.converters.ArffLoader;
import Jama.Matrix;
/*
* 本类可实现稀疏矩阵三元组表示下的矩阵乘法和矩阵加法,以及矩阵转置等。结果也是三元组存储。
* 但是当数据量非常庞大时,乘积的结果无法存储,会出现内存溢出的现象。
*/
public class SMatrix { public Map<ArrayList<Integer>,Integer> Triples;//矩阵的三元组表示
public int rowNum;//矩阵行数
public int colNum;//矩阵列数 public int getRowNum() {
return rowNum;
} public void setRowNum(int rowNum) {
this.rowNum = rowNum;
} public int getColNum() {
return colNum;
} public void setColNum(int colNum) {
this.colNum = colNum;
} /*
* 构造函数1
*/
public SMatrix(){ } /*
* 构造函数2
*/
public SMatrix(Map<ArrayList<Integer>, Integer> triples, int rowNum, int colNum) { Triples = triples;
this.rowNum = rowNum;
this.colNum = colNum;
} /*
* 构造函数3
*/
public SMatrix(Map<ArrayList<Integer>, Integer> triples) { Triples = triples;
} /*
* 稀疏矩阵相乘函数
*/
public SMatrix Multiply(SMatrix M,SMatrix N){
if(M.colNum != N.rowNum){
System.out.println("矩阵相乘不满足条件");
return null;
} Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it1 = M.Triples.entrySet().iterator(); int iter = 0;
while(it1.hasNext()){
iter++;
// System.out.println("迭代次数:"+iter);
Entry<ArrayList<Integer>, Integer> entry = it1.next();
ArrayList<Integer> position = entry.getKey();
// System.out.println("检查程序:" + position);
int value = entry.getValue();
int flag = 0;
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it2 = N.Triples.entrySet().iterator();
while(it2.hasNext()){
Entry<ArrayList<Integer>,Integer> entry2 = it2.next();
ArrayList<Integer> position2 = entry2.getKey();
int value2 = entry2.getValue(); if(position.get(1) == position2.get(0)){
flag = 1;
ArrayList<Integer> temp = new ArrayList<Integer>();
temp.add(position.get(0));
temp.add(position2.get(1));
int v = value * value2;
if(triples.containsKey(temp)){
triples.put(temp, triples.get(temp) + v);
System.out.println(temp+ "\t"+(triples.get(temp) + v)); }
else{
triples.put(temp, v);
System.out.println(temp + "\t" + v);
}
} }
}
SMatrix s = new SMatrix(triples,M.rowNum,N.colNum);
return s;
} /*
* 稀疏矩阵相加函数
*/
public static SMatrix Add(SMatrix M,SMatrix N){
if(M.colNum != N.colNum || M.rowNum != N.rowNum){
System.out.println("矩阵相加不满足条件");
return null;
}
SMatrix s = new SMatrix();
Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it1 = M.Triples.entrySet().iterator();
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it2 = N.Triples.entrySet().iterator(); while(it1.hasNext()){
Entry<ArrayList<Integer>, Integer> entry = it1.next();
ArrayList<Integer> position = entry.getKey();
int value = entry.getValue();
if(triples.containsKey(position)){
triples.put(position, triples.get(position) + value);
}else{
triples.put(position, value);
} } while(it2.hasNext()){
Entry<ArrayList<Integer>,Integer> entry = it2.next();
ArrayList<Integer> position = entry.getKey();
int value = entry.getValue();
if(triples.containsKey(position)){
triples.put(position, triples.get(position) + value);
}else{
triples.put(position, value);
} }
return s;
} /*
* 稀疏矩阵求转置矩阵函数
*/
public SMatrix Transposition(){ Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>();
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it = this.Triples.entrySet().iterator();
while(it.hasNext()){
Entry<ArrayList<Integer>, Integer> entry = it.next();
ArrayList<Integer> position = entry.getKey();
int value = entry.getValue();
ArrayList<Integer> transP = new ArrayList<Integer>();
transP.add(position.get(1));
transP.add(position.get(0)); triples.put(transP, value); }
SMatrix s = new SMatrix(triples,this.colNum,this.rowNum);
return s;
} /*
* 加载文本数据为稀疏矩阵三元组形式的函数
*/
public SMatrix Load(String file, String delimeter){ Map<ArrayList<Integer>,Integer> triples = new HashMap<ArrayList<Integer>,Integer>(); try{
File f = new File(file);
FileReader fr = new FileReader(f);
BufferedReader br = new BufferedReader(fr); String line; while((line = br.readLine()) != null){
String[] str = line.trim().split(delimeter); ArrayList<Integer> s = new ArrayList<Integer>();
for(int i = 0;i < str.length - 1; i++){
s.add(Integer.parseInt(str[i]));
} triples.put(s, Integer.parseInt(str[str.length - 1])); } br.close();
fr.close(); }catch(IOException e){
e.printStackTrace();
}
SMatrix sm = new SMatrix(triples);
return sm;
}
/*
* 打印稀疏矩阵(三元组形式)
*/
public void Print(){
Map<ArrayList<Integer>, Integer> triples = this.Triples;
Iterator<Map.Entry<ArrayList<Integer>, Integer>> it = triples.entrySet().iterator();
int num = 0;
while(it.hasNext()){
Entry<ArrayList<Integer>, Integer> entry = it.next();
ArrayList<Integer> position = entry.getKey();
num++;
System.out.print(num+":");
for(Integer in:position){
System.out.print(in + "\t");
} System.out.println(entry.getValue());
} } public static void main(String[] args){ /*
* 测试程序 String testS = "data/me";
int k = 3;
SMatrix te = new SMatrix();
te = te.Load(testS,"\t");
te.rowNum = 4;
te.colNum = 6;
System.out.println("打印原矩阵");
te.Print();
System.out.println("打印原矩阵的转置矩阵");
te.Transposition().Print(); System.out.println("打印乘积矩阵");
SMatrix A2 = new SMatrix(); A2 = te.Multiply(te, te.Transposition());
A2.Print();
*/ long start = System.currentTimeMillis(); String file1 = "data/AT.txt";//author to term 的稀疏矩阵
String file2 = "data/CA.txt";//conference to author 的稀疏矩阵
String delimeter = " ";
int k = 11;
SMatrix M = new SMatrix();
SMatrix MT = new SMatrix(); SMatrix N = new SMatrix();
SMatrix NT = new SMatrix();
SMatrix P = new SMatrix();
SMatrix Q = new SMatrix(); M = M.Load(file1, delimeter);
M.colNum = 9225;
M.rowNum = 6456;
System.out.println("打印矩阵M");
M.Print();
MT = M.Transposition();
System.out.println("打印矩阵MT");
MT.Print(); System.out.println("计算M和MT的乘积");
System.out.println(M.rowNum);
P = M.Multiply(M, MT);
System.out.println("打印矩阵M与矩阵M转置的乘积");
P.Print(); N = N.Load(file2, delimeter);
N.colNum = 6456;
N.rowNum = 20;
System.out.println("打印矩阵N");
N.Print();
NT = N.Transposition(); System.out.println("打印矩阵NT:");
NT.Print(); System.out.println("计算NT 和 N的乘积");
System.out.println(NT.colNum);
System.out.println(N.rowNum);
Q = M.Multiply(NT, N);
Q.Print(); SMatrix A = new SMatrix();
A = A.Load("data/AA.txt"," "); SMatrix A1 = new SMatrix();
SMatrix A2 = new SMatrix();
System.out.println("计算矩阵A1=P+Q:");
A1 = SMatrix.Add(Q, P); System.out.println("打印矩阵A1:");
A1.Print();
A2 = SMatrix.Add(A1, A);//得到了比较全面的author to author 矩阵三元组 A2.Print(); double[][] matrix = new double[A2.rowNum][A2.colNum]; for(int i = 0;i < A2.rowNum;i++){
for (int j = 0; j < A2.colNum; j++) { ArrayList<Integer> list = new ArrayList<Integer>();
list.add(i);
list.add(j); if (A2.Triples.containsKey(list)) {
matrix[i][j] = A2.Triples.get(list);
}
else{
matrix[i][j] = 0;
} }
} for(int i = 0;i<A2.rowNum;i++){
for(int j = 0;j < A2.colNum;j++){
System.out.print(matrix[i][j]+"\t");
}
System.out.println();
}
Matrix Author = new Matrix(matrix); //第二步:求矩阵的特征值eigValue及其相应的特征向量矩阵,取前K个(最大的)
Matrix diagA = Author.eig().getD(); diagA.print(4, 2);
int m = diagA.getRowDimension();
int n = diagA.getColumnDimension(); Matrix eigVector = Author.eig().getV(); eigVector.print(eigVector.getRowDimension(),4); //将特征向量输出到文本中。
String outFile = "data/eigenVector.txt";
try{
File f = new File(outFile);
FileOutputStream fout = new FileOutputStream(f); fout.write("@RELATION\teigenVector\n".getBytes());
for(int i = n-k;i<n;i++){
fout.write(("@ATTRIBUTE\t"+i + "\tREAL\n").getBytes());
}
fout.write("@DATA\n".getBytes());
if(k <= n){
for(int i = 0;i < m;i++){
for(int j = n-k;j<n;j++){
Double temp = new Double(eigVector.getArray()[i][j]);
String tem = temp.toString();
fout.write((tem + "\t").getBytes()); }
fout.write(("\n").getBytes());
}
}
}
catch(IOException e){
e.printStackTrace();
}
//第三步:对特征向量矩阵进行kmeans聚类
Instances ins = null; SimpleKMeans KM = null; // 目前没有使用到,但是在3.7.10的版本之中可以指定距离算法
// 默认是欧几里得距离
DistanceFunction disFun = null; try {
// 读入样本数据
File file = new File("data/eigenVector.txt");
ArffLoader loader = new ArffLoader();
loader.setFile(file);
ins = loader.getDataSet(); // 初始化聚类器 (加载算法)
KM = new SimpleKMeans();
KM.setNumClusters(2); //设置聚类要得到的类别数量 KM.setMaxIterations(100);
KM.buildClusterer(ins); //开始进行聚类
System.out.println(KM.preserveInstancesOrderTipText());
// 打印聚类结果
System.out.println(KM.toString()); // for(String option : KM.getOptions()) {
// System.out.println(option);
// }
// System.out.println("CentroIds:" + tempIns);
} catch(Exception e) {
e.printStackTrace();
} System.out.println("程序正常结束"); long end = System.currentTimeMillis();
System.out.println(end - start); } }
稀疏矩阵乘法加法等的java实现的更多相关文章
- poj 3735 Training little cats 矩阵快速幂+稀疏矩阵乘法优化
题目链接 题意:有n个猫,开始的时候每个猫都没有坚果,进行k次操作,g x表示给第x个猫一个坚果,e x表示第x个猫吃掉所有坚果,s x y表示第x个猫和第y个猫交换所有坚果,将k次操作重复进行m轮, ...
- 【老鸟学算法】大整数乘法——算法思想及java实现
算法课有这么一节,专门介绍分治法的,上机实验课就是要代码实现大整数乘法.想当年比较混,没做出来,颇感遗憾,今天就把这债还了吧! 大整数乘法,就是乘法的两个乘数比较大,最后结果超过了整型甚至长整型的最大 ...
- 九九乘法表的实现--JAVA基础
JAVA算法实现:输出九九乘法表 Jiujiu.java: package com.qkys.www; public class Jiujiu { public static void main(St ...
- 稀疏矩阵的加法(用十字链表实现A=A+B)
描写叙述: 输入两个稀疏矩阵A和B,用十字链表实现A=A+B,输出它们相加的结果. 输入: 第一行输入四个正整数,各自是两个矩阵的行m.列n.第一个矩阵的非零元素的个数t1和第二个矩阵的非零元素的个数 ...
- 稀疏矩阵乘法 · Sparse Matrix Multiplication
[抄题]: 给定两个 稀疏矩阵 A 和 B,返回AB的结果.您可以假设A的列数等于B的行数. [暴力解法]: 时间分析: 空间分析: [思维问题]: [一句话思路]: 如果为零则不相乘,优化常数的复杂 ...
- 【[Offer收割]编程练习赛13 D】骑士游历(矩阵模板,乘法,加法,乘方)
[题目链接]:http://hihocoder.com/problemset/problem/1504 [题意] [题解] 可以把二维的坐标转成成一维的; 即(x,y)->(x-1)*8+y 然 ...
- python 多线程稀疏矩阵乘法
import threading, time import numpy as np res = [] class MyThread(threading.Thread): def __init__(se ...
- 【HDOJ】2424 Gary's Calculator
大数乘法加法,直接java A了. import java.util.Scanner; import java.math.BigInteger; public class Main { public ...
- Java for LeetCode 043 Multiply Strings
Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...
随机推荐
- android 为应用程序创建桌面快捷方式技巧分享
手机装的软件过多,找起来很不方便,所以在主页面有一个快捷方式的话会很不错的,本文将介绍如何实现,需要了解跟多的朋友可以参考下 我们开发一款软件后,如果手机装的软件过多,去翻的话会很难翻的,所以 ...
- 建立一个node.js服务器(使用express搭建第一个Web环境)
一.官网下载node.js 下载地址:https://nodejs.org/en/download/ 根据向导,下一步安装就可以了! 二.使用express搭建Web环境 express是一个开源的n ...
- C#生成二维码示例
其实现在二维码越来越流行,网上也有很多生成二维码的类库.写一下WEB生成二维码注意事项吧! 目前C#生成二维码大部分都是使用ThoughtWorks.QRCode或者ZXing类库生成,主要说一下Th ...
- Oracle11g空表导出方法
今天凌晨在客户现场进行一个Oracle11g的数据库迁移,习惯性的用了exp/imp,然后在新的数据库发现,空表根本没有exp出来,然后查资料,发现了如下信息:[ORACLE 11G在用EXPORT导 ...
- jetty-run运行报错的原因
- Scala语法笔记
JAVA中,举例你S是一个字符串,那么s(i)就是该字符串的第i个字符(s.charAt(i)).Scala中使用apply的方法 JAVA与C++的?:操作符 等同于Scala的 if ( x &g ...
- [Offer收割]编程练习赛4 A 满减优惠
满减优惠 描述 最近天气炎热,小Ho天天宅在家里叫外卖.他常吃的一家餐馆一共有N道菜品,价格分别是A1, A2, ... AN元.并且如果消费总计满X元,还能享受优惠.小Ho是一个不薅羊毛不舒服斯基的 ...
- JQuery之DataTables强大的表格解决方案
1.DataTables的默认配置 $(document).ready(function() { $('#example').dataTable(); } ); 示例:http://www.guoxk ...
- 关于lib,dll,.a,.so,静态库和动态库的解释说明
[转]关于lib,dll,.a,.so,静态库和动态库的解释说明 目录 1 什么叫程序库 2 什么是lib,什么是dll,什么是.a,什么是so,什么是静态库,什么是动态库 3 补充说明 4 作者 什 ...
- 内存调试工具---valgrind
安装 1.到www.valgrind.org下载最新版valgrind-3.2.3.tar.bz2 2.解压安装包:tar –jxvf valgrind-3.2.3.tar.bz2 3.解压后生成目录 ...