Как избежать java.lang.ArrayIndexOutOfBoundsException в случае, когда вы перебираете первый элемент каждого массива в двумерном массиве? - PullRequest
0 голосов
/ 14 сентября 2018

Я работаю над симуляцией цепочки Маркова для сервера облачных вычислений, который имеет 4 сервера и каждый сервер имеет 4 виртуальные машины.

Сервер в моем случае это массив

{4,1,0}

И занятые виртуальные машины - первая переменная этого массива, поэтому она равна 4. Теперь, когда у нас есть прибытие, мы проверяем, заняты ли все серверы 4 ВМ, если это так, мы отбрасываем пакеты, так что переменная потерь в моем случае будет увеличена, в противном случае я буду проверять, занят ли первый сервер 4 ВМ, если так поступление придет на второй сервер, если его виртуальные машины не все заняты. Теперь во второй итерации у меня может быть вылет, и в этом случае вылет может произойти с каждым из серверов, которые имеют хотя бы одну виртуальную машину. Я проверяю это, используя формулу вероятности, но я не хочу подробно описывать это здесь.

Теперь у меня есть проблема, которую нужно решить для системы, описанной выше, как показано ниже:

В начале симуляции у меня есть 2D-массив

[{4,1,0}, {3,1,0}, {0,1,0}, {0,1,0}]

// Первая итерация

Теперь я хочу проверить, что если для всех массивов первый элемент равен 4, то я увеличу переменную, названную в моем коде, как

Потеря

В противном случае я проверю, равен ли первый элемент массива 4, если он равен 4, тогда я продолжу и проверю второй элемент массива, если второй элемент массива, как в моем случае выше, не равен 4 тогда я увеличу его на 1 и хочу получить результат

[{4,1,0}, {4,1,0}, {0,1,0}, {0,1,0}]

Теперь в следующие 4 итерации «Если у меня всегда будут приходящие пакеты и нет отправлений», я бы хотел получить вывод, как показано ниже

* * Тысяча тридцать-семь [{4,1,0}, {4,1,0}, {1,1,0}, {0,1,0}] [{4,1,0}, {4,1,0}, {2,1,0}, {0,1,0}] [{4,1,0}, {4,1,0}, {3,1,0}, {0,1,0}] [{4,1,0}, {4,1,0}, {4,1,0}, {0,1,0}] * 1 038 *

Но, тем не менее, я все еще должен проверить первую переменную первого массива и второго массива, поскольку эти значения из-за какой-то другой части моего кода могут быть уменьшены, если произойдет отправление.

// Вторая итерация (отправление)

Допустим, у меня во второй Итерации есть вылет, состояние моего 2D-массива после первой Итерации равно

* * Тысяча сорок-девять [{4,1,0}, {4,1,0}, {0,1,0}, {0,1,0}]

Теперь происходит отправление, и пусть, скажем, это происходит со вторым сервером, и мой статус снова будет как начало

* * Одна тысяча пятьдесят пять [{4,1,0}, {3,1,0}, {0,1,0}, {0,1,0}]

// Третья итерация (прибытие)

Теперь я должен проверить первый элемент первого массива, так как он равен 4, я не могу увеличить этот элемент, и поэтому я должен проверить первый элемент второго массива, так как это не 4, я должен увеличить его на 1.

Теперь в моем Java-коде ниже я сталкиваюсь с java.lang.ArrayIndexOutOfBoundsException (который я знаю, что это такое), когда я проверяю, равен ли первый из каждого элемента массивов 4, и если это 4, я должен проверить его для второго массива и так далее

Теперь вторая проблема заключается в том, что у меня больше отправлений, чем поступлений, когда я запускаю свою реализацию для 100 000 репликаций (итераций)

Мне действительно нужна помощь.

MainSimulation markovChain= new MainSimulation();

//statistics
int loss=0;
int arrivals=0;
int k=0;
int failures=0;
int departures=0;

//initializations
int numberOfReplications=100000;
int[] currentStateServer1= {4,1,0}; // this means Server 1 is working and all its VMs are busy
int[] currentStateServer2= {3,1,0};
int[] currentStateServer3= {0,1,0};
int[] currentStateServer4= {0,1,0};

int[][] currentState= {currentStateServer1,currentStateServer2,currentStateServer3,currentStateServer4};

