diff --git a/.idea/misc.xml b/.idea/misc.xml index 38eefb8d41bfcaa3b3c8cc6ce120644e508e2a6e..e778be18ce10327d4e6028c48a4ca77537a3f1da 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> - <component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="18" project-jdk-type="JavaSDK"> + <component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="18" project-jdk-type="JavaSDK"> <output url="file://$PROJECT_DIR$/out" /> </component> </project> \ No newline at end of file diff --git a/out/production/aroTP2/App.class b/out/production/aroTP2/App.class index 4ae707af27c19bbfc1bf784eb39242b2b1eb1ffe..ddc92ab5174f71e7f1974260537408a5c4b0286f 100644 Binary files a/out/production/aroTP2/App.class and b/out/production/aroTP2/App.class differ diff --git a/out/production/aroTP2/InstanceReader.class b/out/production/aroTP2/InstanceReader.class index 5e8faaeb63c791acfcbc457ec4e45f20eb8b6eee..9a1d5b11a0914dac9a5b1a1a0bdda4d0958bdced 100644 Binary files a/out/production/aroTP2/InstanceReader.class and b/out/production/aroTP2/InstanceReader.class differ diff --git a/out/production/aroTP2/Loot.class b/out/production/aroTP2/Loot.class index dcc24c07e6b496357fea863d1d9cdfe408d4b69a..88c549853e6b352a7f562efc7945c9306b874007 100644 Binary files a/out/production/aroTP2/Loot.class and b/out/production/aroTP2/Loot.class differ diff --git a/src/App.java b/src/App.java index a70ffd2bd6aee3fa0e1b931a9341f905b1d113ed..9fbf35526ee85d8b1d2724389cd5a14fa4aa2c22 100644 --- a/src/App.java +++ b/src/App.java @@ -1,10 +1,11 @@ +import java.util.Arrays; import java.util.List; public class App { public static void main(String[] args) throws Exception { - Backpack backpack= new InstanceReader().read("src/sacTest"); - backpack.sortByRatio(); - backpack.solutionFractionnelle(); - System.out.println("solution fractionnelle :" + backpack.getSfValuee()); + Backpack backpack= new InstanceReader().read("src/sac4"); + backpack.solve(); + System.out.println("meilleur solution :" + backpack.getBestValue()); + System.out.println("meilleur solution :" + Arrays.toString(backpack.getBestSolution())); } } diff --git a/src/Backpack.java b/src/Backpack.java index c1b83218929edff63d23363e88d7a2a4c658ee55..7f57281797ce5511872b4a54a982ddc9ee9c7c70 100644 --- a/src/Backpack.java +++ b/src/Backpack.java @@ -2,14 +2,27 @@ import java.util.Comparator; import java.util.List; public class Backpack { - int capacity; - List<Loot> loots; - int sfValuee = 0; - int sfWeight = 0; + private final int capacity; + private final List<Loot> loots; + private int bestValue = 0; + private int currentWeight = 0; + private int currentValue = 0; + private boolean[] currentSolution; + private boolean[] bestSolution; public Backpack(int capacity, List<Loot> loots) { this.capacity = capacity; this.loots = loots; + this.currentSolution = new boolean[loots.size()]; + this.bestSolution = new boolean[loots.size()]; + } + + public void solve() { + this.sortByRatio(); + explore_from(0); + System.out.println("La valeur optimale est : " + bestValue); + System.out.println("Objets inclus dans la solution optimale : " + bestSolution); + } public String toString(){ @@ -23,26 +36,68 @@ public class Backpack { loots.sort(Comparator.comparing(Loot::getRatio).reversed()); } - public void solutionFractionnelle(){ - this.sortByRatio(); + public int solutionFractionnelle(int startIndex, int remainingCapacity) { + int sfValuee = 0; + int sfWeight = 0; - for(Loot loot : loots){ - if(sfWeight + loot.getWeight() <= this.capacity){ + // On commence à partir de startIndex + for(int i = startIndex; i < loots.size(); i++) { + Loot loot = loots.get(i); + if(sfWeight + loot.getWeight() <= remainingCapacity){ // Si l'objet entier peut entrer dans le sac sfValuee += loot.getValue(); sfWeight += loot.getWeight(); } else { // Si l'objet ne peut pas entrer entièrement dans le sac - int remainingWeight = this.capacity - sfWeight; + int remainingWeight = remainingCapacity - sfWeight; sfValuee += (int) (loot.getRatio() * remainingWeight); break; } } + return sfValuee; } - public int getSfValuee() { - return sfValuee; + private void explore_from(int index) { + // Si on a exploré tous les objets + if (index >= loots.size()) { + if (currentValue > bestValue) { + bestValue = currentValue; + System.arraycopy(currentSolution, 0, bestSolution, 0, loots.size()); + } + return; + } + + // On calcule la borne supérieure pour ce nœud + int remainingCapacity = capacity - currentWeight; + int borneSuperieure = currentValue + solutionFractionnelle(index, remainingCapacity); + + // Si la borne supérieure est inférieure à la meilleure solution + if (borneSuperieure <= bestValue) { + return; + } + + // on essaye d'explorer avec l'objet + Loot currentLoot = loots.get(index); + if (currentWeight + currentLoot.getWeight() <= capacity) { + currentWeight += currentLoot.getWeight(); + currentValue += currentLoot.getValue(); + currentSolution[index] = true; + explore_from(index + 1); + currentWeight -= currentLoot.getWeight(); + currentValue -= currentLoot.getValue(); + currentSolution[index] = false; + } + + // on explore sans l'objet + explore_from(index + 1); + } + + public int getBestValue() { + return bestValue; } + public boolean[] getBestSolution() { + return bestSolution; + } } diff --git a/src/Loot.java b/src/Loot.java index d7dc0320d837cc34d2d2fbda4f41e65e6c8f3e3c..e0996e4bd577b524a3931ba00adf4b60f725c84e 100644 --- a/src/Loot.java +++ b/src/Loot.java @@ -1,6 +1,6 @@ public class Loot { - int weight, value; - float ratio; + private int weight, value; + private final float ratio; public Loot(int weight, int value) { this.weight = weight;