1
0
This commit is contained in:
2025-10-10 02:12:44 +02:00
commit dac3abf431
212 changed files with 475579 additions and 0 deletions

View File

@@ -0,0 +1,107 @@
package adda.ej1;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.jgrapht.GraphPath;
import adda.ej1.common.DatosHuertos;
import adda.ej1.common.HuertosEdge;
import adda.ej1.common.HuertosHeuristic;
import adda.ej1.common.HuertosVertex;
import adda.ej1.common.SolucionHuertos;
import adda.util.ConsoleColors;
import adda.util.Titles;
import us.lsi.colors.GraphColors;
import us.lsi.colors.GraphColors.Color;
import us.lsi.common.String2;
import us.lsi.graphs.alg.AStar;
import us.lsi.graphs.alg.BT;
import us.lsi.graphs.alg.PDR;
import us.lsi.graphs.virtual.EGraph;
import us.lsi.graphs.virtual.EGraph.Type;
import us.lsi.path.EGraphPath.PathType;
public class TestHuertosGV {
public static void main(String[] args) {
IntStream.range(1, 4).forEach(i -> {
System.out.println(ConsoleColors.BLUE + Titles.getTitle(i)
+ ConsoleColors.RESET);
DatosHuertos.iniDatos("ficheros/ejercicios/Ejercicio1DatosEntrada"+i+".txt");
System.out.println(ConsoleColors.RED + "A ESTRELLA"
+ String2.linea() + ConsoleColors.RESET);
testAstar(i);
System.out.println(ConsoleColors.RED + "\nBACKTRACKING"
+ String2.linea() + ConsoleColors.RESET);
testBT(i);
System.out.println(ConsoleColors.RED + "\nDINAMICA"
+ String2.linea() + ConsoleColors.RESET);
testPDR(i);
});
}
private static void testAstar(int i) {
EGraph<HuertosVertex, HuertosEdge> g = EGraph.virtual(
HuertosVertex.initial(),
HuertosVertex.goal(),
PathType.Sum, Type.Max
)
.heuristic(HuertosHeuristic::heuristic)
.edgeWeight(e -> e.weight())
.build();
AStar<HuertosVertex, HuertosEdge,?> alg = AStar.of(g);
GraphPath<HuertosVertex, HuertosEdge> gp = alg.search().get();
List<Integer> ls = gp.getEdgeList().stream().map(x -> x.action())
.collect(Collectors.toList());
SolucionHuertos sh = new SolucionHuertos(ls);
System.out.println(sh);
GraphColors.toDot(alg.outGraph(),
"generated/ej1_f"+i+".dot",
v -> v.toString(),
e -> e.action().toString(),
v -> GraphColors.color(Color.black),
e -> GraphColors.colorIf(Color.red, gp.getEdgeList().contains(e)));
}
private static void testBT(int i) {
EGraph<HuertosVertex, HuertosEdge> g = EGraph.virtual(
HuertosVertex.initial(),
HuertosVertex.goal(),
PathType.Sum, Type.Max
)
.heuristic(HuertosHeuristic::heuristic)
.edgeWeight(e -> e.weight())
.build();
BT<HuertosVertex, HuertosEdge,?> alg = BT.of(g);
GraphPath<HuertosVertex, HuertosEdge> gp = alg.search().get();
List<Integer> ls = gp.getEdgeList().stream().map(x -> x.action())
.collect(Collectors.toList());
SolucionHuertos sh = new SolucionHuertos(ls);
System.out.println(sh);
}
private static void testPDR(int i) {
EGraph<HuertosVertex, HuertosEdge> g = EGraph.virtual(
HuertosVertex.initial(),
HuertosVertex.goal(),
PathType.Sum, Type.Max
)
.heuristic(HuertosHeuristic::heuristic)
.edgeWeight(e -> e.weight())
.build();
PDR<HuertosVertex, HuertosEdge,?> alg = PDR.of(g);
GraphPath<HuertosVertex, HuertosEdge> gp = alg.search().get();
List<Integer> ls = gp.getEdgeList().stream().map(x -> x.action())
.collect(Collectors.toList());
SolucionHuertos sh = new SolucionHuertos(ls);
System.out.println(sh);
}
}

View File

