Java:代表大量数据数组

时间:2012-09-14 12:06:10

标签: java arrays memory enums

对于工作安排应用程序,我需要为w周(= 7天)生成许多可能的员工日程安排。员工日程安排包括计划期间每天的班次(早,晚,晚,休日)列表。该应用程序使用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
}

Shift是表示指定班次的枚举,定义为:

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

我在枚举声明和比较属性的方法中也有一些移位属性,但我不认为这是相关的。

每位员工都有他可能的时间表清单:

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名员工的生成时,我的记忆力已经满了。

有人给我的建议是使用一组字符来表示指定的移位而不是枚举数组。这将占用更少的空间。 此外,他表示使用char数组列表而不是Schedule对象列表也更好。但是,然后无法在计划附近的某处保存计划属性(例如成本),并且需要经常重新计算。我认为这将是一个严重的缺点。

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

3 个答案:

答案 0 :(得分:0)

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


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

例如;

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

  • 前500名,你保持

  • 使用这些混合在一起产生接下来的1000个随机突变。

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

重点是;您可以使用另一种方法在更短的时间内生成更少的计划,但仍然可以收敛到最佳解决方案。

答案 1 :(得分:0)

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

建议在文件系统中使用嵌入式数据库。虽然SQL很丑陋,但它允许比手动编码的收集步骤更好的查询;并且更容易维护。

因此,内存消耗问题没有实际意义。

如果您愿意,可以使用JPA,例如使用ORM的eclipseLink。

答案 2 :(得分:0)

如果你真的需要同时在内存中的所有日程安排,那么最节省空间的编码就是每天使用2比特的BitSet。

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];
  }

}