for(int i=0;i<numberOfReplications;i++) {

    // generate a random number uniformly distributed between 0.0 and 1.0
    double uniformRandomNumber=randomNumber.nextDouble(); 
    System.out.println("The random number is" +uniformRandomNumber);

    //Arrival
    if (uniformRandomNumber<lambda/markovChain.sum(currentState)){

        System.out.println("We have arrival");
        if(currentState[0][0]==4 && currentState[1][0]==4 && currentState[2][0]==4 &&currentState[3][0]==4) {
            // the system is full, arrivals get lost
            loss++;
        } else {
            /*
             * test the current state 2D array to check if any server have all VMs busy
             *  If yes, check the next server and so on
             */
             for(int j=0;j<4;j++) {
                 if(currentState[j][0]==4) {
                     //if true, check the next server if all its VMs are busy
  //Here I have a RunTime error
                     currentState[j][0]=currentState[j+1][0];
                     System.out.println("The currentState is "+currentState[j][0]);
                 } else {
                     /*
                      *  if false, then this server has a free VM and the VM requests will occupy this server
                      *  the state of this server(the first variable) in this case will be increased by one
                      */
                      currentState[j][0] = currentState[j][0]+1;
                  } // close if block, used for checking or incrementing the state of each server   

              } // close for used for checking or incrementing the state of each server to the next one
          } // close the if block which check if the system if full or not
          arrivals++;
      } //close arrival

      //Departure   
      //departure check for the first server
      else if(uniformRandomNumber<(lambda+mu*currentState[0][0])/markovChain.sum(currentState)) {

          departures++;
          currentState[0][0]=currentState[0][0]-1;
      } //close the "check if" departure for first server
         // departure check for the second server
      else if(uniformRandomNumber<(lambda+mu*(currentState[0][0]+currentState[1][0]))/markovChain.sum(currentState)){

          departures++;
          currentState[1][0]=currentState[1][0]-1;
      } //close the "check if" departure occurs for the second server
        // departure check for the third server
      else if(uniformRandomNumber<(lambda+mu*(currentState[0][0]+currentState[1][0]+currentState[2][0]))/markovChain.sum(currentState)) {

          departures++;
          currentState[2][0]=currentState[2][0]-1;
       } //close the "check if" departure occurs for the third server
       else if(uniformRandomNumber<(lambda+mu*(currentState[0][0]+currentState[1][0]+currentState[2][0]+currentState[3][0]))/markovChain.sum(currentState)) {

            departures++;
            currentState[3][0]=currentState[3][0]-1;
        } //close the "check if" departure occurs for the third server
           // close departure

    //When I system.out.println the number of arrivals and departures I have more departures

1 Ответ

0 голосов
/ 14 сентября 2018

Ваша первая проблема - это комбинация: во-первых, вам не нужна предварительная проверка, если какой-либо из этих 4 серверов имеет полную виртуальную машину, вы уже проверяете это в цикле for.

Во-вторых, вашпроверить, является ли текущее состояние 4 супер странным.Нет смысла переназначать текущее состояние со следующим текущим состоянием:

for(int j=0;j<4;j++) {
    if(currentState[j][0]==4) {                       
    //Here I have RunTime error
        currentState[j][0]=currentState[j+1][0]; //this is no logical
        System.out.println("The currentState is "+currentState[j][0]);
    }

Лучше сделать это так:

boolean noLoss=false;
for(int j=0;j<4;j++){
    if(currentState[j][0]==4)
        continue; //if current server has no vms free, chck the next server
    else{
        currentState[j][0]++; //
        arrival++; //the package got assigned to a server, so it arrived
        noLoss=true; //the package was able to arrive to a server
        break; //we don't need to check any other server, since the package arrived
    }
}
if(!noLoss)
    loss++; //the package couldn't find a free server, hence it is a loss

эти строки больше не нужны:

if(currentState[0][0]==4 && currentState[1][0]==4 && currentState[2][0]==4 &&currentState[3][0]==4) {
    // the system is full, arrivals get lost
    loss++;
} else{                  
    for(int j=0;j<4;j++) {
        if(currentState[j][0]==4) { 
            currentState[j][0]=currentState[j+1][0];
            System.out.println("The currentState is "+currentState[j][0]);
        }
        else {                
            currentState[j][0] = currentState[j][0]+1;
        } // close if block, used for checking or incrementing the state of each server   
    } // close for used for checking or incrementing the state of each server to the next one
} // close the if block which check if the system if full or not
arrivals++;

К вашей второй проблеме: я не могу проследить, что именно ваш lambda и ваш markovChain объект.Вам необходимо проверить количество поступивших при наличии отправления (отправлять могут только поступившие пакеты?).В противном случае, это совершенно случайно (и зависит от ваших операторов if).Поэтому, если вы получаете слишком много отправлений, это, во-первых, потому, что вы не учитываете прибытия в свои расчеты, и / или ваша цепочка markovChain неверна.

Редактировать 1 : Если вы считаете прибывшиеПакет в любом случае (потеря или не потеря), тогда, конечно, вы должны поместить прибывший вне цикла for

boolean noLoss=false;
for(int j=0;j<4;j++){
    if(currentState[j][0]==4)
        continue; //if current server has no vms free, chck the next server
    else{
        currentState[j][0]++;
        noLoss=true; //the package was able to arrive to a server
        break; //we don't need to check any other server, since the package arrived
    }
}
if(!noLoss)
    loss++; //the package couldn't find a free server, hence it is a loss
arrived++;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...