Triplet sequence table and generalized table

1 sparse matrix:

  Assuming m * n matrix, there is no element t 0. Let q = t / (m * n), q is called a sparse matrix factor. Generally considered q <= 0.05 when considered sparse matrix.

2 triple order table

If storage space is allocated to each element, then the matrix contains a large number of 0 will result in waste of resources. So in general we store a compressed manner, except that the stored value of non-zero elements, but also store the corresponding row and column. Thus, the sparse matrix may be represented by non-zero elements and triples the number of ranks is determined uniquely.

  Related defined as follows:

typedef int the Status
 #define MAX_ROW 100
 #define MAX_SIZE 101 
typedef int elemType; 
typedef struct 
{ 
    int Row; // set the row index
     int COL; // set the column index value 
    elemtype value; // set the element value 
} Triple; 
typedef struct 
{ 
    int RN; // set the number of rows
     int CN; // set the number of columns
     int TN; 
    Triple Data [MAX_SIZE]; // set array 
} TMatrix;

  Transpose operation (transpose performed in a certain order):

  Here we note that storage is stored in rows.

  The time complexity is rn * tn. Tn when much smaller than rn * cn use, otherwise the big time complexity compared to traditional methods and more. (Sacrifice time to optimize storage)

//转置操作
void TransposeSMatrix(TMatrix M, TMatrix T)
{
    T.rn = M.cn; T.cn = M.rn; T.tn = M.tn;
    if (T.tn) {
        q = 1;
        for (col = 1; col < M.rn; ++col)
            for (p = 1; p < M.tn; ++p)
                if (M.data[p].cn == col) {
                    T.data[q].rn = M.data[p].cn; T.data[q].cn = M.data[p].rn;
                    T.data[q].value = M.data[p].value;
                }
    }
}

  Quick transpose:

// quick transposition 
void FastTranspodeSMtrix (M TMatrix, TMatrix T) 
{ 
    T.rn = m.cn; t.cn = M.rn; T.tn = M.tn;
     IF (T.tn) {
         for (COL = . 1 ; COL <M.rn; ++ COL) NUM [COL] = 0 ;
         for (T = . 1 ; T <= T M.tnl ++) ++ NUM [M.data [T] .cn]; 
        the cPOT [ 1 ] = 1 ;
         // find the first one of the first non-zero row col element M.data sequence number 
        for (col = 2 ; col <= M.tn; P ++) the cPOT [col] = the cPOT [COL - . 1 ] + NUM [COL - . 1 ];
         for (p=1; p <= M.tn; ++p) {
            col = M.data[p].cn; q = cpot[col];
            T.data[q].rn = M.data[p].cn; T.data[q].cn = M.data[p].rn;
            T.data[q].value = M.data[p].value; ++cpot[col];
        }
    }
}

  This algorithm compared to the previous over one of the two auxiliary vectors. There are two single cycle, the time complexity is rn + cn. Number of elements and the non-0 rn * cn same order of magnitude, the time complexity of the algorithm is the same as M of the classical.

3 row sequence table logical connection:

   We indicating "line" assistant cpot fixed array of information storage structure among the sparse matrix.

The following two matrix multiplication algorithm:

typedef struct
{
    Triple data[MAX_SIZE];
    int rpos[MAX_ROW];
    int rn, cn, tn;
}RLSMatrix;


//三元组定义  默认行从1开始
void MultsMatrix(PLSMatrix a, RLSMatrix b, RLSMatrix c)
{
    elemtype ctemp[MAX_SIZE];
    int p, q, arow, ccol, brow, t;
    if (a.cn != b.rn) { cout << "Error" << endl; }
    else
    {
        c.rn = a.rn; c.cn = b.cn; c.tn = 0;
        if (a.tn * b.tn != 0)
        {
            for(= AROW . 1 ; AROW <= a.rn; AROW ++)   // for each row of a process 
            { 
                cTemp [AROW] = 0 ;    // current line of each element of the accumulator cleared 0 
                c.rpos [AROW] = C. + TN . 1 ; P = a.rpos [AROW];
                 for (; P <a.rpos [arrow arrow + . 1 ]; P ++)    // for each current row 0 yuan non 
                { 
                    BROW = a.data [ P] .col;       // find the row number corresponding to the b 
                    IF (BROW <b.rn) T = b.rpos [BROW + . 1 ];
                     the else T = + b.tn . 1;
                     For (Q = b.rpos [BROW]; Q <T; ++ Q) 
                    { 
                        CCOL = b.data [Q] .col; 
                        cTemp [CCOL] + = a.data [P] * .Value b.data [Q] .Value; 
                    } 
                } 
                for (CCOL = . 1 ; CCOL <= c.cn; CCOL ++)    // compression stored in the row non-0 yuan 
                    IF (cTemp [CCOL] =! 0 ) 
                    { 
                        IF (++ c.tn> MAX_SIZE) 
                        { 
                            COUT << " Error " << endl; exit(0);
                        }
                        else c.data[c.tn] = (arow, ccol, ctemp[ccol]);
                    }
            }
        }
    }
}

