免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3750 | 回复: 6
打印 上一主题 下一主题

稀疏矩阵(Sparse Matrix)的java实现 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-08-06 23:56 |只看该作者 |倒序浏览
看看这里不像C坛这么热闹,过来给大家捧捧场。
下面是我过去做过的一个assignment,一共有4个class(其中一个inner class),请大家多指教:

   
  1. Background

  2. Very large two-dimensional arrays or matricies often arise in solving problems in areas as diverse as engineering and computer graphics. It is not uncommon for such matrices to have 50,000 rows and 50,000 columns. A tremendous amount of memory would be needed to store such matricies in the conventional manner. For example, if each element is of type float (4 bytes) then 10 GB would be required for the above example! Fortunately, these matricies are often sparse; that is, most elements are zero and only a very few elements are non-zero. To save memory, only the non-zero elements are stored. One way that this can be done is to represent the sparse matrix as a two-dimensional linked list of the non-zero elements.

  3. 有时候出于某种原因我们需要一个非常大的二维数组,但是这数组并不是经常满的,这样就很浪费内存,因此我们可以用稀疏矩阵来代替它,这稀疏矩阵就是用二维链表把非零的节点连起来。
复制代码

论坛徽章:
0
2 [报告]
发表于 2003-08-06 23:57 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现

