1. 程式人生 > >三元組求稀疏矩陣的轉置

三元組求稀疏矩陣的轉置

將非零元素所在的行、列以及它的值構成一個三元組(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;
            }
        }
    }

以下圖為例執行一下程式碼
這裡寫圖片描述
執行結果
這裡寫圖片描述
這裡寫圖片描述