0

私は、遺伝的アルゴリズムを使用して最終年度のプロジェクトを行い、大学の一連の九九を設計しています。

私は前進するのを妨げている1つのエラーに遭遇しています。次のエラーが発生します。

 Exception in thread "main" java.lang.NullPointerException
at LunchTimeFree.calculateViolations(LunchTimeFree.java:36)
at FitnessFunction.calculateFitnesScore(FitnessFunction.java:34)
at Main.main(Main.java:19)

しかし、これは私には意味がありません。その行には、次のコード行があります。

    int time = c.genes[i].time;

可変時間を染色体内の特定の遺伝子の時間値に設定します。時間変数とc.genes[i].time変数を出力した後、デバッグしてprintlnステートメントを挿入しました。これらは両方とも変数に初期化されます。つまり、time=1または2などです。

何が問題なのかわかりません。誰か助けてくれませんか?

public class LunchTimeFree extends constraintInterface {

    Chromosome c;

    public LunchTimeFree(Chromosome chromo){
        c = chromo;
    }

    @Override
    public double calculateViolations() {     
    double violations=0;    

    int i = 0; 
    int y = c.getLength();

    while(i <= y-1 )
    {
        int time = c.genes[i].time;

        if (time >= 16 && time <= 25)   {                           
            violations = violations + 1;        
                            } 
                i++;
    }      

    return violations*this.weight;

    }
}

public class ChromosomeFactory
{

Chromosome c;

 public ChromosomeFactory(int l)
 {

 c = new Chromosome(l);

 DummyDatabase da = new DummyDatabase();

 int numOfLectures = da.GetNumLectures();

  int i=0;

  while(i<=numOfLectures-1)
   {

   int lecture = da.getLecture(i);   

   int r = da.Rooms[(int)(Math.random() * da.Rooms.length)];
   int t = da.TimeSlots[(int)(Math.random() * da.TimeSlots.length)]; 

   Gene g = new Gene(lecture,lecture,r,t);

    c.genes[i] = g;
           System.out.println(""+this.c.genes[i].teacher+","+this.c.genes[i].lecture+","+this.c.genes[i].room+","+this.c.genes[i].time+"");
    i++;
    }
   }  
   }

 public class FitnessFunction 
{
Chromosome c;

public FitnessFunction(Chromosome newChromo)  {
    c = newChromo;
}

public double calculateFitnesScore() {

    LunchTimeFree ltf = new LunchTimeFree(c);

    ltf.setWeight(0.01);

    double violationScore =ltf.calculateViolations();

    double score = (1/(1 + violationScore));

    return score;

  } 

 public class Chromosome 
 {

Gene[] genes;



public Chromosome(int l)
{
genes = new Gene[l]; 

}

public int getLength()
{
return genes.length;
}



}

public class Gene 
{
public int teacher;
public int lecture;
public int room;
public int time;


public Gene(int t,int l, int r, int time)
{

this.teacher=t;    
this.lecture=l;
this.room=r;
this.time=time;

}



}

public class DummyDatabase implements DatabaseAccessor
{

 int[] Lecturers = { 1,2,3,4,5,6,7,8,9 };
  int[] Lectures = { 1,2,3,4,5,6,7,8,10,11,12,13,14,15,16,17,18,19} ;

  int[] TimeSlots =      {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55};

    int[] Rooms = {1,2,3,4,5,6,7,8,9,10};





@Override
public int GetRoom(int entry) {

    return this.Rooms[entry];
}

@Override
public int GetNumLectures() {
    return this.Lectures.length;
}

@Override
public int getTeacher(int entry) {
    return this.Lecturers[entry];
}

@Override
public int getLecture(int entry) {
    return this.Lectures[entry];
}

@Override
public int getNumRooms() {
    return this.Rooms.length;
}

}

4

2 に答える 2

2

の値のいずれかcまたは1つc.genes[i]がnullです。

操作を実行しようとしているか、nullのプロパティを要求しようとしています。だからあなたはを取得していNullPointerExceptionます。Eclipseまたは選択した他のIDEを使用している場合は、それをデバッグしてnullを確認するか、関連するコードを投稿して推測することができます。たぶんあなたのループにi欠陥があります。

于 2012-11-10T21:22:03.130 に答える
0

まず第一に:分割

int time = c.genes[i].time;

の中へ

final Gene[] allGenes = c.genes;
final Gene aGene = allGenes[i];
final int time = aGene.time;

スタックトレースでどの参照がnullであるかを正確に示す必要があります。これは、バグの場所を絞り込むのに役立つ場合があります。

それを除けば、おそらく長い電話ですが、投稿されたコードの他のすべては大丈夫に見えます:

Chromosomeクラスでは、配列getLengthの長さを返しますか?genesまたは、アレイ内の設定された遺伝子の数?遺伝子配列が完全に満たされておらずgetLength、満たされた配列スロットの(誤った)数を示している場合、whileループがオーバーシュートし、配列内でnullに達する可能性があります。lChromosomeFactoryでChromosomeのコンストラクター引数としてint変数を使用しますが、遺伝子配列を。まで入力することに注意してくださいnumOfLecturesl染色体の遺伝子配列のサイズを設定するために使用され、l異なるnumOfLectures場合は、問題が発生する可能性があります。差は配列内のnullで埋められます。

int y = c.getLength();
while(i <= y-1 )
{
    int time = c.genes[i].time;
    if (time >= 16 && time <= 25)   {                           
        violations = violations + 1;        
    } 
    i++;
}

また、これを次のようなforループに置き換えることも検討してください。

for (int i = 0; i < c.getLength(); i++) {
   int time = c.genes[i].time;
   if (time >= 16 && time <= 25) {                           
      violations++;   
   }
}

forループは、ループ変数の範囲を最小限に抑え、ループ変数の増加を処理し、把握しやすいため、優先する必要があります。また、配列の代わりにコレクションクラスの1つを使用することを検討してください。また、すべてのインスタンス変数をゲッター/セッターを使用してプライベートな可視性に変更することを強く検討してください。

それが理由でない場合は、Chromosonクラスや遺伝子配列の構造など、より多くのコードを表示する必要があります。

于 2012-11-10T23:02:47.653 に答える