class SparseMatrix & inner class Element:

   
  1. import java.io.*;

  2. /****************************************************************
  3. This class provides functionality for storing, solving, and
  4. managing sparce matrices. Only the non-zero elements are stored.
  5. It represents the sparse matrix as a two-dimensional linked list
  6. of the non-zero elements. The elements of Matrix are all of type
  7. float.
  8. ****************************************************************/
  9. public class SparseMatrix
  10. {
  11.    // This class provides the list node for the linked list. with
  12.    //        references to the next non-zero element in the same row and
  13.    //        the next non-zero element in the same column.
  14.    class Element
  15.    {
  16.       private int row;
  17.       private int column;
  18.       private float value;
  19.       private Element right;
  20.       private Element down;
  21.    }

  22.    private Element[] rowHead;
  23.    private Element[] columnHead;


  24.    /*************************************************************
  25.     Create an m-by-n SparseMatrix with storing it in the linked
  26.     list.
  27.    
  28.     @param m the number of rows in <code>;this</code>; Matrix.
  29.    
  30.     @param n the number of columns in <code>;this</code>; Matrix.
  31.    **************************************************************/
  32.    public SparseMatrix (int m, int n)                //constructor
  33.    {       
  34.            if(m <= 0)
  35.            {
  36.                    System.out.println("The rows of the matrix must be greater than zero.");
  37.                    System.exit(1);
  38.            }
  39.           
  40.            if(n <= 0)
  41.            {
  42.                    System.out.println("The columns of the matrix must be greater than zero.");
  43.                    System.exit(1);
  44.            }
  45.           
  46.            rowHead = new Element[m];
  47.       columnHead = new Element[n];
  48.    }

  49.    
  50.         /*************************************************************
  51.          Add the passed SparseMatrix to <code>;this</code>; SparseMatrix.
  52.          
  53.          @param B the SparseMatrix to add to <code>;this</code>;
  54.          SparseMatrix.
  55.          
  56.          @return a reference to a new SparseMatrix object that is equal
  57.          to the sum of <code>;this</code>; SparseMatrix and the passed one.
  58.          If the passed SparseMatrix is null or the number of rows and
  59.          columns of <code>;this</code>; SparseMatrix is not equal to the
  60.          passed one, null will be returned.
  61.         **************************************************************/
  62.    public SparseMatrix add (SparseMatrix B)
  63.    {       
  64.            SparseMatrix C = null;
  65.            if (B != null && rowHead.length == B.rowHead.length && columnHead.length == B.columnHead.length)
  66.            {       
  67.                    C = new SparseMatrix(rowHead.length, columnHead.length);
  68.                    SparseList[] scaleOne = new SparseList[rowHead.length * columnHead.length];
  69.                   
  70.                    Element aNext, bNext, rowNext, newNode;
  71.                   
  72.                    for (int i = 0; i < rowHead.length; i++)
  73.                    {       
  74.                            if (rowHead[i] != null || B.rowHead[i] != null)
  75.                            {
  76.                                    aNext = rowHead[i];                        //trace Matrix this' row linked list
  77.                                    bNext = B.rowHead[i];                //trace Matrix B's row linked list
  78.                                    newNode = new Element();        //obtain node for new value
  79.                                    C.rowHead[i] = newNode;       
  80.                                   
  81.                                    do
  82.                                    {
  83.                                            if (aNext == null)
  84.                                            {
  85.                                                    rowNext = bNext;
  86.                                                    bNext = bNext.right;
  87.                                            } else if (bNext == null)
  88.                                            {
  89.                                                    rowNext = aNext;
  90.                                                    aNext = aNext.right;
  91.                                            } else
  92.                                            {       
  93.                                                    if (bNext.column < aNext.column)
  94.                                                    {       
  95.                                                            rowNext = bNext;
  96.                                                            bNext = bNext.right;
  97.                                                    } else if (bNext.column >; aNext.column)
  98.                                                    {       
  99.                                                            rowNext = aNext;
  100.                                                            aNext = aNext.right;
  101.                                                    } else if (Math.abs(aNext.value + bNext.value) >; 0.0001)
  102.                                                    {       
  103.                                                            rowNext = new Element();
  104.                                                            rowNext.row = aNext.row;
  105.                                                            rowNext.column = aNext.column;
  106.                                                            rowNext.value = aNext.value + bNext.value;
  107.                                                            aNext = aNext.right;
  108.                                                            bNext = bNext.right;
  109.                                                    }else        // at the same position && sum of the values = 0
  110.                                                    {       
  111.                                                            aNext = aNext.right;
  112.                                                            bNext = bNext.right;
  113.                                                            continue;
  114.                                                    }
  115.                                            }
  116.                                                                                      
  117.                                            newNode.row = rowNext.row;
  118.                                            newNode.column = rowNext.column;
  119.                                            newNode.value = rowNext.value;
  120.                                                   
  121.                                            C.insertColumn(newNode);
  122.                                           
  123.                                            rowNext = rowNext.right;
  124.                                            if (aNext != null || bNext != null)
  125.                                            {
  126.                                                           newNode.right = new Element();
  127.                                                           newNode = newNode.right;
  128.                                                 } else        // the last node
  129.                                                 {        newNode.right = null;
  130.                                                         newNode.down = null;
  131.                                                 }
  132.                                         }while (aNext != null || bNext != null);
  133.                                 }
  134.                    }
  135.            }
  136.            return C;
  137.    }


  138.    /*************************************************************
  139.          Multiply the passed number to all elements in
  140.          <code>;this</code>; SparseMatrix.
  141.          
  142.          @param k the number to multiply <code>;this</code>; SparseMatrix
  143.          by.
  144.          
  145.          @return a reference to a new Matrix object that is equal to
  146.          the product of <code>;this</code>; SpaseMatrix and the passed
  147.          number.
  148.         **************************************************************/
  149.    public SparseMatrix scale (float k)
  150.    {       
  151.            SparseMatrix C = new SparseMatrix(rowHead.length, columnHead.length);
  152.            Element newNode, rowNext;
  153.           
  154.            if (k != 0.) // if k is equal to zero, no new node is added
  155.            {
  156.                    for (int i = 0; i < rowHead.length; i++)
  157.                    {       
  158.                            if (rowHead[i] != null)
  159.                            {
  160.                                    rowNext = rowHead[i];        //trace this row linked list
  161.                                    newNode = new Element();        //obtain node for new value
  162.                                    C.rowHead[i] = newNode;       
  163.                                   
  164.                                    do
  165.                                    {
  166.                                            int rowNo = rowNext.row;
  167.                                            int columnNo = rowNext.column;
  168.                                           
  169.                                            newNode.row = rowNo;
  170.                                            newNode.column = columnNo;
  171.                                            newNode.value = k * rowNext.value;
  172.                                           
  173.                                            C.insertColumn(newNode);
  174.                                           
  175.                                            rowNext = rowNext.right;
  176.                                            if (rowNext != null)
  177.                                            {
  178.                                                    newNode.right = new Element();
  179.                                                    newNode = newNode.right;
  180.                                            } else        // the last node
  181.                                                 {        newNode.right = null;
  182.                                                         newNode.down = null;
  183.                                                 }
  184.                                    }while (rowNext != null);
  185.                            }
  186.                    }
  187.                 }
  188.            return C;
  189.    }


  190.         /*************************************************************
  191.          Return the maximum absolute row sum of <code>;this</code>;
  192.          SparseMatrix.
  193.          
  194.          @return the infinity norm of <code>;this</code>; SparseMatrix.
  195.         **************************************************************/
  196.    public float norm ()
  197.    {       
  198.            double max = 0.;
  199.            double sum;
  200.            Element newNode;
  201.           
  202.            for (int i = 0; i < rowHead.length; i++)
  203.            {       
  204.                    sum = 0.;
  205.                    // add the value in the same row list
  206.                    for (newNode = rowHead[i]; newNode != null; newNode = newNode.right)
  207.                    {       
  208.                            sum += Math.abs(newNode.value);
  209.                    }
  210.                    if (sum >; max)
  211.                            max = sum;
  212.            }
  213.            return (float)max;
  214.    }


  215.         /*************************************************************
  216.          Initialize <code>;this</code>; SparseMatrix with the values
  217.          from the passed array.
  218.          
  219.          @param a the array to be initialized <code>;this</code>; SparseMatrix.
  220.         **************************************************************/
  221.    public void setMatrix (SparseList[] a)
  222.    {       
  223.       for (int i = 0; i < rowHead.length; i++)
  224.          rowHead[i] = null;

  225.       for (int j = 0; j < columnHead.length; j++)
  226.          columnHead[j] = null;
  227.           
  228.            Element newNode, rowPrevious, rowNext, columnPrevious, columnNext;
  229.           
  230.            for (int i = 0; i < a.length; i++)
  231.            {       
  232.                    //        test if this element is in this matrix and the element's value is not equal to zero
  233.                    if (a[i].getRow() < rowHead.length && a[i].getColumn() < columnHead.length && a[i].getValue() != 0)
  234.                    {       
  235.                            int rowNo = a[i].getRow();
  236.                            int columnNo = a[i].getColumn();
  237.                           
  238.                            newNode = new Element();        //obtain node for new value
  239.                            newNode.right = null;
  240.                            newNode.down = null;
  241.                            newNode.row = rowNo;
  242.                            newNode.column = columnNo;
  243.                            newNode.value = a[i].getValue();
  244.                           
  245.                                   // the later one will overwrite the former one if at the same position
  246.                                   if (rowHead[rowNo] != null && columnNo == rowHead[rowNo].column)
  247.                                    rowHead[rowNo].value = a[i].getValue();
  248.                                   else        //        no former one at the same position
  249.                                           insertRow(newNode);
  250.                            insertColumn(newNode);
  251.                    }
  252.            }
  253.    }

  254.         /*************************************************************
  255.          Display <code>;this</code>; SparseMatrix as a rectangular grid
  256.          of values on the screen. It prints all the elements in the
  257.          matrix, including the implicit zeros.
  258.         **************************************************************/
  259.    public void displayMatrix ()
  260.    {       
  261.            int count;
  262.            Element newNode;
  263.            for (int i = 0; i < rowHead.length; i++)
  264.            {       
  265.                    count = 0; //        count the number of the printed elements       
  266.                    for (newNode = rowHead[i]; newNode != null; newNode = newNode.right)
  267.                    {       
  268.                            //        print the 0's before and between the nodes
  269.                            for (int j = count; j < newNode.column; j++)
  270.                                    System.out.print("0.000    ");
  271.                            System.out.print(newNode.value);
  272.                            for (int j = 0; j < 9 - new Float(newNode.value).toString().length(); j++)
  273.                                    System.out.print(" ");
  274.                            count = newNode.column + 1;
  275.                    }
  276.                   
  277.                    //        print the 0's after the last node or in the empty linked list.
  278.                    for (int j = count; j < columnHead.length; j++)
  279.                            System.out.print("0.000    ");
  280.                         System.out.println();
  281.                 }
  282.                 System.out.println();
  283.    }
  284.    
  285.                         
  286.    // insert to the row linked list
  287.    private void insertRow (Element node)
  288.    {          
  289.            Element rowPrevious, rowNext;
  290.                 int rowNo = node.row;
  291.       int columnNo = node.column;       
  292.                           
  293.            // see if the node goes first in the list
  294.            if (rowHead[rowNo] == null || columnNo < rowHead[rowNo].column)
  295.            {       
  296.                    node.right = rowHead[rowNo];
  297.                    rowHead[rowNo] = node;
  298.            } else        // find place to link the node
  299.            {       
  300.                    rowPrevious = rowHead[rowNo];
  301.                    rowNext = rowHead[rowNo].right;
  302.                    while (rowNext != null && columnNo >; rowNext.column)
  303.                    {       
  304.                            rowPrevious = rowNext;
  305.                            rowNext = rowNext.right;
  306.                    }
  307.                                   
  308.                    // adjust links to complete insertion
  309.                    rowPrevious.right = node;
  310.                    node.right = rowNext;
  311.            }
  312.         }
  313.    
  314.        
  315.         // insert to the column linked list
  316.         private void insertColumn (Element node)
  317.         {
  318.                 Element columnPrevious, columnNext;
  319.                 int rowNo = node.row;
  320.       int columnNo = node.column;
  321.                
  322.                 // see if the node goes first in the list
  323.                 if (columnHead[columnNo] == null || rowNo < columnHead[columnNo].row)
  324.                 {       
  325.                    node.down = columnHead[columnNo];
  326.                         columnHead[columnNo] = node;
  327.                 } else        // find place to link the node
  328.                 {       
  329.                         columnPrevious = columnHead[columnNo];
  330.                         columnNext = columnHead[columnNo].down;
  331.                    while (columnNext != null && rowNo >; columnNext.row)
  332.                    {       
  333.                            columnPrevious = columnNext;
  334.                            columnNext = columnNext.down;
  335.                    }
  336.                                           
  337.                           // adjust links to complete insertion
  338.                    columnPrevious.down = node;
  339.                    node.down = columnNext;
  340.                 }
  341.         }
  342. }