@@ -0,0 +1,99 @@
package adda.ej1.common;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import us.lsi.common.Files2;
import us.lsi.common.String2;
public class DatosHuertos {
public static int N;
public static int M;
private static List<Verdura> verduras;
private static List<Huerto> huertos;
public static record Huerto(String nombre, Integer metrosDisponibles) {
public static Huerto of(String s) {
s = s.replace(";", "");
String[] partes = s.split(": metrosdisponibles=");
return new Huerto(partes[0], Integer.valueOf(partes[1]));
}
}
public static record Verdura(String nombre, Integer metrosRequeridos, List<String> incompatibles) {
public static Verdura of(String s) {
s = s.replace(" -> metrosrequeridos=", ";").replace(" incomp=", "");
String[] partes = s.split(";");
return new Verdura(partes[0], Integer.valueOf(partes[1]), Arrays.asList(partes[2].split(",")));
}
}
public static void toConsole() {
String2.toConsole(huertos, "Huertos de verdura:");
String2.toConsole(verduras, "Verduras:");
String2.toConsole(String2.linea());
}
public static void iniDatos(String fichero) {
List<String> lineas = Files2.linesFromFile(fichero);
Integer aux = lineas.indexOf("// VARIEDADES");
List<String> h = lineas.subList(1, aux);
List<String> v = lineas.subList(aux + 1, lineas.size());
huertos = new ArrayList<>();
for(String huerto : h) {
huertos.add(Huerto.of(huerto));
}
verduras = new ArrayList<>();
for(String verdura : v) {
verduras.add(Verdura.of(verdura));
}
N = verduras.size();
M = huertos.size();
// toConsole();
}
public static Verdura getVerdura(Integer i) {
return verduras.get(i);
}
public static List<Verdura> getVerduras() {
return verduras;
}
public static Huerto getHuerto(Integer j) {
return huertos.get(j);
}
public static Integer getN() {
return N;
}
public static Integer getM() {
return M;
}
public static Integer getMetrosRequeridos(Integer i) {
return verduras.get(i).metrosRequeridos();
}
public static Integer getMetrosDisponibles(Integer j) {
return huertos.get(j).metrosDisponibles();
}
// Incompatible -> 1; Compatible -> 0
public static Integer incompatible(Integer i, Integer k) {
return verduras.get(i).incompatibles().contains(verduras.get(k).nombre()) ? 1 : 0;
}
public static void main(String[] args) {
iniDatos("ficheros/ej1/Ejercicio1DatosEntrada1.txt");
}
public static List<Huerto> getHuertos() {
return huertos;
}
}

View File

@@ -0,0 +1,15 @@
package adda.ej1.common;
import us.lsi.graphs.virtual.SimpleEdgeAction;
public record HuertosEdge(
HuertosVertex source,
HuertosVertex target,
Integer action,
Double weight)
implements SimpleEdgeAction<HuertosVertex, Integer> {
public static HuertosEdge of(HuertosVertex v1, HuertosVertex v2, Integer action) {
return new HuertosEdge(v1, v2, action, action == -1 ? 0. : 1.);
}
}

View File

@@ -0,0 +1,14 @@
package adda.ej1.common;
import java.util.function.Predicate;
public class HuertosHeuristic {
public static Double heuristic(
HuertosVertex v1,
Predicate<HuertosVertex> goal,
HuertosVertex v2) {
// MAXIMO DE VERDURAS PLANTABLES DE v1.index() HASTA DatosHuertos.getN()
return (double) DatosHuertos.getN() - v1.index();
}
}

View File

@@ -0,0 +1,103 @@
package adda.ej1.common;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import adda.ej1.common.DatosHuertos.Huerto;
import us.lsi.common.Set2;
import us.lsi.graphs.virtual.VirtualVertex;
public record HuertosVertex(Integer index,
List<Set<Integer>> reparto, // reparto en cada huerto de las verduras ya plantadas
List<Integer> metrosDisponibles) // metros disponibles que quedan en cada huerto
implements VirtualVertex<HuertosVertex, HuertosEdge, Integer> {
public static HuertosVertex of(Integer index,
List<Set<Integer>> reparto, List<Integer> metrosDisponibles) {
return new HuertosVertex(index,reparto,metrosDisponibles);
}
public static HuertosVertex initial() {
return of(0,repartoInicial(),
DatosHuertos.getHuertos().stream()
.map(Huerto::metrosDisponibles)
.toList());
}
private static List<Set<Integer>> repartoInicial() {
List<Set<Integer>> res = new ArrayList<>();
IntStream.range(0, DatosHuertos.getM())
.forEach(i -> {
res.add(Set.of());
});
return res;
}
public static Predicate<HuertosVertex> goal() {
return v -> v.index == DatosHuertos.getN();
}
// X_i = en que huerto (X) se planta la verdura i -> X_0 = 1 Verdura0 en huerto 1.
// this.index es ese i
@Override
public List<Integer> actions() {
Stream<Integer> actions = IntStream.range(0, DatosHuertos.getM())
.boxed()
.filter(j -> cabe(this.index, j))
.filter(j -> compatible(this.index, j));
if(this.index < DatosHuertos.getN()) {
List<Integer> res = actions.collect(Collectors.toList());
res.add(-1);
return res;
} else {
return List.of();
}
}
private boolean cabe(Integer i, Integer j) {
return this.metrosDisponibles.get(j) >= DatosHuertos.getMetrosRequeridos(i);
}
private boolean compatible(Integer i, Integer j) {
return this.reparto.get(j).stream()
.noneMatch(k -> DatosHuertos.incompatible(i, k) == 1);
}
@Override
public HuertosVertex neighbor(Integer a) {
List<Set<Integer>> nuevoReparto = new ArrayList<>();
for(Set<Integer> s : this.reparto) {
nuevoReparto.add(Set2.copy(s));
}
List<Integer> nuevosMetrosDisponibles = new ArrayList<>(this.metrosDisponibles);
if(a == -1) {
return of(this.index + 1, nuevoReparto, nuevosMetrosDisponibles);
} else {
Set<Integer> nuevoSet = nuevoReparto.get(a);
nuevoSet.add(this.index);
nuevoReparto.set(a, nuevoSet);
nuevosMetrosDisponibles.set(a, nuevosMetrosDisponibles.get(a) -
DatosHuertos.getMetrosRequeridos(this.index));
return of(this.index + 1, nuevoReparto, nuevosMetrosDisponibles);
}
}
@Override
public HuertosEdge edge(Integer a) {
return HuertosEdge.of(this, neighbor(a), a);
}
@Override
public String toString() {
return "("+this.index+","+this.reparto+","+this.metrosDisponibles+")";
}
}

View File

@@ -0,0 +1,50 @@
package adda.ej1.common;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import adda.ej1.common.DatosHuertos.Huerto;
import adda.ej1.common.DatosHuertos.Verdura;
import us.lsi.common.Pair;
public class SolucionHuertos {
private static int index;
private static Integer distintas;
private static List<Pair<Verdura, Huerto>> solucion;
public static SolucionHuertos of_range(List<Integer> ls) {
return new SolucionHuertos(ls);
}
public SolucionHuertos() {
distintas = 0;
solucion = new ArrayList<>();
}
public SolucionHuertos(List<Integer> ls) {
index = 0;
solucion = new ArrayList<>();
ls.stream().forEach(hue -> {
if(hue != -1) {
Verdura v = DatosHuertos.getVerdura(index);
Huerto h = DatosHuertos.getHuerto(hue);
solucion.add(Pair.of(v, h));
}
index++;
});
distintas = (int) solucion.stream()
.map(p -> p.first())
.distinct().count();
}
public String toString() {
String verduras = solucion.stream()
.map(p -> p.first().nombre() + ": Huerto " + p.second().nombre().replace("H", ""))
.collect(Collectors.joining("\n ", "Reparto de verduras y huerto en el que es plantada " +
"cada una de ellas (si procede):\n ", "\n"));
return String.format("%sVariedades cultivadas: %d", verduras, distintas);
}
}

View File

@@ -0,0 +1,89 @@
package adda.ej1.common.manual;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import adda.ej1.common.DatosHuertos;
import adda.ej1.common.SolucionHuertos;
import us.lsi.common.List2;
import us.lsi.common.Map2;
public class HuertosPDR {
public static record Spm(Integer a, Integer weight) implements Comparable<Spm> {
public static Spm of(Integer a, Integer weight) {
return new Spm(a, weight);
}
@Override
public int compareTo(Spm sp) {
return this.weight.compareTo(sp.weight);
}
}
public static Map<HuertosProblem, Spm> mem;
public static Integer bestVal = Integer.MIN_VALUE;
private static SolucionHuertos sol() {
List<Integer> actions = List2.empty();
HuertosProblem prob = HuertosProblem.initial();
Spm spm = mem.get(prob);
while(spm != null && spm.a != null) {
HuertosProblem old = prob;
actions.add(spm.a);
prob = old.neighbor(spm.a);
spm = mem.get(prob);
}
return new SolucionHuertos(actions);
}
private static Double cota(Integer ac, HuertosProblem prob, Integer a) {
Integer w = a == -1 ? 0 : 1;
return ac + w + prob.neighbor(a).heuristic();
}
private static Spm pdr_search(HuertosProblem prob, Integer ac) {
Spm res = null;
boolean isTerminal = prob.index() == DatosHuertos.getN();
boolean isSolution = true;
if(mem.containsKey(prob)) {
res = mem.get(prob);
} else if(isTerminal && isSolution) {
res = Spm.of(null, 0);
mem.put(prob, res);
if(ac > bestVal) { //maximizando
bestVal = ac;
}
} else {
List<Spm> sols = List2.empty();
for(Integer a : prob.actions()) {
Double cota = cota(ac, prob, a);
if(cota <= bestVal) {
continue;
}
HuertosProblem n = prob.neighbor(a);
Integer w = a == -1 ? 0 : 1;
Spm spm = pdr_search(n, ac + w);
if(spm != null) {
Spm aux = Spm.of(a, spm.weight() + w);
sols.add(aux);
}
}
// maximizando
res = sols.stream().max(Comparator.naturalOrder()).orElse(null);
if(res != null) {
mem.put(prob, res);
}
}
return res;
}
public static SolucionHuertos search() {
mem = Map2.empty();
bestVal = Integer.MIN_VALUE; // maximizando
pdr_search(HuertosProblem.initial(),0);
return sol();
}
}

