1

I have this code : indexOfChromosomes : 48 indexOfGens : 20 double Truncation; double Crossover; double Mutation; int Generation;

private Context context;

int indexOfChromosomes;
int indexOfGens;
int gensNumber;
int chromosomesNumber;

public AdapterDB(int Bits, double Truncation, double Crossover, double Mutation, int Chromosomes, int Generation, Context ctx)
{
    this.indexOfGens = Bits;
    this.Truncation = Truncation;
    this.Crossover = Crossover;
    this.Mutation = Mutation;
    this.indexOfChromosomes = Chromosomes;
    this.Generation = Generation;
    this.context = ctx;
    DBHelper = new DatabaseHelper (context);
}

String [][] population = new String[indexOfChromosomes][indexOfGens];

    public void generateChromosome()
{       
    for(chromosomesNumber = 0; chromosomesNumber < indexOfChromosomes ; chromosomesNumber++)
    {
                    int o = 0;
        for(gensNumber = 0; gensNumber < 12 ; gensNumber++)
        {
            Cursor l = db.rawQuery("SELECT _id, key_foodstuff, key_calorie, key_carbohydrate, key_fat, key_protein FROM (food INNER JOIN categories ON food.key_nocategory = categories.nocategories) WHERE key_type='primary' AND _id!=164 AND (key_carbohydrate!=0 OR key_protein!=0 OR key_fat!=0) ORDER BY RANDOM() LIMIT 1", null);

            if((l.moveToFirst()) && (l!=null))
            {   
                if (o == indexOfGens)
                {
                    gensNumber = 0;
                    sumOfCarbohydrateMor = 0;
                    sumOfFatMor = 0;
                    sumOfProteinMor = 0;
                    sumOfCalorieMor = 0;
                    o = 0;
                }

                population[chromosomesNumber][gensNumber] = l.getString(0);
                morning_food[k] = l.getString(3);
                sumOfCarbohydrateMor = sumOfCarbohydrateMor + Double.parseDouble(morning_food[k]);  
                morning_food[f] = l.getString(4);
                sumOfFatMor = sumOfFatMor + Double.parseDouble(morning_food[f]);
                morning_food[p] = l.getString(5);   
                sumOfProteinMor = sumOfProteinMor + Double.parseDouble(morning_food[p]);
                morning_food[c] = l.getString(2);   
                sumOfCalorieMor = sumOfCalorieMor + Double.parseDouble(morning_food[c]);
                if (((sumOfCarbohydrateMor >= (morning_car-(morning_car*0.2))) && (sumOfCarbohydrateMor <= morning_cal*1.1)) && ((sumOfProteinMor >= (morning_pro-(morning_pro*0.2))) && (sumOfProteinMor <= morning_pro*1.1)) && ((sumOfFatMor >= (morning_fat-(morning_fat*0.2))) && (sumOfFatMor <= morning_fat*1.1)))
                //if((sumOfCarbohydrateMor > (morning_car*0.6)) && (sumOfProteinMor > (morning_pro*0.7)) && (sumOfFatMor > (morning_fat*0.8)))
                {
                    Log.e("lala", "lalala");
                    break;
                }

                if ((sumOfCarbohydrateMor > (morning_car*1.1)) || (sumOfProteinMor > (morning_pro*1.1)) || (sumOfFatMor > (morning_fat*1.1)) || (sumOfCalorieMor > (morning_cal*1.1))
                {

                    morning_food[k] = l.getString(3);
                    sumOfCarbohydrateMor = sumOfCarbohydrateMor - Double.parseDouble(morning_food[k]);
                    morning_food[f] = l.getString(4);
                    sumOfFatMor = sumOfFatMor - Double.parseDouble(morning_food[f]);
                    morning_food[p] = l.getString(5);
                    sumOfProteinMor = sumOfProteinMor - Double.parseDouble(morning_food[p]);
                    morning_food[c] = l.getString(2);
                    sumOfCalorieMor = sumOfCalorieMor - Double.parseDouble(morning_food[c]);
                    gensNumber--;
                    o++;

                }   

            }
        }

and it error in line : 48

The error says that : java.lang.ArrayIndexOutOfBoundsException

any idea? Thx u

6
  • Are you sure they are in fact 48 and 20? Have you done any debugging? Commented Nov 17, 2011 at 6:16
  • Yes I am sure, I have already display it on LogCat Commented Nov 17, 2011 at 6:20
  • insufficient info . what values you are giving to constructor ? Commented Nov 17, 2011 at 6:21
  • @Michelle for future reference post your code here on SO, not on external sites. Commented Nov 17, 2011 at 6:22
  • int Bits = 48, double Truncation = 0.5, double Crossover = 0.5, double Mutation = 0.01, int Chromosomes = 20, int Generation = 100 Commented Nov 17, 2011 at 6:23

3 Answers 3

1

Try setting

population = new String[indexOfChromosomes][indexOfGens];

inside your adapterDB.

It looks like when you are initializing populatioin, indexOfChromosomes and indexOfGens are not initialized yet, so you are creating an array of size 0. So when you call

population[chromosomesNumber][gensNumber] 

you get java.lang.ArrayIndexOutOfBoundsException

Sign up to request clarification or add additional context in comments.

4 Comments

you have a gensNumber--; inside your if. Maybe that is causing the problem and not letting you out of the for loop
but I have this condition too : if (((sumOfCarbohydrateMor >= (morning_car-(morning_car*0.2))) && (sumOfCarbohydrateMor <= morning_cal*1.1)) && ((sumOfProteinMor >= (morning_pro-(morning_pro*0.2))) && (sumOfProteinMor <= morning_pro*1.1)) && ((sumOfFatMor >= (morning_fat-(morning_fat*0.2))) && (sumOfFatMor <= morning_fat*1.1))) { Log.e("lala", "lalala"); break; } why it is not read it >_<
Maybe the conditions for your other loop are always met. Just give it a try and remove that line of code (gensNumber--) and see what happens. If that solves it you have to look very carefully to those conditions. Sadly I can't help you with that part, but I recommend you use Eclipse's debug tool to check the values of your variables everytime you loop through those ifs
You welcome. Remember to mark your question as solved if you fixed the problem :)
1

It's because you define the population string outside a function, without initializing the indexOfChromosomes to 48 and the indexOfGens to 20. Try defining the population at the top and setting it to something new in the adapter, AFTER you've set your variables. Something like this:

double Truncation;
double Crossover;
double Mutation;
int Generation;

private Context context;

int indexOfChromosomes;
int indexOfGens;
int gensNumber;
int chromosomesNumber;

String [][] population;

public AdapterDB(int Bits, double Truncation, double Crossover, double Mutation, int Chromosomes, int Generation, Context ctx)
{
    this.indexOfGens = Bits;
    this.Truncation = Truncation;
    this.Crossover = Crossover;
    this.Mutation = Mutation;
    this.indexOfChromosomes = Chromosomes;
    this.Generation = Generation;
    this.context = ctx;
    DBHelper = new DatabaseHelper (context);

    //Create population after initializing variables.
    population = new String[indexOfChromosomes][indexOfGens];
}   

Comments

1

This is your problem:

String [][] population = new String[indexOfChromosomes][indexOfGens];

This occurs outside your constructor, and is therefore executed before your constructor, when indexOfChromosomes and indexOfGens are both still 0. Put the initialization inside your constructor. Here's a simpler example showing the same problem:

public class Test {
    private int size;

    public Test(int size) {
        this.size = size;
    }

    private String[] array = new String[size];

    public static void main(String[] args) {
        Test t = new Test(5);
        System.out.println(t.array.length);
    }
}

And the fixed version:

public class Test {
    private int size;
    private String[] array;

    public Test(int size) {
        this.size = size;
        array = new String[size];
    }


    public static void main(String[] args) {
        Test t = new Test(5);
        System.out.println(t.array.length);
    }
}

Note that the positioning of the variable declaration with respect to the constructor makes no difference to the execution flow.

EDIT: As for why it's now looping forever - in the middle of your code you have:

if (o == indexOfGens)
{
    gensNumber = 0;
    ...
}

which will reset the inner loop back to (nearly) the start (not quite the start, as gensNumber will be incremented at the end of the loop body, before the start of the next iteration).

It's not at all clear what you're trying to do, but I suspect that's not helping.

I'd also encourage you to use local variables wherever possible - it's very unusual to use an instance variable as a loop counter, for example.

Finally, I'd encourage you to break up your large method into smaller ones for readability.

2 Comments

@Michelle: That suggests you've got more than one bug in your code :) I suggest you look carefully - I only tried to address the first problem you raised...
Hoo Thx u, I have already tried this for a day >_< and I confused what should I do, last time I have tried to put String [][] population = new String[indexOfChromosomes][indexOfGens]; on generateChromosomes(), it works too but looping forever too. Anyway Thx a lot =D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.