当前位置: 首页 > 知识库问答 >
问题:

Java:表示大量数据数组

梁兴文
2023-03-14

对于工作计划应用程序,我需要为w周(=7w天)生成许多可能的员工计划。员工时间表由计划期内每天的班次(早班、晚班、夜班、Rest日)列表组成。应用程序是用Java编程的。

此时,我代表员工时间表如下:

public class Schedule
{
    /** List with for every day of planning period the assigned shift */
    private Shift[] shiftlist = new Shift[Settings.schedule_days];

    /** Cost of schedule (for measuring its quality) */
    private double cost;

    // A list of variables, representing schedule properties
    // which are referenced often.
    // E.g.: number of workweekends, number of night shifts

    // Also some methods for updating / retrieving information
}

移位是表示分配移位的枚举,定义为:

public enum Shift
{
    DAY, LATE, NIGHT, FREE;
}

我在枚举声明和方法中也有一些shift属性来比较属性,但我认为这与此无关。

每个员工都有一份他可能的时间表列表:

public class Employee
{
    /** Large set of possible schedules for planning period */
    public LinkedList<Schedule> generated_schedules;

    // Variables representing properties of employee
}

我的问题是,我实际上有50名员工,我想为每个员工生成100.000 -- 1.000.000可能的时间表。

时间表实际上生成得很快,因为我的电脑有8GB的可用内存,我可以存储很多。然而,当为30到40名员工完成生成后,我的记忆就满了。

有人给我的建议是使用字符数组来表示指定的移位,而不是枚举数组。这将占用更少的空间。此外,他表示,使用字符数组列表而不是调度对象列表也更好。但是,不可能将明细表属性(如成本)保存在明细表附近的某个位置,因此需要经常重新计算这些属性。我认为这将是一个严重的缺点。

这种观察确实有意义吗,或者你认为有更好的方法来表达这些大量的数据,以便使用更少的空间?

共有3个答案

仇航
2023-03-14

如果要减少内存,需要确定当前使用最多内存的是什么,以及可以对该数据类型做出哪些假设,从而使其更小。没有这些信息,你只能猜测。

我建议您使用基于通用算法的方法。

例如;

>

  • 您只能生成1000个时间表并对其进行评分。

    前500名,你继续

    将这些基因混合在一起,生成下一个1000个带有一些随机突变的基因。

    重复,直到你的最好成绩没有提高。

    关键是;您可以使用另一种方法在更短的时间内生成更少的时间表,但仍能收敛到最佳解决方案。

  • 子车高超
    2023-03-14

    类似“小”项目的一次经验:

    建议使用也存储在文件系统中的嵌入式数据库。尽管SQL很丑,但它允许比手动编码的集合遍历更好的查询;并且更容易维护。

    这样,内存消耗的问题就没有实际意义了。

    如果你愿意,你可以使用JPA,例如eclipseLink和ORM。

    壤驷喜
    2023-03-14

    如果您确实需要同时在内存中使用所有调度,那么最节省空间的编码将是使用每天2位的位集。

    public class BitSetShiftList {
      private BitSet bitset;
    
      public void BitSetShiftList(int size) {
        bitset = new BitSet(size * 2);
      }
    
      public void setShift(int day, Shift shift) {
        int ordinal = shift.ordinal();
        assert ordinal >= 0 && ordinal <= 3;
    
        bitset.set(day * 2, (ordinal & 0x1) != 0);
        bitset.set(day * 2 + 1, (ordinal & 0x2) != 0);
      }
    
      public Shift getShift(int day) {
        int ordinal = (bitset.get(day * 2) ? 0x1 : 0x0) |
          (bitset.get(day * 2 + 1) ? 0x2 : 0x0);
        return Shift.values()[ordinal];
      }
    
    }
    
     类似资料:
    • 问题内容: 我有一个Java应用程序,它需要显示大量数据(大约一百万个数据点)。数据并不需要全部同时显示,而仅在用户请求时才显示。该应用程序是桌面应用程序,未与应用程序服务器一起运行或未与任何集中式数据库连接。 我的想法是在计算机上运行数据库并在其中加载数据。在大多数时候,数据库都是只读的,因此我应该能够建立索引以帮助优化查询。如果我在本地系统上运行,则不确定是否应该尝试实现一些缓存(我不确定查询

    • 第 6 章 大量数据的表示和处理 第 2 章讨论了现实世界信息在计算机中的抽象表示问题,那里主要介绍的是简单数据, 而本章将继续介绍复杂数据的表示和处理。简单数据一般指单个数据,并且没有内部结构, 不可分割。复杂数据正相反,可在两方面呈现复杂性:一是数量多,即待处理的数据是由大 量相互关联的成员数据组成的;二是有内部结构,即数据在内部由若干分量组成,每个分量 本身可能又由更小的分量组成。对于大量数

    • 问题内容: 我有一个JList,必须显示3000多个项目。我希望列表中有100个左右的“可见”项,并且当您滚动并接近“可见”项的末尾(或开头)时,必须在列表中加载下一部分(约50个)。有没有简单的方法可以做到这一点? 问题答案: 不,没有简单的方法,您必须实现分页 由数据库引擎管理时最简单的工作,然后大多数直接支持分页 在模型中,但是我从未见过XxxListModel的解决方法,而是将JTable

    • 我创建了一个向MySql数据库插入数百万个值的程序。我读到过有关批插入的文章,它将优化我的程序并使其更快,但当我尝试这样做时,它以同样的方式工作。我没有将每个值插入数据库,而是每次将500个值保存在一个列表中,然后将它们插入一个大循环中,如下所示: 然后我删除列表中的所有值,并再次开始收集500个值。它不应该工作得更好吗? 我的插入代码是: 我有一些问题: 1。为什么当我批量插入时它不能更快地工作

    • 问题内容: 我只是尝试使用sklearn.decomposition中的IncrementalPCA,但它像以前的PCA和RandomizedPCA一样引发了MemoryError。我的问题是,我要加载的矩阵太大,无法放入RAM。现在,它以形状〜(1000000,1000)的数据集形式存储在hdf5数据库中,因此我有1.000.000.000 float32值。我以为IncrementalPCA可

    • 问题内容: 哪种数据类型倾向于代表十进制数字,例如“ 10364055.81”。 如果尝试使用double: 但是,当我尝试打印该数字时,它会显示为“ 1.036405581E7 ”,这是我不想要的。 我应该使用BigDecimal吗?但其显示为 10364055.81000000052154064178466796875 。是否有任何数据类型按原样显示值?同样,该数字可能大于示例中的数字。 顺便