2016-09-30 51 views
2

是否有經常更改的數據對象結構的設計模式?是否有經常更改的數據對象結構的設計模式?

我正在重構遺傳算法,其中染色體的結構(基因數量,基因類型和基因邊界)從問題變爲問題。例如:

一個問題可以使用

class Chromosome{ 
    double gene1; // 0.0 < gene1 < 100.0 
    double gene2; // -7.3 < gene2 < 9.0 
} 

另一個問題可能使用

class Chromosome{ 
    int gene1;  // 200 < gene1 < 1000 
    double gene2; // 50.0 < gene2 
    double gene3; // gene3 < -5.0 
} 

目前的染色體結構是硬編碼,是很難修改的一個新問題。我正在考慮修改染色體變化的策略模式,除非有人有更好的主意。

回答

0

如果染色體僅僅是基因對象的集合,它們會變得更容易處理,特別是如果邊界也被視爲對象。

public class Gene 
{ 
    public string Id { get; set; } 
    public double Value { get; set; } 
    public Boundary Boundary { get; set; } 
} 

public class Boundary 
{ 
    public double? Minimum { get; set; } 
    public double? Maximum { get; set; } 
} 

public class Chromosome 
{ 
    public string Name { get; set; } 
    public List<Gene> Genes { get; set; } 
} 

然後染色體的一個新實例,可以通過必要的基因列表提供它只是使...

var chromosome1 = new Chromosome 
    { 
     Name = "Biggie", 
     Genes = new List<Gene> 
       { 
        new Gene {Id = "1", Boundary = new Boundary {Minimum = 0, Maximum = 100}}, 
        new Gene {Id = "2", Boundary = new Boundary {Minimum = -7.3, Maximum = 9}} 
       } 
    }; 

var chromosome2 = new Chromosome 
     { 
      Name = "Fusion", 
      Genes = new List<Gene> 
      { 
       new Gene {Id = "1", Boundary = new Boundary {Minimum = 200, Maximum = 1000}}, 
       new Gene {Id = "2", Boundary = new Boundary {Minimum = 50}}, 
       new Gene {Id = "3", Boundary = new Boundary {Maximum = -5}} 
       } 
     }; 

由於所有的染色體現在具有相同的結構,它成爲使染色體創建數據驅動相對微不足道。染色體定義可以保存在配置文件或數據庫中,並根據需要添加新的。每個染色體對象可以通過一個簡單的循環來填充,該循環讀取它所包含的基因列表。

+0

此解決方案不起作用。基因價值的類型並不總是雙重的。它可以是double,integer,boolean或枚舉。同樣,如果有兩個基因,每個基因的價值可能有不同的類型。 –

+0

所有這些將適合一個雙。你也可以引入泛型,但它可能不值得付出努力。 – dbugger

+0

缺乏數學支持使得泛型的工作比值得。決定使用Double,最小值,最大值和增量值。我將在基因價值和它的解釋之間使用一個適配器。 –

0

感謝dbugger的幫助,我相信我有一個解決方案。爲了簡單起見,我放棄了ID和邊界。 IGene和Gene類是解決方案。 TestGene是一個測試實現。

public interface IGene<T>{ 
    //Accessors 
    public T   getValue(); 

    public void   setValue(T value); 
} 

public class Gene<T> implements IGene<T> { 
    //Attributes 
    T   _value; 

    //Accessors 
    public T   getValue(){ return this._value;} 

    public void   setValue(T value){ this._value = value; } 
} 

import java.util.ArrayList; 
import java.util.List; 

public class TestGene { 
    public enum EnumType {VALUE1, VALUE2} 

    public TestGene() { 
     IGene gene; 

     List<IGene> chromosome = new ArrayList(); 

     gene= new Gene<Double>(); 
     gene.setValue(1.08); 
     chromosome.add(gene); 

     gene = new Gene<Integer>(); 
     gene.setValue(3); 
     chromosome.add(gene); 

     gene = new Gene<EnumType>(); 
     gene.setValue(EnumType.VALUE1); 
     chromosome.add(gene); 

     for (int i = 0; i < chromosome.size(); i++){ 
      System.out.println(chromosome.get(i).getValue()); 
     } 
    }