diff --git a/run.sh b/run.sh
index 35ab6c2bda16374ddf95079a87083576d36f94c0..41cff02232fe4d3dea04f4236d23a99038a9d22d 100755
--- a/run.sh
+++ b/run.sh
@@ -1,7 +1,8 @@
 #!/bin/bash
 
+date "+%T"
 cp $1 build/graph.graph
 python3 src/part1/unified.py
 java -classpath src/part2/GraphCompress/out/production/GraphCompress Main
 python3 src/part3/encode.py
-# python3 src/part4/draw.py
+date "+%T"
diff --git a/src/part2/GraphCompress/.idea/misc.xml b/src/part2/GraphCompress/.idea/misc.xml
index e0844bc7be0a8ca77dcee74dfc4059ee4a9d4a1d..0a44d59a3049e5594a0d81649fd0b8d861644b40 100644
--- a/src/part2/GraphCompress/.idea/misc.xml
+++ b/src/part2/GraphCompress/.idea/misc.xml
@@ -1,4 +1,3 @@
-<?xml version="1.0" encoding="UTF-8"?>
 <project version="4">
   <component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="11" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/out" />
diff --git a/src/part2/GraphCompress/.idea/vcs.xml b/src/part2/GraphCompress/.idea/vcs.xml
index f1f0a09377b046f00df0ea33544740f0f8688a4c..710fa8b405fcfa094f8af011394b196183cd85aa 100644
--- a/src/part2/GraphCompress/.idea/vcs.xml
+++ b/src/part2/GraphCompress/.idea/vcs.xml
@@ -3,6 +3,5 @@
   <component name="VcsDirectoryMappings">
     <mapping directory="$PROJECT_DIR$/../../../../.." vcs="Git" />
     <mapping directory="$PROJECT_DIR$/../../../../../" vcs="Git" />
-    <mapping directory="$PROJECT_DIR$/../../.." vcs="Git" />
   </component>
 </project>
\ No newline at end of file
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/CompressMath.class b/src/part2/GraphCompress/out/production/GraphCompress/CompressMath.class
index 3d105f92d4750af7187f08f6bac09f5d28e90515..ab261a4e89d6cb07bf916b86bf9fa4bddde8312b 100644
Binary files a/src/part2/GraphCompress/out/production/GraphCompress/CompressMath.class and b/src/part2/GraphCompress/out/production/GraphCompress/CompressMath.class differ
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/Greedy.class b/src/part2/GraphCompress/out/production/GraphCompress/Greedy.class
new file mode 100644
index 0000000000000000000000000000000000000000..c0e12c0997227f03aabeef71c85015f9fb04c587
Binary files /dev/null and b/src/part2/GraphCompress/out/production/GraphCompress/Greedy.class differ
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/Main.class b/src/part2/GraphCompress/out/production/GraphCompress/Main.class
index 562dcf712292d0ff6b837971221fe8d9730c9bd0..e8c4dd8035ad746e684dd8f8cc1dd5a8078f56a3 100644
Binary files a/src/part2/GraphCompress/out/production/GraphCompress/Main.class and b/src/part2/GraphCompress/out/production/GraphCompress/Main.class differ
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/Pic.class b/src/part2/GraphCompress/out/production/GraphCompress/Pic.class
new file mode 100644
index 0000000000000000000000000000000000000000..de829a4e4f34178eb380aa564201fd23ea21f35a
Binary files /dev/null and b/src/part2/GraphCompress/out/production/GraphCompress/Pic.class differ
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/Score$1.class b/src/part2/GraphCompress/out/production/GraphCompress/Score$1.class
new file mode 100644
index 0000000000000000000000000000000000000000..5c23d4495cf0da714317d95140f8c4a38ac6734a
Binary files /dev/null and b/src/part2/GraphCompress/out/production/GraphCompress/Score$1.class differ
diff --git a/src/part2/GraphCompress/out/production/GraphCompress/Score.class b/src/part2/GraphCompress/out/production/GraphCompress/Score.class
new file mode 100644
index 0000000000000000000000000000000000000000..4117690c26f2bebfbb7af22221150981ad2e07bc
Binary files /dev/null and b/src/part2/GraphCompress/out/production/GraphCompress/Score.class differ
diff --git a/src/part2/GraphCompress/src/CompressMath.java b/src/part2/GraphCompress/src/CompressMath.java
index 8ebd7a8f193efc4893b35580afcf4104d9afcb06..01e29fd2c496f1fcd4cbbea1b5c91b2191db2496 100644
--- a/src/part2/GraphCompress/src/CompressMath.java
+++ b/src/part2/GraphCompress/src/CompressMath.java
@@ -57,4 +57,11 @@ public class CompressMath {
         return term1 + term2 + term3;
     }
 
