stack overflow problem what to do to fix it, improve performance, Java?

Asked

Viewed 53 times

1

I know the stackoverflow is given by the memory burst but I’m with it in java and I don’t know a way to give performance so that it doesn’t occur. I’m making a software to calculate a linear programming simplex, so I have to tinker with multidimensional arrays (matrix). Until the last call I will leave commented works everything, already when it arrives in the line I said I will leave commented, I call a function that was used again, ai da stackoverflow because it will be in a loop of functions calling functions until the condition is valid. Follow the code, I’ll leave the comment I said in capital letters

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package projetoplr;

import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public final class ValidaDados {
    int ln;
    double [][] tabela;
    public ValidaDados(ArrayList data, int quantidade, int qtdRest[]) {
        int somaqtd = 0;

        for (int i = 0; i < qtdRest.length; i++) {
            somaqtd = somaqtd + qtdRest[i];
        }
        //subString(data, quantidade);
        double[][] calcula = calcula(subString(data, quantidade),restricoes(data, somaqtd,quantidade,qtdRest),data, quantidade);
    }

    public String [] subString(ArrayList lista, int quantidade) {
       
        int conta = quantidade*2+1;
        String array[] = new String[conta];
        int cont = 1;
        int newExiste = 0;

        cont = 1;
        for(int i =0; i<conta;i++){
            int existe = lista.get(0).toString().indexOf("x" + cont);
            //System.out.println("existe:" + existe);
            String valor = String.valueOf(cont);

                if (i == 0) {
                    //Primeiro número do FO
                    array[i] = lista.get(0).toString().substring(0, existe);
                    newExiste = existe;
                    ln = Integer.parseInt(lista.get(0).toString().substring(0, existe)) * -1;

                } else if(i < quantidade) {
                    //outros números
                    array[i] = lista.get(0).toString().substring(newExiste + valor.length() + 1, existe);
                    newExiste = existe;
                    //Pegar o valor em negativo
                    if ((Integer.parseInt(array[i])*-1)<ln) {
                        ln = Integer.parseInt(array[i])*-1;
                    }
                    
                }
                else{
                        array[i] = "0";
                }
                cont++;   
                System.out.println(array[i]);
        } 
 
        return array;
    }

    public double [][] calcula(String [] fo ,int [][] restricoes,ArrayList lista,int quantidade){
        int z = 1;
        int [] foNew ;
        foNew = retornaInt(fo);
        double pegaPivot = 0;
        int guardaLn = 0,linePivot=0;
        double pivot = 0;
        int fim = quantidade * 2 +2;
        int lastLine = lista.size()-1;
        double[][] tabela = new double[lista.size()][quantidade * 2 + 2];
        
        
            for (int i = 0; i < lista.size(); i++) {
                    for (int o = 0; o < fim; o++) {
                       if(i==0){
                           //primeiro receberá z
                           if(i==0 && o == 0){
                             tabela[i][o] = z;
                             }
                           else{
                              //depois o FO
                             tabela[i][o] = foNew[o-1]*-1;
                             //e o valor da tabela for igual ln pega a coluna em qe ln está
                             if(tabela[i][o]==ln){
                                 guardaLn = o;
                             }

                            }
                       }
                       else{
                           //Coluna Z
                           if(o==0){
                               tabela[i][o] = 0;
                                   }
                           //Outras colunas
                           else{
                               tabela[i][o] = restricoes[i-1][o-1];
                           }
                           //Se o(coluna) for igual a guarda ln(posição da coluna da ln)
                           if(o == guardaLn && i>1){
                               //System.out.println("foi");
                                 //Divide o B pelos elementos da coluna ln
                                 //pega a linha anterior e divide pelo b annterior
                                 pegaPivot = tabela[i-1][fim-1]/tabela[i-1][guardaLn];
                                 //Se a linha for a segunda(i=0)
                                 //armazenará a divisão de b por ln em pivot e pegará essa linha
                                 if(i == 2){
                                     pivot = pegaPivot;
                                     //Pegará a linha anterior(linha das operações)
                                     linePivot = i-1;
                                 }

                                 //Verifica o menor numero positivo e pega a linha
                                 else if(pegaPivot>0 && pegaPivot < pivot){
                                     pivot = pegaPivot;
                                     linePivot = i-1;
                                 }
                                  //System.out.println(pegaPivot+"pgpv");
                             }
                       }

                         // System.out.println(tabela[i][o]);

                    }
                    //tabela[i][o] 
                }
                //Pegando a ultima linha
                pegaPivot = tabela[lastLine][fim-1]/tabela[lista.size()-1][guardaLn];

                if(pegaPivot>0 && pegaPivot < pivot){
                pivot = pegaPivot;
                linePivot = lastLine;
                
                 }
                newLinePivot(tabela,linePivot, tabela[linePivot][guardaLn], fim,lista.size(),guardaLn);
              return tabela;
            }
    public void calcula2(int linhas, int colunas, int colunaMain, double [][]newTable){
        double [][] newTab = new double[linhas][colunas];
      
              int z = 1;
              int cont=0;
              double [] check = new double[colunas];
              for (int i = 0; i < linhas; i++) {
               for (int o = 0; o < colunas; o++) {
                   if(i==0 && o == 0){
                       newTab[i][o] = z;
                       
                   }
                   else{
                       newTab[i][o] = newTable[i][o];
                       if(i==0){
                       check[i] = newTable[i][o];
                          if(check[i]>0){
                              cont++;
                          }     
                               
                   }
                   }     }
              }
              if(cont!=colunas-1){
              pegaPivot(linhas,colunas,newTab);}
             else{
                 for (int i = 0; i < linhas; i++) {
               for (int o = 0; o < colunas; o++) {
                   System.out.println(newTab[i][o]);   
                   
               } 
              }
                  System.out.println("Melhor Solução");
              }
               newTab = null;
               return;
    }
    public int [][] restricoes(ArrayList lista, int somaqtd,int quantidade,int qtdRest[]) {
        String valor;

        int existe, newExiste = 0;
        int fim = quantidade * 2 +1;
        boolean aux=false;
        int armazena = 0, armazena2 = 0;
        int[][] restricoes = new int[lista.size()][quantidade * 2 + 1];
        for (int i = 0; i < lista.size() - 1; i++) {
            for (int o = 0; o < fim; o++) {
                existe = lista.get(i + 1).toString().indexOf("x" + (o + 1));

                int existeRest = lista.get(i + 1).toString().indexOf("<=");
                if (o == 0) {
                    //Primeiro número de cada restrição
                    restricoes[i][o] = Integer.parseInt(lista.get(i + 1).toString().substring(0, existe));
                    newExiste = existe;
                } else {
                    if(o+1>quantidade*2){
                        restricoes[i][o] = Integer.parseInt(lista.get(i + 1).toString().substring(existeRest + 2, lista.get(i + 1).toString().length()));
                        
                    }else{
                        
                        if((o + 1) > qtdRest[i] && (o+1) <= (quantidade*2) && aux == true ){
                            restricoes[i][o] = 0;
                            if(o+1 == armazena+1 && i == armazena2){
                                aux = false;
                            }
                        }
                        else{
                        if ((o + 1) > qtdRest[i] && (o+1) <= (quantidade*2) && aux == false) {      
                            restricoes[i][o] = 1;
                            armazena = o;
                            armazena2 = i+1;
                            aux = true;
                        }
                        else {
                            valor = String.valueOf(o + 1);
                            //Outros números das retrições
                            restricoes[i][o] = Integer.parseInt(lista.get(i + 1).toString().substring(newExiste + valor.length() + 1, existe));
                        }
                        }
                    }
                    newExiste = existe;
                }
                   
                    
            }
          
        }
            
    }

    public double [][] recalcula(double [][] tabela,int colunas,int linhas,double [] newlinepvt,int colunaP,int linePvt){
      double[][] newTabela = new double[linhas][colunas];   
     
        for(int i=0; i<linhas;i++){
            for(int o=0;o<colunas;o++){
                if(i!=linePvt){
                newTabela[i][o] = (newlinepvt[o]*(double)(tabela[i][colunaP]*-1))+(double)tabela[i][o];
                }
                else{
                newTabela[i][o] = newlinepvt[o];
                }
               
            }         
    }
    calcula2(linhas,colunas,colunaP,newTabela);
     newTabela = null;
    return newTabela;
    }
    
    public void newLinePivot(double [][] tabela,int linePivot, double elemPivot,int colunas,int linhas,int colunaP){
       // System.out.println(elemPivot+"lpvt");
       
        double [] newLpv = new double[colunas*2];
       
        //Pegando os números da linha pivot
        for(int i=0; i<colunas; i++){
        newLpv[i] =(double) tabela[linePivot][i]/elemPivot;
          
        }
        
    recalcula(tabela,colunas,linhas,newLpv,colunaP,linePivot);
     newLpv = null; 
     return;
    }
    
    public int [] retornaInt(String [] texto){
        int [] foNew = new int[texto.length*2];
        for(int i=0; i<texto.length;i++){
            foNew[i] = Integer.parseInt(texto[i]);
        }
        return foNew;
    }
    
    public void pegaPivot(int linha, int coluna, double[][] tabela) {
        double guardaLn = 2;
        int colLn=0;
        double [][] table = new double[linha*2][coluna*2];
        double pegaPivot2=0, pivot = 0;
        int linePivot=0;
        for (int i = 0; i < linha; i++) {
            for (int o = 0; o < coluna; o++) {
                table[i][o] = tabela[i][o];
                //restricoes[i - 1][o - 1];
                if (i == 0 && tabela[i][o] < guardaLn) {
                    guardaLn = tabela[i][o];
                    colLn = o;
                   // System.out.println(guardaLn);
                }
                //Se o(coluna) for igual a guarda colLn(posição da coluna da ln)
                if (o == colLn && i > 1) {
          
                    //Divide o B pelos elementos da coluna ln
                    //pega a linha anterior e divide pelo b anterior
                    pegaPivot2 = tabela[i - 1][coluna - 1] / tabela[i - 1][colLn];                    
                    //Se a linha for a segunda(i=0)
                    //armazenará a divisão de b por ln em pivot e pegará essa linha
                    if (i == 2) {
                        pivot = pegaPivot2;
                        //Pegará a linha anterior(linha das operações)
                        linePivot = i - 1;
                    } //Verifica o menor numero positivo e pega a linh
                    else if (pegaPivot2 > 0 && pegaPivot2 < pivot) {
                        pivot = pegaPivot2;
                        linePivot = i - 1;
                    }
                }
            }
        }

        //Pegando a ultima linha
        pegaPivot2 = tabela[linha - 1][coluna - 1] / tabela[linha - 1][colLn];

        if (pegaPivot2 > 0 && pegaPivot2 < pivot) {
            pivot = pegaPivot2;
            linePivot = linha - 1;

        }
/*AQUI ESTA O X, ELE COMENTADO FUNCIONA POIS NÃO HAVERÁ O LOOP DE FUNÇÕES JÁ SE EU DESCOMENTAR DA STACKOVERFLOW POIS ESSA FUNÇÃO CHAMARÁ A NEWLINEPIVOT > RECALCULA > CALCULA2 E ASSIM RESPECTIVAMENTE, COMO DAR DESEMPENHO PARA O LOOP DAS FUNÇÕES?

       //newLinePivot(table,linePivot,tabela[linePivot][colLn],coluna,linha,colLn);
       return;
    }

}

  • The most common cause of stack overflow in Java is that you have entered an infinite recursion. The second most common cause is that its recursive solution requires more space than is available to store the execution stack than is necessary. I recommend you look mathematically at your recursion: from a generic case, is it approaching the basic case at each input level? Are the cases getting smaller and smaller? It’s been a long time since I studied simplex to, in a quick look, talk about where (or if) there is an error in its implementation

  • Ah, yes, of course, remember that there are cases where simplex takes too long (if I’m not mistaken, superpolynomial) to run. So... Validate first if your test input is a suitable input

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.