Good morning, I'm trying to optimize this backtracking algorithm that takes me 400ms to execute.
Any recommendations to improve the execution time of this algorithm?
Test:
public class Test {
public static void main(String[] args){
BackTracking a = new BackTracking();
List b = a.recursividad(0,new ArrayList(),new TreeSet(),new TreeSet());
System.out.println("Soluciones: "+b.size());
for(List c : b){
System.out.println(c);
}
}
}
Queens:
public class Reina {
private Integer y;
private Integer x;
public Reina(int x, int y) {
this.x = x;
this.y = y;
}
public Integer getY() {
return y;
}
public Integer getX() {
return x;
}
public Integer getDiagonalPrincipal(){
return y-x;
}
public Integer getDiagonalSecundaria(){
return y+x;
}
@Override
public String toString() {
return "[" + x + ","+ y + "]";
}
}
BackTracking:
public class BackTracking {
public Integer reinas = 4;
private List> resultado = new ArrayList>();
public List> recursividad(Integer x,List yOcupadas,Set diagonalesPrincipalesOcupadas,Set diagonalesSecundariasOcupadas){
if(x == reinas){
//Posibles soluciones
List lista = new ArrayList(); //Creo una lista con las posiciones actuales
for(int i=0;i<"reinas";i++){
lista.add(new Reina(i, yOcupadas.get(i)));
}
if(getNumeroDeConflictos(lista) == 0){ //Compruebo si esa lista es valida
Integer i = 0;
if(!resultado.containsAll(lista)){ //Si no esta en la solucion la lista, la a�ado
resultado.add(i, lista);
i++;
}
}
}else{
for(Integer a : getAlternativa(x,yOcupadas,diagonalesPrincipalesOcupadas,diagonalesSecundariasOcupadas)){ //Las alternativas
yOcupadas.add(a);
calculaPropiedadesDerivadas(yOcupadas,diagonalesPrincipalesOcupadas,diagonalesSecundariasOcupadas);
recursividad(x+1, yOcupadas,diagonalesPrincipalesOcupadas,diagonalesSecundariasOcupadas);
yOcupadas.remove(yOcupadas.size()-1);
calculaPropiedadesDerivadas(yOcupadas,diagonalesPrincipalesOcupadas,diagonalesSecundariasOcupadas);
}
}
return resultado;
}
private void calculaPropiedadesDerivadas(List yOcupadas,Set diagonalesPrincipalesOcupadas,Set diagonalesSecundariasOcupadas){
diagonalesPrincipalesOcupadas = new HashSet<>();
diagonalesSecundariasOcupadas = new HashSet<>();
for(int x=0; x < yOcupadas.size();x++){
diagonalesPrincipalesOcupadas.add(yOcupadas.get(x)-x);
diagonalesSecundariasOcupadas.add(yOcupadas.get(x)+x);
}
}
public List getAlternativa(Integer x,List yOcupadas,Set diagonalesPrincipalesOcupadas,Set diagonalesSecundariasOcupadas){
Stream s = IntStream
.range(0, reinas)
.filter(y -> !yOcupadas.contains(y)
&& !diagonalesPrincipalesOcupadas.contains(y-x)
&& !diagonalesSecundariasOcupadas.contains(y+x)
)
.boxed();
return s.collect(Collectors.toList());
}
public Integer getNumeroDeConflictos(List ls){
Set diagonalesPrincipalesOcupadas = new HashSet<>();
Set diagonalesSecundariasOcupadas = new HashSet<>();
for(Reina r:ls){
diagonalesPrincipalesOcupadas.add(r.getY()-r.getX());
diagonalesSecundariasOcupadas.add(r.getY()+r.getX());
}
return 2*reinas
- diagonalesPrincipalesOcupadas.size()
-diagonalesSecundariasOcupadas.size();
}
}