+    public static int arithmeticSubSum(Pic[] picList){
+        int s = 0;
+        for (Pic pic : picList){
+            s += pic.arithmeticSub();
+        }
+        return  s;
+    }
 }
diff --git a/src/part2/GraphCompress/src/Greedy.java b/src/part2/GraphCompress/src/Greedy.java
new file mode 100644
index 0000000000000000000000000000000000000000..15d3e68d6a69bc8c30cf25ff312b508bdcbcabe9
--- /dev/null
+++ b/src/part2/GraphCompress/src/Greedy.java
@@ -0,0 +1,88 @@
+import java.util.ArrayList;
+
+public class Greedy {
+    String path;
+    Graph graph;
+    ArrayList<Structure> structList;
+    ArrayList<Integer> bestStructList;
+    ArrayList<Score> score; // size of score should always be (size of structList - size of bestStructList)
+
+    public Greedy(String path){
+        this.path = path;
+        String graphFilename = path + "graph.graph";
+        String structFilename = path + "struct.txt";
+        this.graph = Graph.fromFile(graphFilename);
+        this.structList = Structure.listFromFile(structFilename);
+        this.bestStructList= new ArrayList<Integer>();
+        this.score = new ArrayList<Score>();
+    }
+
+    public void updateScore(){
+        int i;
+        int n = structList.size();
+        Structure struct;
+        int currentDiskSpace;
+
+        this.score.clear();
+
+        for (i = 0; i < n; i++) {
+            if (!bestStructList.contains(i)) {
+                struct = structList.get(i);
+                graph.undoInit();
+                graph.addStructure(struct);
+                currentDiskSpace = graph.diskSpace();
+                this.score.add(new Score(i, currentDiskSpace, struct));
+                graph.undoAction();
+            }
+        }
+
+        this.score.sort(Score.C);
+    }
+
+    public void addBestStructure(){
+        int i = 0;
+        int j = this.bestStructList.size();
+        int n = this.score.size();
+        Structure struct;
+        int structIndex;
+        int currentDiskSpace;
+        int bestCompression = graph.diskSpace();
+        while (i < n) {
+            struct = score.get(i).getStruct();
+            structIndex = score.get(i).getIndex();
+            graph.undoInit();
+            graph.addStructure(struct);
+            currentDiskSpace = graph.diskSpace();
+            if (currentDiskSpace < bestCompression) {
+                bestCompression = currentDiskSpace;
+                bestStructList.add(structIndex);
+                graph.addStructure(struct);
+                System.out.println("> Selecting structure " + structIndex + " as n°" + j + ", estimate size is " + graph.diskSpace() + " bits");
+                j++;
+                i++;
+            } else {
+                graph.undoAction();
+                i = n; // break
+            }
+        }
+    }
+
+    public void run(){
+        String partFilename = this.path + "partition.txt";
+
+        System.out.println("Part 2");
+        System.out.println("> Without structure, estimate size is " + graph.diskSpace() + " bits");
+
+        int prev_size = -1;
+        int new_size = 0;
+        while(prev_size < new_size){
+            prev_size = bestStructList.size();
+            System.out.println("> Updating scores...");
+            this.updateScore();
+            this.addBestStructure();
+            new_size = bestStructList.size();
+        }
+
+        FileIO.write(graph.getPartition().toFormattedString(), partFilename);
+    }
+}
diff --git a/src/part2/GraphCompress/src/Main.java b/src/part2/GraphCompress/src/Main.java
index 5fff43decefda6edc08a0b55273c566072fc7703..cc46eb1cb68fb84576fb7c31c56182d54bc567b3 100644
--- a/src/part2/GraphCompress/src/Main.java
+++ b/src/part2/GraphCompress/src/Main.java
@@ -1,20 +1,103 @@
-import java.io.File;
-import java.sql.SQLOutput;
 import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
 
 public class Main {
+    public static void test1() {
+        int n = 10;
+        String edgeString = "0,1;0,2;0,3;1,2;1,3;2,3;2,4;2,5;3,5;4,6";
+        Graph graph = new Graph(Edge.parseString(edgeString), n);
+        Structure s1 = new Structure("fc 0 1 2 3");
+        Structure s2 = new Structure("fc 2 3 4 5");
+        graph.addStructure(s1);
+        System.out.println(graph.toString());
+        Graph copyGraph = graph.clone();
+        copyGraph.undoInit();
+        copyGraph.addStructure(s2);
+        System.out.println(graph.toString());
+        System.out.println(copyGraph.toString());
+        copyGraph.undoAction();
+        System.out.println(graph.toString());
+        System.out.println(copyGraph.toString());
+    }
+
+    public static void test2(){
+        String graphName;
+        graphName = "as-oregon";
+        graphName = "choc";
+        String path;
+        path = "/home/pitois/Documents/these/thesis/prog/compress/";
+        path = "C:/Users/Pit/Documents/Boulot/Thèse/travail/thesis/prog/compress/";
+        path = "../compress/";
+        String graphFilename = path + "graph/" + graphName + ".graph";
+        String structFilename = path + "struct/" + graphName + ".txt";
+        Graph graph = Graph.fromFile(graphFilename);
+        ArrayList<Structure> structList = Structure.listFromFile(structFilename);
+        int i, n;
+        Structure struct;
+        n = structList.size();
+        for (i=0; i<n; i++){
+            struct = structList.get(i);
+            graph.addStructure(struct);
+        }
+
+        ArrayList<Edge> edgeList = Edge.readFile(graphFilename);
+        Graph graph2 = Graph.fromFile(graphFilename);
+        for (i=0; i<n; i++){
+            struct = structList.get(i);
+            graph2.undoInit();
+            graph2.addStructure(struct);
+            graph2.undoAction();
+            graph2.addStructure(struct);
+            System.out.println(i + ": " + graph2.diskSpace());
+        }
+        System.out.println(graph.check(edgeList));
+        System.out.println(graph2.check(edgeList));
+
+        int row, column;
+        for (Block block: graph.getBlockMatrix()){
+            row = block.getRow();
+            column = block.getColumn();
+            if(!graph2.getBlockMatrix().hasValue(row, column)){
+                System.out.println("Missing: " + row + ", " + column);
+            }
+        }
+
+        //System.out.println(i + ": " + graph.diskSpace());
+        //System.out.println(i + ": " + graph2.diskSpace());
+        //System.out.println(graph);
+        //System.out.println(graph.getPartition());
+        //System.out.println(graph2);
+        //System.out.println(graph2.getPartition());
+
+        /*
+        Iterator<Block> iterator = graph.getBlockMatrix().iterator();
+        Iterator<Block> iterator2 = graph2.getBlockMatrix().iterator();
+        Block block;
+        Block block2;
+
+        for (; iterator.hasNext() && iterator2.hasNext();) {
+            block = iterator.next();
+            block2 = iterator2.next();
+            System.out.println(block);
+            System.out.println(block2);
+            System.out.println(block.equals(block2));
+        }
+
+         */
+    }
+
     public static void greedy(){
         String path;
         path = "build/";
+        // path = "../../../build/";
         String graphFilename = path + "graph.graph";
         String structFilename = path + "struct.txt";
         String partFilename = path + "partition.txt";
         Graph graph = Graph.fromFile(graphFilename);
         ArrayList<Structure> structList = Structure.listFromFile(structFilename);
-        int i, n;
+        int i, k, n, m;
         n = structList.size();
+        m = n / 10;
+        m = n;
         Structure struct;
         ArrayList<Integer> bestStructList= new ArrayList<Integer>();
         int bestCompression = 10*graph.diskSpace();
@@ -25,6 +108,7 @@ public class Main {
         int j = 0;
         while (true) {
             bestStructure = -1;
+            k = 0;
             for (i = 0; i < n; i++) {
                 if (!bestStructList.contains(i)) {
                     struct = structList.get(i);
@@ -34,6 +118,13 @@ public class Main {
                     if (currentDiskSpace < bestCompression) {
                         bestCompression = currentDiskSpace;
                         bestStructure = i;
+                        k = 0;
+                        //System.out.println(i);
+                    } else {
+                        k++;
+                        if (k > m){
+                            i = n; // break
+                        }
                     }
                     graph.undoAction();
                 }
@@ -41,18 +132,25 @@ public class Main {
             if(bestStructure >= 0){
                 bestStructList.add(bestStructure);
                 graph.addStructure(structList.get(bestStructure));
-                System.out.println("> Selecting structure " + bestStructure + ", estimate size is " + graph.diskSpace() + " bits");
+                System.out.println("> Selecting structure " + bestStructure + " as n°" + j + ", estimate size is " + graph.diskSpace() + " bits");
+                //FileIO.write(graph.getPartition().toFormattedString(), path + "partition" + j + ".txt");
                 j++;
             } else {
                 break;
             }
         }
 
+        //System.out.println(graph.check(edgeList));
         FileIO.write(graph.getPartition().toFormattedString(), partFilename);
 
     }
 
     public static void main(String[] args) {
-        greedy();
+        /* run the old algorithm without speed-up */
+        // greedy();
+
+        /* run the new algorithm with SORTING speed-up */
+        Greedy g = new Greedy("build/");
+        g.run();
     }
 }
\ No newline at end of file
diff --git a/src/part2/GraphCompress/src/Pic.java b/src/part2/GraphCompress/src/Pic.java
new file mode 100644
index 0000000000000000000000000000000000000000..98de9c955b81d1826d159f337538c0ea17fe4ac9
--- /dev/null
+++ b/src/part2/GraphCompress/src/Pic.java
@@ -0,0 +1,21 @@
+public class Pic {
+    private final int nbOne;
+    private final int nbPixel;
+
+    public Pic(int nbOne, int nbPixel) {
+        this.nbOne = nbOne;
+        this.nbPixel = nbPixel;
+    }
+
+    public int getNbOne() {
+        return nbOne;
+    }
+
+    public int getNbPixel() {
+        return nbPixel;
+    }
+
+    public int arithmeticSub(){
+        return CompressMath.arithmeticSub(this.getNbOne(), this.getNbPixel());
+    }
+}
diff --git a/src/part2/GraphCompress/src/Score.java b/src/part2/GraphCompress/src/Score.java
new file mode 100644
index 0000000000000000000000000000000000000000..6660d1065d71f73e4cb5dbd3f9361e4f572a05f4
--- /dev/null
+++ b/src/part2/GraphCompress/src/Score.java
@@ -0,0 +1,27 @@
+import java.util.Comparator;
+
+public class Score {
+    private int index;
+    private int score;
+    private Structure struct;
+    public static final Comparator<? super Score> C = new Comparator<Score>(){
+        @Override
+        public int compare(Score lhs, Score rhs){
+            return lhs.score > rhs.score ? 1 : (lhs.score < rhs.score ? -1 : 0);
+        }
+    } ;
+
+    public Score(int index, int score, Structure struct){
+        this.index = index;
+        this.score = score;
+        this.struct = struct;
+    }
+
+    public Structure getStruct(){return struct;}
+    public int getIndex(){return index;}
+
+    @Override
+    public String toString() {
+        return "(" + this.index + ", " + this.score + ")";
+    }
+}