复制代码

论坛徽章:
0
3 [报告]
发表于 2003-08-06 23:59 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现

class SparseList:

   
  1. // This class holds the (i,j) co-ordinates and values of the non-zero elements
  2. public class SparseList
  3. {
  4.    private int row;
  5.    private int column;
  6.    private float value;

  7.    public void setRow (int row)
  8.    {  this.row = row;
  9.    }

  10.    public void setColumn (int column)
  11.    {        this.column = column;
  12.    }

  13.    public void setValue (float value)
  14.    {  this.value = value;
  15.    }
  16.    
  17.    public int getRow ()
  18.    {        return row;
  19.         }

  20.         public int getColumn ()
  21.         {        return column;
  22.         }

  23.         public float getValue ()
  24.         {        return value;
  25.         }
  26. }
复制代码


class SparseMatrixDriver:

  1. import java.io.*;

  2. /***********************************************
  3. This is the test driver for the Matrix class.
  4. ***********************************************/
  5. public class SparseMatrixDriver
  6. {
  7.    public static void main (String[] args)
  8.    {
  9.       // create SparseMatrix A
  10.                 System.out.print("Input the command ");
  11.                 System.out.println("(\"i\" for inputting from keyboard or another key for default):");
  12.       BufferedReader In = new BufferedReader(new InputStreamReader(System.in));
  13.       String inputText;
  14.                 try
  15.                 {
  16.                         inputText = In.readLine();
  17.                 } catch (IOException IOE)
  18.                 {
  19.                         System.out.println(IOE.toString());
  20.                         return;
  21.                 }      
  22.       SparseList[] a;
  23.       SparseMatrix A;
  24.       
  25.       if (inputText.equals("i"))
  26.       {       
  27.               int row, column, num;
  28.                         try
  29.                         {
  30.                                 System.out.print("Input the rows of the SparseMatrix A: ");
  31.                                 row = Integer.parseInt(In.readLine());
  32.                                 System.out.print("Input the columns of the SparseMatrix A: ");
  33.                                 column = Integer.parseInt(In.readLine());
  34.                                 System.out.print("Input the number of elements in SparseMatrix A: ");
  35.                                 num = Integer.parseInt(In.readLine());
  36.                         } catch (IOException IOE)
  37.                         {
  38.                                 System.out.println(IOE.toString());
  39.                                 System.out.println("Unable to get the integer data.");
  40.                                 return;
  41.                         }
  42.               A = new SparseMatrix(row, column);
  43.               a = new SparseList[num];
  44.               for (int i = 0; i < num; i++)
  45.               {       
  46.                       System.out.println("The element " + i + ":");
  47.                       a[i] = new SparseList();
  48.                       int row_num, column_num;
  49.                                 try
  50.                                 {
  51.                                         System.out.print("Input the row:");
  52.                                         row_num = Integer.parseInt(In.readLine());
  53.                                         System.out.print("Input the column:");
  54.                                         column_num = Integer.parseInt(In.readLine());
  55.                                 } catch (IOException IOE)
  56.                                 {
  57.                                         System.out.println(IOE.toString());
  58.                                         System.out.println("Unable to get the integer data.");
  59.                                         return;
  60.                                 }
  61.                       a[i].setRow(row_num);
  62.                       a[i].setColumn(column_num);
  63.                       System.out.print("Input the value:");
  64.                       float value;
  65.                                 try
  66.                                 {
  67.                                         value = Float.parseFloat(In.readLine());
  68.                                 } catch (IOException IOE)
  69.                                 {
  70.                                         System.out.println(IOE.toString());
  71.                                         System.out.println("Unable to get the double data.");
  72.                                         return;
  73.                                 }
  74.                               a[i].setValue(value);
  75.                      }
  76.       } else
  77.       {
  78.               a = new SparseList[3];
  79.        
  80.               a[0] = new SparseList();
  81.               a[0].setRow(4);
  82.               a[0].setColumn(6);
  83.               a[0].setValue(4.0f);
  84.        
  85.               a[1] = new SparseList();
  86.               a[1].setRow(5);
  87.               a[1].setColumn(3);
  88.               a[1].setValue(6.0f);
  89.        
  90.               a[2] = new SparseList();
  91.               a[2].setRow(9);
  92.               a[2].setColumn(5);
  93.               a[2].setValue(7.0f);
  94.        
  95.               A = new SparseMatrix(10,15);
  96.            }

  97.       A.setMatrix(a);
  98.       
  99.       System.out.println("Matrix A:");
  100.       A.displayMatrix();
  101.       
  102.       System.out.println("k * Matrix A:");
  103.       A.scale(5.2f).displayMatrix();
  104.       
  105.       System.out.print("norm |A| = ");
  106.       System.out.println(A.norm() + "\n");
  107.       
  108.       // create SparseMatrix B
  109.                 System.out.print("Input the command ");
  110.                 System.out.println("(\"i\" for inputting from keyboard or another key for default):");
  111.                 try
  112.                 {
  113.                         inputText = In.readLine();
  114.                 } catch (IOException IOE)
  115.                 {
  116.                         System.out.println(IOE.toString());
  117.                         return;
  118.                 }
  119.       SparseList[] b;
  120.       SparseMatrix B;
  121.       
  122.       if (inputText.equals("i"))
  123.       {       
  124.               int row, column, num;
  125.                         try
  126.                         {
  127.                                 System.out.print("Input the rows of the SparseMatrix B: ");
  128.                                 row = Integer.parseInt(In.readLine());
  129.                                 System.out.print("Input the columns of the SparseMatrix B: ");
  130.                                 column = Integer.parseInt(In.readLine());
  131.                                 System.out.print("Input the number of elements in SparseMatrix B: ");
  132.                                 num = Integer.parseInt(In.readLine());
  133.                         } catch (IOException IOE)
  134.                         {
  135.                                 System.out.println(IOE.toString());
  136.                                 System.out.println("Unable to get the integer data.");
  137.                                 return;
  138.                         }
  139.               B = new SparseMatrix(row, column);
  140.               b = new SparseList[num];
  141.               for (int i = 0; i < num; i++)
  142.               {       
  143.                       System.out.println("The element " + i + ":");
  144.                       b[i] = new SparseList();
  145.                       int row_num, column_num;
  146.                                 try
  147.                                 {
  148.                                         System.out.print("Input the row:");
  149.                                         row_num = Integer.parseInt(In.readLine());
  150.                                         System.out.print("Input the column:");
  151.                                         column_num = Integer.parseInt(In.readLine());
  152.                                 } catch (IOException IOE)
  153.                                 {
  154.                                         System.out.println(IOE.toString());
  155.                                         System.out.println("Unable to get the integer data.");
  156.                                         return;
  157.                                 }
  158.                       b[i].setRow(row_num);
  159.                                 b[i].setColumn(column_num);
  160.                       System.out.print("Input the value:");
  161.                       float value;
  162.                                 try
  163.                                 {
  164.                                         value = Float.parseFloat(In.readLine());
  165.                                 } catch (IOException IOE)
  166.                                 {
  167.                                         System.out.println(IOE.toString());
  168.                                         System.out.println("Unable to get the double data.");
  169.                                         return;
  170.                                 }
  171.                               b[i].setValue(value);
  172.                      }
  173.       } else
  174.       {
  175.               b = new SparseList[4];
  176.        
  177.               b[0] = new SparseList();
  178.               b[0].setRow(3);
  179.               b[0].setColumn(7);
  180.               b[0].setValue(14.45f);
  181.        
  182.               b[1] = new SparseList();
  183.               b[1].setRow(5);
  184.               b[1].setColumn(3);
  185.               b[1].setValue(76.23f);
  186.        
  187.               b[2] = new SparseList();
  188.               b[2].setRow(3);
  189.               b[2].setColumn(5);
  190.               b[2].setValue(5.0f);
  191.              
  192.               b[3] = new SparseList();
  193.               b[3].setRow(6);
  194.               b[3].setColumn(5);
  195.               b[3].setValue(0.34f);
  196.              
  197.               B = new SparseMatrix(10,15);
  198.                 }

  199.       B.setMatrix(b);
  200.       
  201.       System.out.println("Matrix B:");
  202.       B.displayMatrix();
  203.       
  204.       System.out.print("norm |B| = ");
  205.       System.out.println(B.norm() + "\n");
  206.       
  207.       System.out.println("Matrix (A + B):");
  208.       if (A.add(B) != null)
  209.               A.add(B).displayMatrix();
  210.       else
  211.               System.out.println("null\n");
  212.    }
  213. }
复制代码

论坛徽章:
0
4 [报告]
发表于 2003-08-07 16:03 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现

欢迎常来讨论哦

论坛徽章:
0
5 [报告]
发表于 2003-08-07 21:37 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现

那如果不用链表呢
也就是查找时直接查找它的下标

因为链表的左指针与右指针不知道有没有用

论坛徽章:
0
6 [报告]
发表于 2003-08-08 00:07 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现

原帖由 "无双" 发表:
那如果不用链表呢
也就是查找时直接查找它的下标

因为链表的左指针与右指针不知道有没有用
   

无双老大,没懂你的意思。不用链表?费内存啊。

论坛徽章:
0
7 [报告]
发表于 2003-08-08 13:29 |只看该作者

稀疏矩阵(Sparse Matrix)的java实现


看错

我原来意思就是创建成一个数组形式

每个数组元素里面都有行号列号值

只是如果这样的话添加新元素不方便
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP