`

稀疏矩阵

 
阅读更多
好久没有写过C#了。不过C#确实非常方便,代码写起来也很顺。这个代码是描述行逻辑链接的三元组顺序表。(处理稀疏矩阵效率要比经典算法高得多的~而且也更节省存储空间。)
//#defineOUTPUT_DEBUG
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
 
namespace MatrixCSharp
{
    public class Matrix {
 
        public struct PolyEx {
            publicint i;
            publicint j;
            publicint val;
        }
 
        publicMatrix() {
            polyExList = new List<PolyEx>();
            row = col = tu = 0;
        }
 
        publicMatrix(int[,] array)
            :this(){
 
            LoadPolyExList(array);
        }
 
        public void LoadPolyExList(int[,]array) {
            polyExList.Clear();
            row = array.GetLength(0);
            col = array.GetLength(1);
            tu = 0;
 
            for(int i = 0; i < row; ++i)
            {
                for(int j = 0; j < col; ++j)
                {
                    if(array[i, j] != 0)
                    {
                        PolyEx pe = new PolyEx();
                        pe.i = i;
                        pe.j = j;
                        pe.val = array[i, j];
                        polyExList.Add(pe);
                        ++tu;
                    }
                }
            }
 
            firstIndexs = GetFirstIndex(1);
        }
 
        //
        // 1 =>row
        // 0 =>col
        //
        privateint[] GetFirstIndex(intrOrC) {
            // Readall the column numbers.
            intsize = 0;
            if(rOrC == 1){
                size = row;
            }
            else{
                size = col;
            }
            int[]num4Col = new int[size];
            int[]indexs = new int[size];
 
            foreach(PolyEx pe inpolyExList) {
                if(rOrC == 1){
                    num4Col[pe.i]++;
                }
                else{
                    num4Col[pe.j]++;
                }
            }
 
            for(int i = 0; i < size; ++i){
                if(i > 0)
                {
                    indexs[i] += num4Col[i - 1]+ indexs[i - 1];
                }
                else
                {
                    indexs[i] = 0;
                }
            }
 
#if OUTPUT_DEBUG
            Console.WriteLine("FirstIndexs:");
            foreach (int i in indexs) {
                Console.Write(i + "");
            }
            Console.WriteLine();
#endif
 
            returnindexs;
        }
 
        public void Translate() {
            PolyEx[] resList = new PolyEx[tu];
 
            int[]colFirstIndexs = GetFirstIndex(0);
            intindex = -1;
            foreach(PolyEx pe inpolyExList) {
                PolyExpeNew = new PolyEx();
                peNew.j = pe.i;
                peNew.i = pe.j;
                peNew.val = pe.val;
                index = colFirstIndexs[pe.j];
                resList[index] = peNew;
                colFirstIndexs[pe.j]++;
            }
 
            polyExList = new List<PolyEx>(resList);
 
            firstIndexs = colFirstIndexs;
 
            inttemp = row;
            row = col;
            col = row;
        }
 
        public Matrix Mul(Matrixm2) {
            if(this.col != m2.row) {
                returnnull;
            }
 
            MatrixmRes = new Matrix();
 
            // 累加器
            int[] acc = new int[m2.col];
 
            for(int i = 0; i < polyExList.Count; ++i) {
                if(i > 0) {
                    if(polyExList[i].i != polyExList[i - 1].i) {
 
                        for (int j = 0; j < m2.col;++j)
                        {
                            if (acc[j] != 0)
                            {
                                PolyEx pe = new PolyEx();
                                pe.i =polyExList[i].i;
                                pe.j = j;
                                pe.val =acc[j];
                                Console.WriteLine("Col:"+ j + " Val:" + pe.val);
                               mRes.polyExList.Add(pe);
                            }
                        }
                        setZero(acc);
                    }
                }
 
                intcolIndex = m2.firstIndexs[polyExList[i].j];
                while(colIndex < m2.polyExList.Count
                        &&m2.polyExList[colIndex].i == polyExList[i].j) {
#if OUTPUT_DEBUG
                    Console.WriteLine("i=> " + polyExList[i].i);
                    Console.WriteLine("m2j => " + m2.polyExList[colIndex].j);
                    Console.WriteLine();
#endif
                    acc[m2.polyExList[colIndex].j]
                        +=m2.polyExList[colIndex].val * polyExList[i].val;
                    colIndex++;
                }
            }
 
            for(int j = 0; j < m2.col; ++j)
            {
                if(acc[j] != 0)
                {
                    PolyExpe = new PolyEx();
                    pe.i =polyExList[polyExList.Count - 1].i;
                    pe.j = j;
                    pe.val = acc[j];
#if OUTPUT_DEBUG
                   Console.WriteLine("Col:" + j + " Val:" + pe.val);
#endif
                    mRes.polyExList.Add(pe);
                }
            }
 
            mRes.row = row;
            mRes.col = m2.col;
            mRes.firstIndexs = mRes.GetFirstIndex(1);
            mRes.tu = mRes.polyExList.Count;
 
            returnmRes;
        }
 
        privatevoid setZero(int[]array) {
            for(int i = 0; i < array.Length; ++i) {
                array[i] = 0;
            }
        }
 
        public int Row {
            get{ return row; }
        }
 
        public int Col {
            get{ return col; }
        }
 
        public override stringToString()
        {
            StringBuildersb = new StringBuilder();
 
            sb.AppendLine("i\tj\tvalue");
            sb.AppendLine("--\t--\t-----");
            foreach(PolyEx pe inpolyExList) {
                sb.AppendFormat("{0}\t{1}\t{2}\n",
                    pe.i,
                    pe.j,
                    pe.val);
            }
 
            returnsb.ToString();
        }
           
        privateList<PolyEx>polyExList;
        privateint[] firstIndexs;              // 记录每一行非零元的起始位置
        privateint row;
        privateint col;
        privateint tu;
    }
 
    class Program
    {
        static int[,] SimpleMul(int[,]m1, int[,] m2) {
            introw1 = m1.GetLength(0);
            intcol1 = m1.GetLength(1);
            introw2 = m2.GetLength(0);
            intcol2 = m2.GetLength(1);
 
            int[,]mRes = new int[row1,col2];
            for(int i = 0; i < row1; ++i) {
                for(int j = 0; j < col2; ++j) {
                    mRes[i, j] = 0;
                    for(int k = 0; k < col1; ++k) {
                        mRes[i,j] += m1[i,k] *m2[k,j];
                    }
                }
            }
 
            for(int i = 0; i < row1; ++i) {
                for(int j = 0; j < col2; ++j) {
                    if(mRes[i, j] == 0){
                        Console.Write("-\t");
                    }
                    else{
                        Console.Write(mRes[i, j] + "\t");
                    }
                }
                Console.WriteLine();
            }
 
                returnmRes;
        }
 
        static void Main(string[]args)
        {
            int[,]test = {
                { 0, 0, 1, 0, 0, 0, 1, 0, 3,4},
                { 3, 0, 0, 0, 0, 0, 7, 0, 3,4},
                { 0, 4, 9, 0, 0, 5, 1, 0, 3,4},
                { 0, 0, 0, 13, 0, 0, 8, 0, 3, 4},
                { 0, 0, 0, 0, 0, 0, 9, 0, 3,4},
                { 0, 0, 0, 0, 0, 0, 1, 0, 3,4},             
            };
 
            int[,]test2 = {
                { 1, 0, 8, 0, 0, 1},
                { 0, 0, 0, 0, 3, 0},
                { 0, 3, 0, 0, 0, 0},
                { 0, 5, 0, 0, 0, 0}, 
                { 0, 5, 0, 0, 0, 0},
                { 0, 5, 4, 0, 0, 0},
                { 0, 9, 0, 0, 1, 0},
                { 0, 5, 0, 0, 0, 0},
                { 0, 5, 0, 5, 0, 0},
                { 0, 5, 0, 0, 0, 0},            
            };
 
            Matrixm = new Matrix(test);
            Matrixm2 = new Matrix(test2);
 
            Console.WriteLine(m);
            Console.WriteLine(m2);
 
            Matrixres = m.Mul(m2);
            Console.WriteLine(res);
 
            SimpleMul(test, test2);
 
            //m.Translate();
            //Console.WriteLine(m);
            Console.ReadKey();
        }
    }
}
 
 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics