Commit c80a2a26 authored by Falucho's avatar Falucho

Se calcula la frecuencia y se cachean algunos resultaods

parent 69899d3b
......@@ -119,6 +119,8 @@ public final class AEControlador {
}
Individuo individuo = poblacion.parallelStream().min(Comparator.comparingInt(Individuo::getCosto)).orElse(best);
ProblemaControlador.getInstance().calculoDeFrecuencias(individuo);
if (individuo.getCosto() < best.getCosto()) {
generacionInvariante = 0;
best = individuo;
......
package uy.edu.fing.lrt.controlador;
import uy.edu.fing.lrt.modelo.Arista;
import uy.edu.fing.lrt.modelo.Linea;
import uy.edu.fing.lrt.modelo.Nodo;
import uy.edu.fing.lrt.modelo.*;
import uy.edu.fing.lrt.test.Parada;
import uy.edu.fing.lrt.util.GlpkUtil;
import uy.edu.fing.lrt.util.Logger;
import uy.edu.fing.lrt.util.MathUtil;
import uy.edu.fing.lrt.util.matrix.Matrix;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.*;
import java.util.stream.IntStream;
public final class ProblemaControlador {
......@@ -72,11 +71,47 @@ public final class ProblemaControlador {
}
public void addParada(Parada p) {
p.setCoordX((p.getCoordX() - 554395.545355653972365) / 10D);
p.setCoordY((p.getCoordY() - 6134610.9221502495929599) / 10D);
paradasOriginales.put(p.getNombre(),p);
}
public Matrix<Integer> obtenerMatrizDemanda(List<Nodo> nodos) {
int cantNodos = cantNodos();
Matrix<Integer> matriz = new Matrix<>(cantNodos + 1, cantNodos + 1);
matriz.setDefaultValue(0);
Map<Integer, Integer> paradas = asignarParadasAEstaciones(nodos);
paradas.forEach((k_i, v_i) ->
paradas.forEach((k_j, v_j) ->
matriz.setValueAt(v_i, v_j,
matriz.getValueAt(v_i, v_j) + matrizOD.getValueAt(k_i - 1, k_j - 1).intValue())));
IntStream.rangeClosed(0, cantNodos).forEachOrdered(i -> matriz.setValueAt(i, i, null));
//Borro la demanda en el centro
for (int i = 1; i <= 3; i++) {
for (int j = i; j <= 3; j++) {
matriz.setValueAt(i, j, null);
matriz.setValueAt(j, i, null);
}
}
return matriz;
}
private Map<Integer, Integer> asignarParadasAEstaciones(List<Nodo> nodos) {
Map<Integer, Integer> result = new HashMap<>();
paradasOriginales.values().stream()
.filter(s -> s.getNombre() < 6150).forEach(e -> {
Nodo nodo = nodos.stream().min(Comparator.comparing(o -> MathUtil.dist(o, e))).get();
result.put(e.getNombre(), nodo.getNombre());
});
return result;
}
public void addODvalue(String[] splited) {
matrizOD.setValueAt(Integer.parseInt(splited[0]),Integer.parseInt(splited[1]),Double.parseDouble(splited[2]));
}
......@@ -97,6 +132,122 @@ public final class ProblemaControlador {
}
}
private static Map<String, Integer[]> chacheFrec = new HashMap<>();
private int cacheHit = 0;
public void calculoDeFrecuencias(Individuo individuo) {
String id = individuo.getId();
Integer[] frec;
if (chacheFrec.containsKey(id)) {
cacheHit++;
frec = chacheFrec.get(id);
} else {
frec = calculoDeFrecuencias_(individuo);
chacheFrec.put(id, frec);
}
for (int i = 0, frecLength = frec.length; i < frecLength; i++) {
individuo.getLinea(i).setFrecuencia(frec[i]);
}
}
private Integer[] calculoDeFrecuencias_(Individuo individuo) {
try {
Logger.info("Calculo de frecuencia");
Integer[] frec = {1, 1, 1, 1, 1, 1, 1, 1, 1};
Integer[] demandasMax = {0, 0, 0, 0, 0, 0, 0, 0, 0};
Map<Integer, Integer> frecuenciaTramo = new HashMap<>();
Map<Integer, Integer> demandaTramo = new HashMap<>();
List<Arista> aristasIndividuo = individuo.getAristas();
List<Nodo> nodosIndividuo = individuo.getNodos();
//Calculo la matrix de demanda
Matrix<Integer> matrixDemandaIndividuo = ProblemaControlador.getInstance().obtenerMatrizDemanda(nodosIndividuo);
//Calculo la demanda por hora en cada tramo
int lineaId = 0;
Concentrador[] concentradores = individuo.getConcentradores();
for (Concentrador concentrador : concentradores) {
for (Linea linea : concentrador.getLineas()) {
List<Integer> nodos = linea.getNodos();
Collections.reverse(nodos);
for (Integer nodo : nodos) {
for (Nodo nodoDestino : nodosIndividuo) {
//TODO no chequea que no regrese (es una relajacion)
if (nodoDestino.getNombre() == nodo) {
continue;
}
Integer demanda = matrixDemandaIndividuo.getValueAt(nodo, nodoDestino.getNombre());
Linea lineaDemanda = new Linea(GlpkUtil.SPP(aristasIndividuo, nodo, nodoDestino.getNombre(), Arista::getLargo));
for (Arista tramo : lineaDemanda.getTramos()) {
Integer demandaAcc = demandaTramo.getOrDefault(tramo.getId(), 0);
demandaTramo.put(tramo.getId(), demandaAcc + demanda);
}
}
}
lineaId++;
}
}
//Busco la mejor combinacion de frecuencia para una solucion
boolean ok = false;
while (!ok) {
//Calculo la Frecuenca disponible en cada tramo
frecuenciaTramo.clear();
lineaId = 0;
for (Concentrador concentrador : concentradores) {
for (Linea linea : concentrador.getLineas()) {
for (Arista tramo : linea.getTramos()) {
//Acumulo frecuencias del tramo
Integer frecTramo = frecuenciaTramo.getOrDefault(tramo.getId(), 0);
frecuenciaTramo.put(tramo.getId(), frecTramo + frec[lineaId]);
}
lineaId++;
}
}
lineaId = 0;
for (Concentrador concentrador : concentradores) {
for (Linea linea : concentrador.getLineas()) {
int demandaMaxLinea = 0;
for (Arista tramo : linea.getTramos()) {
//Acumulo frecuencias del tramo
Integer frecTramo = frecuenciaTramo.get(tramo.getId());
Integer demTramo = demandaTramo.getOrDefault(tramo.getId(), 0);
int demReal = demTramo / frecTramo;
if (demReal > demandaMaxLinea) {
demandaMaxLinea = demReal;
}
}
demandasMax[lineaId] = demandaMaxLinea;
lineaId++;
}
}
Integer max = Arrays.stream(demandasMax).max(Comparator.naturalOrder()).get();
if (max < 350) {
ok = true;
} else {
Integer idMax = -1;
for (int i = 0, demandasMaxLength = demandasMax.length; i < demandasMaxLength; i++) {
if (max.equals(demandasMax[i])) {
idMax = i;
break;
}
}
frec[idMax]++;
}
}
return frec;
} catch (Exception e) {
Logger.error("Error en frecuencia", e);
return null;
}
}
public int cantNodos() {
return nodos.size();
}
......@@ -125,9 +276,12 @@ public final class ProblemaControlador {
return (new ArrayList<>(nodos.values()));
}
public List<Parada> getParadas() {
return (new ArrayList<>(paradasOriginales.values()));
}
public List<Arista> getAristas() {
return (new ArrayList<>(aristasId.values()));
}
private Integer pairId(Arista a) {
......
package uy.edu.fing.lrt.genetic;
import uy.edu.fing.lrt.controlador.ProblemaControlador;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.modelo.Concentrador;
import uy.edu.fing.lrt.modelo.Individuo;
import java.util.ArrayList;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import uy.edu.fing.lrt.util.Random;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import uy.edu.fing.lrt.util.Random;
public final class Cruzador {
//Clase con metodos estaticos
......@@ -18,15 +18,20 @@ public final class Cruzador {
}
public static List<Individuo> run(List<Individuo> candidatos) {
List<Individuo> result;
Integer algoritmo = PropiedadesControlador.getIntProperty(PropiedadesEnum.CRUZAMIENTO);
switch (algoritmo) {
case 0:
return candidatos;
result = candidatos;
break;
case 1:
return algoritmo1(candidatos);
result = algoritmo1(candidatos);
break;
default:
throw new RuntimeException("No se ha definido una acion " + algoritmo + " para la propiedad " + PropiedadesEnum.CRUZAMIENTO.getNombre());
}
result.forEach(e -> ProblemaControlador.getInstance().calculoDeFrecuencias(e));
return result;
}
/* Algoritmo que realiza un cruzamiento seleccionando con una probabilidad x
......
package uy.edu.fing.lrt.genetic;
import uy.edu.fing.lrt.modelo.Concentrador;
import uy.edu.fing.lrt.modelo.Individuo;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import uy.edu.fing.lrt.controlador.ProblemaControlador;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.modelo.Arista;
import uy.edu.fing.lrt.modelo.Concentrador;
import uy.edu.fing.lrt.modelo.Individuo;
import uy.edu.fing.lrt.modelo.Linea;
import uy.edu.fing.lrt.util.GlpkUtil;
import uy.edu.fing.lrt.util.ListUtil;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import uy.edu.fing.lrt.util.Random;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
public final class Inicializador {
//Clase con metodos estaticos
......@@ -23,14 +24,19 @@ public final class Inicializador {
public static List<Individuo> run() {
Integer algoritmo = PropiedadesControlador.getIntProperty(PropiedadesEnum.INICIALIZACION);
List<Individuo> result;
switch (algoritmo) {
case 1:
return algoritmo1();
result = algoritmo1();
break;
case 2:
return algoritmo2();
result = algoritmo2();
break;
default:
throw new RuntimeException("No se ha definido una acion " + algoritmo + " para la propiedad " + PropiedadesEnum.INICIALIZACION.getNombre());
}
result.parallelStream().forEach(e -> ProblemaControlador.getInstance().calculoDeFrecuencias(e));
return result;
}
//Algoritmo que genera los individuos de a uno por partes y concentrador
......@@ -51,17 +57,9 @@ public final class Inicializador {
Concentrador[] concentradores = new Concentrador[cantFuentes];
//Por cada fuente
for (int i = cantCentros; i < (cantCentros + cantFuentes); i++) {
for (int trys = 0; trys < maxIntentos; trys++) {
Concentrador tmp = glpk1(i, aristas, lineasPorFuentes, trys % 2 == 0);
if (tmp.isValido()) {
concentradores[i - cantCentros] = tmp;
break;
}
}
if (concentradores[i - cantCentros] == null) {
throw new RuntimeException("Se han superado la cantidad maxima ("
+ maxIntentos + ") de intentos para generar una solucion factible para el concentrador " + i + " - Poblacion " + p);
}
Concentrador tmp = glpk1(i, aristas, lineasPorFuentes, Random.prob(50));
concentradores[i - cantCentros] = tmp;
}
result.add(new Individuo(concentradores));
}
......@@ -168,7 +166,6 @@ public final class Inicializador {
Integer[] lineasPorFuentesCopy = Arrays.copyOf(lineasPorFuentes, lineasPorFuentes.length);
String[] delays = PropiedadesControlador.getProperty(PropiedadesEnum.DELAYS).split(";");
Integer lineas = lineasPorFuentesCopy[fuente];
lineasPorFuentesCopy[fuente] = 1;
List<Linea> lineasResult = new ArrayList<>();
......
package uy.edu.fing.lrt.genetic;
import java.util.ArrayList;
import java.util.Arrays;
import uy.edu.fing.lrt.modelo.Individuo;
import java.util.List;
import uy.edu.fing.lrt.controlador.ProblemaControlador;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.modelo.Arista;
import uy.edu.fing.lrt.modelo.Concentrador;
import uy.edu.fing.lrt.modelo.Individuo;
import uy.edu.fing.lrt.modelo.Linea;
import uy.edu.fing.lrt.util.GlpkUtil;
import uy.edu.fing.lrt.util.ListUtil;
import uy.edu.fing.lrt.util.Logger;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import uy.edu.fing.lrt.util.Random;
import uy.edu.fing.lrt.util.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public final class Mutador {
private static List<Arista> aristas = null;
private static Integer individuosRepetidos = 0;
private static Integer mutadosEspeciales = 0;
private static Integer individuosFallidos = 0;
private static Integer mutaciones = 0;
......@@ -30,27 +28,35 @@ public final class Mutador {
aristas = ProblemaControlador.getInstance().getAristas();
individuosFallidos = 0;
mutaciones = 0;
mutadosEspeciales = 0;
individuosRepetidos = 0;
}
public static void show() {
Logger.info("mutaciones: " + mutaciones);
Logger.info("lineasRepetidos: " + individuosRepetidos);
Logger.info("mutadosEspeciales: " + mutadosEspeciales);
Logger.info("individuosFallidos: " + individuosFallidos);
}
public static List<Individuo> run(List<Individuo> candidatos) {
Integer algoritmo = PropiedadesControlador.getIntProperty(PropiedadesEnum.MUTACION);
List<Individuo> result;
switch (algoritmo) {
case 0:
return candidatos;
result = candidatos;
break;
case 1:
return algoritmo1(candidatos);
result = algoritmo1(candidatos);
break;
case 2:
return algo2(candidatos);
result = algo2(candidatos);
break;
default:
throw new RuntimeException("No se ha definido una acion " + algoritmo + " para la propiedad " + PropiedadesEnum.MUTACION.getNombre());
}
result.forEach(e -> ProblemaControlador.getInstance().calculoDeFrecuencias(e));
return result;
}
private static List<Individuo> algoritmo1(List<Individuo> candidatos) {
......@@ -71,14 +77,17 @@ public final class Mutador {
Individuo result = new Individuo(candidato);
Concentrador[] concentradores = result.getConcentradores();
for (int i = 0; i < concentradores.length; i++) {
muto = mutar1(concentradores[i], i) || muto;
muto = mutar1(candidato, concentradores[i], i) || muto;
}
if (muto) {
ProblemaControlador.getInstance().calculoDeFrecuencias(result);
}
return result;
}
/* Algoritmo que realiza una mutacion producto de eliminar líneas y
reconstruirlas sobre grafos perturbados */
private static boolean mutar1(Concentrador concentrador, int idConcentrador) {
private static boolean mutar1(Individuo candidato, Concentrador concentrador, int idConcentrador) {
Integer prob = PropiedadesControlador.getIntProperty(PropiedadesEnum.MUTACION_PROPABILIDAD);
List<Linea> lineas = concentrador.getLineas();
......@@ -109,7 +118,14 @@ public final class Mutador {
Linea lineaNueva = new Linea(GlpkUtil.delay(aristasUsables, lineasPorFuentes, ruido));
if (lineaNueva.igualA(lineaOriginal)) {
individuosRepetidos++;
lineaNueva = mutarAux(candidato, concentrador, i, lineasPorFuentes);
if (lineaNueva.igualA(lineaOriginal)) {
individuosRepetidos++;
} else {
mutadosEspeciales++;
muto = true;
concentrador.getLineas().set(i, lineaNueva);
}
} else {
muto = true;
concentrador.getLineas().set(i, lineaNueva);
......@@ -119,6 +135,22 @@ public final class Mutador {
return muto;
}
private static Linea mutarAux(Individuo candidato, Concentrador concentrador, int idLinea, Integer[] lineasPorFuentes) {
//Calculo las aristas del concentrador
List<Linea> lineas = concentrador.getLineas();
List<Arista> listAristas = new ArrayList<>();
for (int j = 0; j < lineas.size(); j++) {
if (j != idLinea) {
listAristas.addAll(concentrador.getLineas().get(j).getTramos());
}
}
List<Arista> aristasUsables = ListUtil.restaDeAristas(candidato.getAristas(), listAristas);
return new Linea(GlpkUtil.delay(aristasUsables, lineasPorFuentes, 0));
}
//Algoritmo no muta xD
private static List<Individuo> algo2(List<Individuo> candidatos) {
return candidatos;
......
......@@ -4,6 +4,7 @@ import uy.edu.fing.lrt.controlador.AEControlador;
import uy.edu.fing.lrt.controlador.ProblemaControlador;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.modelo.*;
import uy.edu.fing.lrt.test.Parada;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import javax.swing.*;
......@@ -31,7 +32,7 @@ public final class GuiHelper {
public static void dibujarNodos() {
Graphics g = mapa.getGraphics();
resetStroke(g);
mapa.paintComponents(dibujarNodos(g));
mapa.paintComponents(dibujarParadasyNodos(g));
}
public static void dibujarAristas(List<Arista> aristas, Color color, int px) {
......@@ -39,7 +40,7 @@ public final class GuiHelper {
clearAristas(g);
dibujarAristas(g);
dibujarAristas(g, aristas, color, px);
dibujarNodos(g);
dibujarParadasyNodos(g);
mapa.paintComponents(g);
}
......@@ -52,7 +53,7 @@ public final class GuiHelper {
for (int i = 0; i < lineas.size(); i++) {
dibujarAristas(g, lineas.get(i).getTramos(), colors[i], 2);
}
dibujarNodos(g);
dibujarParadasyNodos(g);
mapa.paintComponents(g);
}
......@@ -77,7 +78,7 @@ public final class GuiHelper {
Graphics g = mapa.getGraphics();
clearAristas(g);
dibujarAristas(g);
dibujarNodos(g);
dibujarParadasyNodos(g);
mapa.paintComponents(g);
}
......@@ -141,6 +142,55 @@ public final class GuiHelper {
return g;
}
private static Graphics dibujarParadasyNodos(Graphics g) {
resetStroke(g);
Boolean debug = PropiedadesControlador.getBoolProperty(PropiedadesEnum.DEBUG);
ProblemaControlador controlador = ProblemaControlador.getInstance();
double propY = ((double) mapa.getSize().getHeight() - 20) / controlador.getHeight();
double propX = ((double) mapa.getSize().getWidth() - 20) / controlador.getWidth();
final Integer cantFuente = PropiedadesControlador.getIntProperty(PropiedadesEnum.CANT_FUENTES);
final Integer cantSum = PropiedadesControlador.getIntProperty(PropiedadesEnum.CANT_SUMIDEROS);
java.util.List<Nodo> nodos = ProblemaControlador.getInstance().getNodos();
java.util.List<Parada> paradas = ProblemaControlador.getInstance().getParadas();
nodos.forEach((nodo) -> {
if (nodo.getNombre() <= cantSum) {
g.setColor(Color.BLUE);
} else {
if (nodo.getNombre() <= (cantSum + cantFuente)) {
g.setColor(Color.RED);
} else {
g.setColor(Color.YELLOW);
}
}
final int x = ((int) (nodo.getCoordX() * propX)) + 10;
final int y = (int) mapa.getSize().getHeight() - (((int) (nodo.getCoordY() * propY))) - 10;
g.drawOval(x - 3, y - 3, 7, 7);
g.fillOval(x - 3, y - 3, 7, 7);
if (debug) {
g.drawString(nodo.getNombre() + "", x, y);
}
});
g.setColor(Color.WHITE);
paradas.forEach((parada) -> {
final int x = ((int) (parada.getCoordX().intValue() * propX)) + 10;
final int y = (int) mapa.getSize().getHeight() - (((int) (parada.getCoordY().intValue() * propY))) - 10;
g.drawOval(x - 1, y - 1, 1, 1);
g.fillOval(x - 1, y - 1, 1, 1);
});
return g;
}
private static Graphics dibujarAristas(Graphics g, List<Arista> aristas, Color color, int px) {
Boolean debug = PropiedadesControlador.getBoolProperty(PropiedadesEnum.DEBUG);
......
......@@ -540,8 +540,8 @@ public final class Principal extends javax.swing.JFrame {
}
individuo = Parte2.run();
List<Arista> aristas = ProblemaControlador.getInstance().getAristas();
individuo = GlpkUtil.SPP(aristas, 1, 54, Arista::getLargo);
//List<Arista> aristas = ProblemaControlador.getInstance().getAristas();
//individuo = GlpkUtil.SPP(aristas, 3, 55, Arista::getLargo);
Linea l = new Linea(individuo);
List<Integer> nodos = l.getNodos();
......@@ -662,6 +662,8 @@ public final class Principal extends javax.swing.JFrame {
java.util.logging.Logger.getLogger(Principal.class.getName()).log(Level.SEVERE, null, ex);
}
//</editor-fold>
Logger.initLogger();
Logger.info("Start");
InputStream isMat = Principal.class.getClassLoader().getResourceAsStream("10-bus.mat");
InputStream isPar = Principal.class.getClassLoader().getResourceAsStream("ubicacionProcesada.txt");
InputStream isAri = Principal.class.getClassLoader().getResourceAsStream("aristasV2.txt");
......
package uy.edu.fing.lrt.modelo;
import uy.edu.fing.lrt.controlador.ProblemaControlador;
import uy.edu.fing.lrt.controlador.PropiedadesControlador;
import uy.edu.fing.lrt.util.PropiedadesEnum;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
......@@ -26,16 +30,60 @@ public final class Individuo {
return costo;
}
private void checkOperacion() {
boolean recalcularFrec = getLineas().stream().anyMatch(e -> e.getFrecuencia() == null);
if (recalcularFrec) {
ProblemaControlador.getInstance().calculoDeFrecuencias(this);
}
}
private void calcularCosto() {
//TODO: falta tener en cuenta el costo de operacion y usuario
costo = 0;
costo = getAristas().stream().map(Arista::getCosto).reduce(costo, Integer::sum);
Integer factorA = PropiedadesControlador.getIntProperty(PropiedadesEnum.FITNESS_A);
Integer factorB = PropiedadesControlador.getIntProperty(PropiedadesEnum.FITNESS_B);
Integer factorC = PropiedadesControlador.getIntProperty(PropiedadesEnum.FITNESS_C);
checkOperacion();
int costoConstruccion = getAristas().stream().map(Arista::getCosto).reduce(0, Integer::sum);
int costoOperacion = getLineas().stream().map(l -> l.getLargo() * l.getFrecuencia()).reduce(0, Integer::sum);
int costoUsuario = 0;
costo = costoConstruccion * factorA + costoOperacion * factorB + costoUsuario * factorC;
}
public boolean isValido() {
return Arrays.stream(concentradores).allMatch(Concentrador::isValido);
}
public List<Nodo> getNodos() {
Map<Integer, Nodo> tmp = new HashMap<>();
Arrays.stream(concentradores)
.forEachOrdered(concentrador -> concentrador.getLineas()
.forEach(linea -> linea.getTramos()
.forEach(arista -> {
tmp.put(arista.getIdNodoA(), arista.getNodoA());
tmp.put(arista.getIdNodoB(), arista.getNodoB());
})));
return new ArrayList<>(tmp.values());
}
public Linea getLinea(int l) {
int lineaId = 0;
for (Concentrador concentrador : concentradores) {
for (Linea linea : concentrador.getLineas()) {
if (lineaId == l) {
return linea;
}
lineaId++;
}
}
return null;
}
public List<Linea> getLineas() {
return Arrays.stream(concentradores).flatMap(e -> e.getLineas().stream()).collect(Collectors.toList());
}
public List<Arista> getAristas() {
Map<Integer, Arista> tmp = new HashMap<>();
for (Concentrador concentrador : concentradores) {
......@@ -46,7 +94,7 @@ public final class Individuo {
}
}
return new ArrayList(tmp.values());
return new ArrayList<>(tmp.values());
}
public Concentrador[] getConcentradores() {
......@@ -54,9 +102,7 @@ public final class Individuo {
}
private void genId() {
List<Concentrador> lista = Arrays.asList(concentradores);
lista.sort(Comparator.comparing(Concentrador::getId));
id = lista.stream().map(Concentrador::getId).collect(Collectors.joining(":"));
id = getAristas().stream().map(Arista::getId).sorted().map(e -> e + "").collect(Collectors.joining("-"));
}
public String getId() {
......