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;
}
}
}
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. –