2012-09-14 41 views
2

對於工作計劃應用程序,我需要爲w周(= 7w天)生成大量可能的員工計劃。員工時間表包含計劃期間每天的班次列表(早,晚,晚,休息日)。該應用程序使用Java進行編程。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; 
} 

我也有在一些移性質枚舉聲明和方法來比較屬性,但我不認爲這是相關的。

每一個員工都有他可能日程表的列表:

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對象列表也更好。但是,那麼不可能在計劃附近的某處保存計劃屬性(例如成本),並且他們需要經常重新計算。我認爲這將是一個嚴重的缺點。

這樣的觀察確實有意義嗎?或者您認爲有更好的方式來表達大量的數據以便使用更少的空間嗎?

+1

您是否需要將所有生成的計劃同時保留在內存中?你在跟他們做什麼?是不可能一個接一個地產生和處理它們(並忘記前一個)? – Thilo

+0

這是'[作業]'嗎? –

+0

時間表是根據個人喜好爲單個員工創建的。使用列生成迭代地將選擇的時間表添加到線性程序中。 LP試圖爲每個員工選擇一個名冊,以滿足員工的需求。因此,我需要記憶中的所有時間表。 – user1671257

回答

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

} 
+0

看起來像一個有效的想法!這隻使用2位而不是char使用的16位。非常感謝,我會調查這種方法。 :-) – user1671257

0

如果您想減少內存,您需要確定當前使用最多內存的內容以及您可能會對該數據類型做出哪些假設以使其更小。沒有這些信息,你只會猜測。


我建議你使用基於通用算法的方法。

例如;

  • 您只能生成1000個時間表並對它們進行評分。

  • 世界500強,你保持

  • 使用這些混合在一起,用一些隨機突變產生下一個1000。

直到您的最佳分數沒有提高。

重點是;您可以使用另一種方法在更短的時間內生成更少的時間表,但仍能收斂到最佳解決方案。在類似的「小」項目

+0

謝謝,但這種調度方法經常被研究。我目前正在研究另一種方法,我需要更多的時間表。我知道我可以通過各種方式減少時間表的數量,但對於我的方法,我想保持更多的記憶。生成時間表的方式不在我的問題範圍之內。我想知道的是如果使用char數組而更少的Schedule對象提供更好的性能。 – user1671257

+0

答案可能是這樣,但是直到你使用內存分析器才能說出來。 –

+0

好的,謝謝你的幫助! – user1671257

0

的經歷:

在文件系統中使用嵌入式數據庫存儲也,是明智的。儘管SQL很醜陋,但它比手動編碼集合散步更容易查詢;並且更容易維護。

因爲內存消耗的問題是沒有意義的。

如果您想要,您可以使用JPA,例如帶ORM的eclipseLink。