1

I have an Android Studio project that optimises mobile resources using the swarm particle algorithm. I keep getting this error in my fitness function, my main activity never runs or shows me results because of this. This is my class that I keep getting problems on...

public class CustomService implements Goodness {


public static int numOfServices = MainActivity.servicenames.size();
public static final int NUM_DIMENSIONS = 1 + numOfServices;
public static HashMap<String, Integer> serviceMap = new HashMap<String, Integer>(); //hashmap to store values
ArrayList<String> serviceNames = MainActivity.servicenames;
ArrayList<Double> costData = MainActivity.costDATA;
ArrayList<Double> costWlan = MainActivity.costWLAN;
ArrayList<Double> costUtilities = MainActivity.costUTILITY;
double batteryCost;

public void setBatteryCost(double batteryCost) {
    this.batteryCost = batteryCost;
}

public CustomService(double batteryCost, ArrayList<Double> costData, ArrayList<Double> costWlan,
                     ArrayList<Double> costUtilities) {
    if (costUtilities == null || costUtilities.size() < 1 || costData.size() < 1 || costWlan.size() < 1) {
        throw new RuntimeException("Please add atleast 1 cost to Data, WLAN and Utility");
    }
    this.batteryCost = batteryCost; //make sure you add battery field to UI, user enters battery level
    this.costData = costData;
    this.costWlan = costWlan;
    this.costUtilities = costUtilities;
}


public double getGoodness(boolean[] bits) {
    double utility = 0.0;
    double rcost = 0.0;
    ArrayList<Double> resourceCost = new ArrayList<Double>();
    Collections.sort(costUtilities);
    double maxValue = Collections.max(costUtilities);
    int NumOfDimensions = serviceMap.size();
    serviceMap.put("DATA", 0);
    serviceMap.put("WLAN", 1);
    int data = serviceMap.get("DATA");
    int wlan = serviceMap.get("WLAN");
    for (int i = 2; i <= NumOfDimensions; i++) { //hashmap that stores the service names with a bit value i
        for (int k = 0; k < numOfServices; k++) {
            serviceMap.put(serviceNames.get(k), i); //if i = 2, k = 1, put(2, Facebook), put(3, Twitter)
        }

        if (bits[data] && bits[wlan]) {
            return -500;
        }
        if (!bits[data] || bits[wlan]) {
            return -1000; //particle goodness always returns this??
        }
        if (bits[data]) {
            resourceCost = costData;
        } else if (bits[wlan]) {
            resourceCost = costWlan;
        }


        for (int n = 2; n <= numOfServices; n++) {
            if (bits[serviceMap.get(n)]) {
                utility += costUtilities.get(n - 1);
                rcost += resourceCost.get(n - 1);
            }
        }
        if (rcost < batteryCost) {
            return utility;
        }
    }
        return utility * 0.50;
    }

}

Basically, I implemented a hashmap that takes user input from the main activity and assigns these inputs with an int value that is used as a bit in the bits[] array. These are my errors...

Caused by: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
                  at test_classes.CustomService.getGoodness(CustomService.java:60)
                  at bpso.BinaryPso.optimize(BinaryPso.java:45)
                  at android_tests.CustomUseCase.test(CustomUseCase.java:56)
                  at ai69.psoui.ParticleActivity.runTest(ParticleActivity.java:108)
                  at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:59)
                  at ai69.psoui.ParticleActivity$runTests.doInBackground(ParticleActivity.java:56)
                  at android.os.AsyncTask$2.call(AsyncTask.java:295)
                  at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                  at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
Az Islam
  • 133
  • 11
  • And what is unclear about the error? `bits[]` is clearly a zero length array. – john16384 Apr 10 '17 at 10:36
  • @john16384 I want to pass the hashmap values into the array. Its a boolean array however it is based on whether the services in the hashmap taht the user enters, are on (true) or off (false). – Az Islam Apr 10 '17 at 10:56

1 Answers1

0

It seems to me you want to use the bits array as an input/output parameter. However, you cannot change the size of an array after it was created. So you have a few options:

1) Make sure that the array has the same size as serviceNames when you pass it in.

2) Use an object that can be resize (like a BitSet or List<Boolean>) instead of the array.

3) Create the array inside getGoodness and return a composite value that has the double and the created bits array as the return value of getGoodness.

john16384
  • 7,800
  • 2
  • 30
  • 44
  • how can I make sure that the array has same size as serviceNames if there is nothing in it atm? I need it to be an array because the original algorithm implementation (Goodness interface) takes in boolean[] position as the parameter for the goodness function and I can't change that. Thank you for your help :) – Az Islam Apr 10 '17 at 15:08
  • Well, `serviceMap.size()` seems to me to be the size the `bits` array should be. If you donot have control over the caller code (who is calling `getGoodness`?) then that will never work -- the caller is passing in a zero-length array it seems. – john16384 Apr 10 '17 at 17:05
  • getGoodness is being called by the actual algorithm called 'bpso' which I cannot change. So the boolean[] bits will have to be the parameter for the getGoodness function. I've been trying to code this for days now, I still can't pass the services in the bits unless I declare them as final static int's. I can't do that either because the number of services and the service names will vary depending on what the user inputs. Thank you for your help anyway! – Az Islam Apr 12 '17 at 12:16