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
– Jefferson Quesado
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
– Jefferson Quesado