在Java中表示上三角矩阵的最佳数据结构是什么?

在Java中表示上三角矩阵的最佳数据结构是什么?,java,sparse-matrix,Java,Sparse Matrix,假设给出了一个整数的上三角矩阵。在Java中存储这些信息的最佳方式是什么?简单的2d int数组显然效率不高。我提出的解决方案被移到了答案部分。如果矩阵总是对角的,我会使用: List<List<Integer>> matrix = ... 列表矩阵=。。。 如果是稀疏矩阵,我会使用贴图: Map<Map<Integer>> = ... Map=。。。 在第二种情况下,您可能需要使用get和set操作将映射包装到一个类中,以便管理对新行和新

假设给出了一个整数的上三角矩阵。在Java中存储这些信息的最佳方式是什么?简单的2d int数组显然效率不高。我提出的解决方案被移到了答案部分。

如果矩阵总是对角的,我会使用:

List<List<Integer>> matrix = ...
列表矩阵=。。。
如果是稀疏矩阵,我会使用贴图:

Map<Map<Integer>> = ...
Map=。。。
在第二种情况下,您可能需要使用get和set操作将映射包装到一个类中,以便管理对新行和新列的访问


然而,所有这些都取决于你的需要、你的记忆限制和矩阵大小。

番石榴怎么样?它是使用HashMaps或TreeMap(以及2D数组,如果需要的话)实现的,但是它提供了比定义
映射更好的API。如果你想节省内存,你的解决方案看起来很棒——它被称为。逐列,自上而下,您的数组将如下所示:
1 2 6 3 7 8 4 1 9 5

我建议根据求和公式
(n²+n)/2
(行和列均以零为基础)对指数进行更简单的计算

实现可能如下所示:

public class TriangularMatrix {
    private final int[] list;

    public TriangularMatrix(int size) {
        list = new int[sumFormula(size)];
    }

    public int set(int row, int column, int value) {
        validateArguments(row, column);

        int listIndex = getListIndex(row, column);
        int oldValue = list[listIndex];
        list[listIndex] = value;

        return oldValue;
    }

    public int get(int row, int column) {
        validateArguments(row, column);

        return list[getListIndex(row, column)];
    }

    private void validateArguments(int row, int column) {
        if (row > column) {
            throw new IllegalArgumentException("Row (" + row + " given) has to be smaller or equal than column (" + column + " given)!");
        }
    }

    private int getListIndex(int row, int column) {
        return sumFormula(column) + row;
    }

    private int sumFormula(int i) {
        return (i*i + i) / 2;
    }
}

虽然是关于Fortran的,但仍在讨论(负面)性能影响。

我想我找到了解决方案。这里是我的解决方案:假设你有一个4X4的上三角矩阵M

1 2 3 4
0 6 7 1
0 0 8 9
0 0 0 5
如果你能在一维数组中映射M的每个元素,那是最好的解决方案。您只需知道矩阵的哪个[行,列]对应于1d数组的哪个元素。以下是您如何使用魔法:

start_index=((col_index-1)+1)+((col_index-2)+1)+...+1
end_index=start_index + col_index
例如:如果我想找到矩阵第3列的元素在数组中的位置:

start_index=((3-1)+1)+((3-2)+1)+((3-3)+1)=6
end_index=6+3=9

所以,我需要做的就是从数组的索引6开始,读取所有元素直到索引9(包括第9个元素)。按照这个过程,您可以在(n+n^2)/2空间中存储和检索nXn矩阵的所有单元格。

我找到了另一个解决方案。请看一看,让我知道你的想法。@user3639557如果你的矩阵总是三角形的,那么你的解决方案是正确的,在内存使用方面是最优的。我建议您使用accesors方法实现它的包装类,该方法基于(I行,j列)索引提供对其元素的直接访问。请看一看,让我知道你的想法。@user3639557我更改了我的答案以匹配你的问题-我的第一个版本对三角矩阵根本没有效率。“最佳”是哪种方式?灵活性使用现有的矩阵库之一。演出使用普通1D数组。(如果性能非常关键,矩阵是“小”的,您甚至可以考虑创建一个(RoSQL)数组,并将它的左下角留空。在任何情况下,我都不会使用不打算用作矩阵的类(如“表”),也不会使用嵌套数据结构(如列表中的列表)。还要注意的是,对于最后一点性能(即使在使用数组时),*访问模式也是至关重要的,无论您使用行主存储还是列主存储,您都可以回答自己的问题:将您的解决方案移动到一个答案(在本页的“您的答案”框中键入)。@PeterO。谢谢只是把它移到了答案部分。
start_index=((3-1)+1)+((3-2)+1)+((3-3)+1)=6
end_index=6+3=9