2016-04-10 4 views
0

Ich versuche, eine genetische Algorithmus Implementierung für meine These zu machen. Es gibt zwei Hauptklassen: Facility als Chromosom und FacilityCell als Gen. Aber ich bekomme einen Fehler, wenn ich den Fitnesswert von Facility Klasse bekomme.Warum bekomme ich NullReferenceException, wenn versucht wurde, einen Wert für das Eigenschaftsfeld festzulegen?

Die erforderlichen Werte werden in der Form.cs gesetzt und nach dem Algorithmus ausgeführt wurde, sind diese Eigenschaften null in der Facility Instanz. Diese Eigenschaften sind Facility.Flows und Facility.Demands. Ich kann nicht verstehen warum. Bitte helfen Sie.

-Code Teil von Form.cs

fac = new Facility(); 
List<FacilityCell> gens = new List<FacilityCell>(); 
for (int i = 0; i < 6; i++) 
{ 
    gens.Add(new FacilityCell(i.ToString(), i)); 
} 

fac.Genes = gens.ToArray(); 
fac.Cells = gens.ToArray(); 

float[] dems = new float[3]; 
dems[0] = 300; 
dems[1] = 60; 
dems[2] = 160; 
fac.Demands = dems; 

FacilityCell[][] fl = new FacilityCell[3][]; 
fl[0] = new FacilityCell[] { 
    fac.Cells[0], 
    fac.Cells[2], 
    fac.Cells[4], 
    fac.Cells[1], 
    fac.Cells[3], 
    fac.Cells[5] }; 
fl[1] = new FacilityCell[] { 
    fac.Cells[2], 
    fac.Cells[4], 
    fac.Cells[1], 
    fac.Cells[5], 
    fac.Cells[3], 
    fac.Cells[4] }; 
fl[2] = new FacilityCell[] { 
    fac.Cells[1], 
    fac.Cells[0], 
    fac.Cells[4], 
    fac.Cells[2], 
    fac.Cells[3], 
    fac.Cells[5] }; 
fac.Flows = fl; 

-Code von Facility.cs:

public class Facility : IChromosome 
{ 
    public Facility() 
    { 

    } 
    public Facility(FacilityCell[] cells) 
    { 
     this.cells = cells; 
     flows = null; 
     demands = null; 
     for (int i = 0; i < cells.Length; i++) 
     { 
      cells[i].Order = i; 
     } 
    } 

    private IGene[] cells; 
    private float[] demands; 
    private FacilityCell[][] flows; 

    public FacilityCell[][] Flows 
    { 
     get { return flows; } 
     set { flows = value; } 
    } 
    public FacilityCell[] Cells 
    { 
     get 
     { 
      return cells as FacilityCell[]; 
     } 
     set 
     { 
      cells = value; 
     } 
    } 

    public float[] Demands 
    { 
     get { return demands; } 
     set { demands = value; } 
    } 

    public float FitValue 
    { 
     get 
     { 
      float total = 0; 

      //I AM GETTING ERROR IN THIS LINE OF CODE, THE FOR LOOP 
      //It throws NullReferenceException for both this.Demands and this.Flows 

      for (int i = 0; i < flows.Length; i++) 
      { 
       for (int j = 0; j < flows[i].Length - 1; j++) 
       { 
        int dist = Math.Abs(flows[i][j + 1].Order - flows[i][j].Order); 
        float totflow = dist * demands[i]; 
        total += totflow; 
       } 
      } 
      return total; 
     } 
    } 

    public IGene[] Genes 
    { 
     get 
     { 
      return cells; 
     } 
     set 
     { 
      cells = value; 
     } 
    } 
} 
+0

Haben Sie darüber nachgedacht, Mitglieder vor der Verwendung zu initialisieren? In OOP versuchen wir Konstruktoren zu schreiben, die die Klasseninstanz in einem verwendbaren Zustand initialisieren. Die Hälfte der Initialisierung an zufälligen Stellen außerhalb des Konstruktors zu verbergen, ist eine schlechte Idee, wie Sie sehen können. Das eine Bit Code, das immer ausgeführt wird, wenn Sie eine Instanz erstellen, ist ein Konstruktor. Keep It Simple: Initialisiere es im Konstruktor, und du kannst dich auf den 'new'-Operator verlassen, der dir etwas gibt, das nicht explodiert. –

Antwort

1

Dieser Code: FacilityCell[][] fl = new FacilityCell[3][]; wird im Konstruktor gesetzt demands auf null, rufen Sie ths Code, nachdem Sie die demands eingestellt.

Verwandte Themen