4 Cross List

  When the non-zero matrix IE number and position change during operation is large, it should not be used to represent the sequence structure of linear form triples. For example, the matrix B is added to the matrix A, since the operation of non-zero elements of the array causes a change. Therefore, the use of chain table easier.

  In addition to the row and column values, and two pointers, the identifier for a peer of the next non-zero element and the same row of non-0.

 

typedef struct clnode 
{ 
    int I, J; 
    elemType E; 
    struct clnode Down *, * right; 
} OLNode; 
// below are definitions of the entire sparse matrix 
typedef struct 
{ 
    int MU; int NU; int TU; 
    OLNode * rhead; 
    OLNode * chead; 
} CrossList; 
void CreateSMatrix_OL (CressList & m) 
{ 
    int m, n-, T;
     // create a sparse matrix. Cross chain represented using 
    IF (M) Free (M); 
    COUT <<" Please enter the number of rows of the matrix M, the number of columns and the number of non-0 element ' << endl; 
    CIN >> >> m >> n- T; 
    M.mu = m; = n-M.nu; M.tu = T;       // number of rows uM amount, the number of columns and the number of nonzero elements 
    IF (! (M.rhead = (OLNode *) the malloc ((m + . 1 ) * the sizeof (OLNode)))) COUT << " input data error " << endl;
     IF (! (M.chead = (OLNode *) the malloc ((n-+ . 1 ) * the sizeof (OLNode)))) COUT << " input data error " << endl; 
    M. rhead [] = M.Permission [] =NULL;
     for (CIN I >> >> >> J E; I =! 0 ; CIN I >> >> >> J E;) {
         IF ! ((P = (OLNode *) the malloc ( the sizeof (OLNode)) )) COUT << " data allocation error " << endl; 
        P -> I = I; p-> J = J; p-> E = E;        // generating node 
        IF (M.rhead [I] == || M.rhead NULL [I] -> J> J) {p-> right = M.rhead [I]; M.rhead [I] = P;}
         the else {         // find the insertion position of the row in the table 
            for (Q = M.rhead [I]; (Q-> right) && Q-> right-> J <J; Q = Q-> right);
            p->right = q->right; q->right =P; 
        } 
        IF (M.chead [J] == NULL || M.chead [J] -> I> I) {p-> Down = M.chead [J]; M.chead [J] = P; }
         the else {         // find the insertion position in the list 
            for (Q = M.chead [I]; (Q-> Down) && Q-> DOWN-> J <J; Q = Q-> Down); 
            P - > = Q- Down> Down; Q-> Down = P;       // complete insertion column 
        } 
    } 
}

5 General List

  Generalized linear table is a generalization of the table.

  Generally referred to as generalized list:

      LS = (a1, a2, a3,..., an)

  Each element may be a single element, the table may be generalized, and the sub-tables are called atoms generalized table.

  When generalized list is not empty, we used to call the first element is the header, said the remaining elements for the end of the table (a2, a3, a4, ..., an).

  It is worth recalling list () and (()) different. The former table is empty, a length of 0; 1 is a length which can be decomposed to obtain the header, footer table are empty ().

  This flexibility will need to use a chain storage structure. Node needs two structures, one is the node atoms to atoms represented by flags field, the composition range; the other is a list by standard range, and range pointer field identification header components.

 

Seeking a generalized table depth (recursively):

  Generalized maximum depth of the respective sub-table is the table plus a depth, a distinction length;

  We atom with 0 ATOM (Tag), and vice versa for the child table.

typedef struct GLNode { 
    ElemTag Tag;    // common portion, for distinguishing atoms and Table nodes 
    int Atom; 
    GLNode * HP; 
    GLNode * TP; 
} * a GList;
 // Solution Table depth 
int GListDepth (a GList L) 
{ 
    int DEP, max; 
    a GList PP; 
    // use head and tail linked list storage structure, the depth L out generalized table 
    IF (L!) return  . 1 ;     // empty list a depth 
    IF (L-> the ATOM Tag ==) retun 0 ;    // atoms depth 0 
    for (max = 0, L = PP; PP; PP = PP-> TP) 
    { 
        DEP = GListDepth (pp-> hp);   // seek to pp-> hp for the first sub-table pointers depth 
        IF (DEP> max) max = DEP; 
    } 
    return max + . 1 ; 
}

2 recursive copy generalized table

  Each recursive copy headers and footers:

// Copy generalized table 
void CopyGlist (a GList & T, a GList L) 
{ 
    IF (! L) T = NULL;    // copy empty table 
    the else {
         IF ((T = (a GList)! The malloc ( the sizeof (GLNode))) COUT < < " erroneous data distribution occurs " << endl;    // build the table node 
            T-> = L-Tag> Tag;
             IF (L-> Tag == 0 ) T-> = L-Atom> Atom;     // copy single atom 
            the else { 
                CopyGlist (T -> HP, L-> HP); 
                CopyGlist (T -> TP, L-> TP);
            }
    }
}

 

Guess you like

Origin www.cnblogs.com/a-runner/p/12602184.html