View File

@@ -0,0 +1,89 @@
package adda.ej1.common.manual;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import adda.ej1.common.DatosHuertos;
import adda.ej1.common.DatosHuertos.Huerto;
import us.lsi.common.Set2;
public record HuertosProblem(
Integer index,
List<Set<Integer>> reparto,
List<Integer> metrosDisponibles) {
public static HuertosProblem of(Integer index,
List<Set<Integer>> reparto, List<Integer> metrosDisponibles) {
return new HuertosProblem(index,reparto,metrosDisponibles);
}
public static HuertosProblem initial() {
return of(0,repartoInicial(),
DatosHuertos.getHuertos().stream()
.map(Huerto::metrosDisponibles)
.toList());
}
private static List<Set<Integer>> repartoInicial() {
List<Set<Integer>> res = new ArrayList<>();
IntStream.range(0, DatosHuertos.getM())
.forEach(i -> {
res.add(Set.of());
});
return res;
}
public List<Integer> actions() {
Stream<Integer> actions = IntStream.range(0, DatosHuertos.getM())
.boxed()
.filter(j -> cabe(this.index, j))
.filter(j -> compatible(this.index, j));
if(this.index < DatosHuertos.getN()) {
List<Integer> res = actions.collect(Collectors.toList());
res.add(-1);
return res;
} else {
return List.of();
}
}
private boolean cabe(Integer i, Integer j) {
return this.metrosDisponibles.get(j) >= DatosHuertos.getMetrosRequeridos(i);
}
private boolean compatible(Integer i, Integer j) {
return this.reparto.get(j).stream()
.noneMatch(k -> DatosHuertos.incompatible(i, k) == 1);
}
public HuertosProblem neighbor(Integer a) {
List<Set<Integer>> nuevoReparto = new ArrayList<>();
for(Set<Integer> s : this.reparto) {
nuevoReparto.add(Set2.copy(s));
}
List<Integer> nuevosMetrosDisponibles = new ArrayList<>(this.metrosDisponibles);
if(a == -1) {
return of(this.index + 1, nuevoReparto, nuevosMetrosDisponibles);
} else {
Set<Integer> nuevoSet = nuevoReparto.get(a);
nuevoSet.add(this.index);
nuevoReparto.set(a, nuevoSet);
nuevosMetrosDisponibles.set(a, nuevosMetrosDisponibles.get(a) -
DatosHuertos.getMetrosRequeridos(this.index));
return of(this.index + 1, nuevoReparto, nuevosMetrosDisponibles);
}
}
public Double heuristic() {
// MAXIMO DE VERDURAS PLANTABLES DE v1.index() HASTA DatosHuertos.getN()
return (double) DatosHuertos.getN() - this.index;
}
}

View File

@@ -0,0 +1,22 @@
package adda.ej1.common.manual;
import java.util.stream.IntStream;
import adda.ej1.common.DatosHuertos;
import adda.util.ConsoleColors;
import adda.util.Titles;
import us.lsi.common.String2;
public class TestPDR {
public static void main(String[] args) {
IntStream.range(1, 4).forEach(i -> {
System.out.println(ConsoleColors.BLUE + Titles.getTitle(i)
+ ConsoleColors.RESET);
DatosHuertos.iniDatos("ficheros/ejercicios/Ejercicio1DatosEntrada"+i+".txt");
System.out.println(ConsoleColors.RED + "\nPDR MANUAL"
+ String2.linea() + ConsoleColors.RESET);
System.out.println(HuertosPDR.search());
});
}
}