三元組求稀疏矩陣的轉置
阿新 • • 發佈:2019-01-02
將非零元素所在的行、列以及它的值構成一個三元組(row,col,value),然後再按某種規律儲存這些三元組,這種方法可以節約儲存空間。
演算法思想
直接按照稀疏矩陣A的三元組表A.value的次序依次順序轉換,並將轉換後的三元組放置於三元組表B.value的恰當位置。
為了算出每個三元組的具體位置,設兩個輔助向量num[ ]和cpot[ ] 。
◆ num[col]:統計稀疏矩陣A中第col列中非0元素的個數
◆ cpot[col] :指示稀疏矩陣A中第col列第一個非0元素在B.value中的恰當位置
顯然有位置對應關係:
cpot[1]=1,col=1
cpot[col]=cpot[col-1]+num[col-1],2≦col≦A.cn
程式碼如下:
三元組的類
public class ThreeTuples {
int row;//非零元素的行下標
int col;//非零元素的列下標
int value;//值
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this .col = col;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + col;
result = prime * result + row;
result = prime * result + value ;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ThreeTuples other = (ThreeTuples) obj;
if (col != other.col)
return false;
if (row != other.row)
return false;
if (value != other.value)
return false;
return true;
}
public ThreeTuples(int row, int col, int value) {
super();
this.row = row;
this.col = col;
this.value = value;
}
public ThreeTuples() {
super();
}
@Override
public String toString() {
return "(row=" + row + ", col=" + col + ", value=" + value + ")";
}
}
稀疏矩陣的類
public class SMatrix {
ThreeTuples[] value;
int rn;// 矩陣的行數
int cn;// 矩陣的列數
int tn;// 非零元素個數
public ThreeTuples[] getValue() {
return value;
}
public void setValue(ThreeTuples[] value) {
this.value = value;
}
public int getRn() {
return rn;
}
public void setRn(int rn) {
this.rn = rn;
}
public int getCn() {
return cn;
}
public void setCn(int cn) {
this.cn = cn;
}
public int getTn() {
return tn;
}
public void setTn(int tn) {
this.tn = tn;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + cn;
result = prime * result + rn;
result = prime * result + tn;
result = prime * result + Arrays.hashCode(value);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SMatrix other = (SMatrix) obj;
if (cn != other.cn)
return false;
if (rn != other.rn)
return false;
if (tn != other.tn)
return false;
if (!Arrays.equals(value, other.value))
return false;
return true;
}
public SMatrix() {
super();
}
public SMatrix(ThreeTuples[] value, int rn, int cn, int tn) {
super();
this.value = value;
this.rn = rn;
this.cn = cn;
this.tn = tn;
}
@Override
public String toString() {
System.out.println("TSMatrix \n[");// data=
System.out.println("rn=" + rn + "\ncn=" + cn + "\ntn=" + tn);
for (int i = 1; i <= tn; i++) {
System.out.println(value[i]);
}
return "]";
}
}
操作類
public class Op {
public static int n = 20;//設稀疏矩陣最多有n個元素
// 稀疏矩陣的快速轉置
public void transposeSMatrix(SMatrix m, SMatrix m1) {
int[] num = new int[m.cn + 1];// 統計每一列非零元素的個數
int[] cpot = new int[n + 1];// 每一列的一個非零元素在三元組中的位置
int col;
int q;
m1.rn = m.cn;
m1.cn = m.rn;
m1.tn = m.tn;
if (m.tn == 0) {
System.out.println("the matrix A = 0");
} else {
for (int i = 1; i <= m.cn; i++) {
num[i] = 0;
}
// 求每一列中的非零元素個數
for (int i = 1; i <= m.tn; i++) {
num[m.value[i].col]++;
}
// 求每一列中第一個非零元素的位置
// 第i列非零元素位置 = 第i-1列第一個元素位置 + 第i-1的非零元素個數
// 第一列的第一個元素在三元組第一個位置
for (cpot[1] = 1, col = 2; col <= m.cn; col++) {
cpot[col] = cpot[col - 1] + num[col - 1];
}
m1.value = new ThreeTuples[n + 1];// value陣列例項化
// 轉置
for (int i = 1; i <= m.tn; i++) {
col = m.value[i].col;
q = cpot[col];
m1.value[q] = new ThreeTuples();//
m1.value[q].row = m.value[i].col;
m1.value[q].col = m.value[i].row;
m1.value[q].value = m.value[i].value;
cpot[col]++;// 第col加上一個元素,所以第col列第一個元素的位置也要加一
}
}
}
// 建立一個稀疏矩陣
public void createSMatrix(SMatrix m) {
char op;
int pos = 1;
m.value = new ThreeTuples[n + 1];
Scanner sc = new Scanner(System.in);
System.out.print("please enter the row of the sparse matrix:");
m.rn = sc.nextInt();
System.out.print("please enter the column of the sparse matrix:");
m.cn = sc.nextInt();
while (true) {
System.out.print("Do you continue to enter?(Y|N)");
op = sc.next().charAt(0);
if (op == 'Y' || op == 'y') {
int row;
int col;
System.out.print("row:");
row = sc.nextInt();
System.out.print("column:");
col = sc.nextInt();
if (row <= m.rn && row > 0 && col <= m.cn && col > 0) {
System.out.print("please enter the value:");
int value = sc.nextInt();
m.value[pos] = new ThreeTuples();// 陣列中的每一個物件都要例項化
m.value[pos].setRow(row);
m.value[pos].setCol(col);
m.value[pos].setValue(value);
m.tn++;
pos++;
} else {
System.out.print("illegal position.");
}
} else if (op == 'N' || op == 'n') {
break;
} else {
System.out.println("error.");
}
}
}
}
主方法
public static void main(String[] args) {
SMatrix M = new SMatrix();
Scanner sc = new Scanner(System.in);
Op op = new Op();
System.out.println("1.create a sparse matrix\n2.sparse matrix transposing");
while (true) {
System.out.print("please enter operationcode:");
int a = sc.nextInt();
switch (a) {
case 1:
op.createSMatrix(M);
System.out.println(M);
break;
case 2:
SMatrix M1 = new SMatrix();// 定義一個轉置後的稀疏矩陣
op.transposeSMatrix(M, M1);// 轉置
System.out.println(M1);
break;
default:
System.out.println("Error operating code.");
break;
}
}
}
以下圖為例執行一下程式碼
執行結果