From 08958b32a7fe6afb9e5988ea53dd9b8b7b9a4195 Mon Sep 17 00:00:00 2001
From: konog98 <konog98@mi.fu-berlin.de>
Date: Tue, 7 May 2024 10:03:38 +0200
Subject: [PATCH] =?UTF-8?q?Main=20und=20fortesting.py=20funktionieren=20nu?=
 =?UTF-8?q?n=20f=C3=BCr=20alle=20tiny=20sets,=20l=C3=B6sung=20manchmal=20a?=
 =?UTF-8?q?nders,=20aber=20gleiche=20minimale=20crossings.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore                                    |   4 +-
 src/fortesting.py                             | 127 +++++---
 src/main.py                                   | 110 ++++---
 src/prob.lp                                   | 292 ++++++++++++++++--
 src/solution_instances/1.gr                   | 122 --------
 src/solution_instances/cycle_8_shuffled.sol   |   4 +-
 src/solution_instances/cycle_8_sorted.sol     |   2 +-
 .../{complete_4_5.gr => grid_9_shuffled.sol}  |   6 +-
 ..._8_shuffled.gr => ladder_4_4_shuffled.sol} |   4 +-
 .../{0.gr => ladder_4_4_sorted.sol}           |   3 +-
 src/solution_instances/matching_4_4.sol       |   4 +
 src/solution_instances/path_9_shuffled.sol    |   4 +
 src/solution_instances/path_9_sorted.sol      |   4 +
 src/solution_instances/plane_5_6.sol          |   6 +
 src/solution_instances/star_6.sol             |   6 +
 src/solution_instances/tree_6_10.sol          |  10 +
 src/solution_instances/website_20.sol         |  10 +
 17 files changed, 483 insertions(+), 235 deletions(-)
 delete mode 100644 src/solution_instances/1.gr
 rename src/solution_instances/{complete_4_5.gr => grid_9_shuffled.sol} (100%)
 rename src/solution_instances/{cycle_8_shuffled.gr => ladder_4_4_shuffled.sol} (100%)
 rename src/solution_instances/{0.gr => ladder_4_4_sorted.sol} (50%)
 create mode 100644 src/solution_instances/matching_4_4.sol
 create mode 100644 src/solution_instances/path_9_shuffled.sol
 create mode 100644 src/solution_instances/path_9_sorted.sol
 create mode 100644 src/solution_instances/plane_5_6.sol
 create mode 100644 src/solution_instances/star_6.sol
 create mode 100644 src/solution_instances/tree_6_10.sol
 create mode 100644 src/solution_instances/website_20.sol

diff --git a/.gitignore b/.gitignore
index d4a7e63..3cac8d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
 test.py
-test?.py
\ No newline at end of file
+test?.py
+*alt.py
+*test.py
\ No newline at end of file
diff --git a/src/fortesting.py b/src/fortesting.py
index df28fda..689d621 100644
--- a/src/fortesting.py
+++ b/src/fortesting.py
@@ -1,5 +1,11 @@
 import os
+import logging
 from pulp import *
+# Erstellen eines Graphen zur Bestimmung der Knotenreihenfolge
+from collections import defaultdict, deque
+
+# Konfiguriere Logging
+logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
 
 def count_initial_crossings(edges):
     crossings = 0
@@ -15,15 +21,16 @@ def count_crossings_via_variables(c_vars):
     for c_var in c_vars.values():
         if c_var.varValue == 1:
             crossings += 1
-    return crossings
+    print("Crossings:", crossings)
 
 def solve_bipartite_minimization(graph_file):
-
+    logging.info(f"Prozess für {graph_file} gestartet")
     # Extrahiere den Basisnamen der Eingabedatei
     base_name = os.path.basename(graph_file)
     new_base_name = base_name.replace('.gr', '.sol')
     # Erstelle den Ausgabepfad
     output_file = os.path.join('solution_instances', new_base_name)
+    logging.info(f"Die Ausgabedatei wird {output_file} sein")
 
     edges = []
     with open(graph_file, "r") as file:
@@ -34,16 +41,19 @@ def solve_bipartite_minimization(graph_file):
                 parts = line.split()
                 n0 = int(parts[2])  # Anzahl der Knoten in A
                 n1 = int(parts[3])  # Anzahl der Knoten in B
+                logging.info(f"Größen der Partitionen: A={n0}, B={n1}")
             else:
                 x, y = map(int, line.split())
                 edges.append((x, y))
-    
+    logging.info(f"{len(edges)} Kanten geladen.")
+
     prob = LpProblem("Minimize_Crossings", LpMinimize)
 
     # Boolesche Variablen für relative Positionen innerhalb jeder Partition
     x = {(i, j): LpVariable(f"x_{i}_{j}", 0, 1, cat='Binary') for i in range(1, n0 + 1) for j in range(1, n0 + 1) if i < j}
-    y = {(i, j): LpVariable(f"y_{i}_{j}", 0, 1, cat='Binary') for i in range(n0 + 1, n0 + n1 + 1) for j in range(n0 + 1, n0 + n1 + 1) if i != j}
+    y = {(i, j): LpVariable(f"y_{i}_{j}", 0, 1, cat='Binary') for i in range(n0 + 1, n0 + n1 + 1) for j in range(n0 + 1, n0 + n1 + 1) if i < j}
     c = {(i, j, k, l): LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary') for (i, j) in edges for (k, l) in edges if i < j and k < l and i < k and j != l}
+    logging.info("x, y und c geladen.")
     """
     # Crossing Variables
     c = {}
@@ -54,69 +64,102 @@ def solve_bipartite_minimization(graph_file):
     """
     # Zielfunktion, die minimiert werden soll
     prob += lpSum(c.values())
-   
+    logging.info("Zielfunktion aufgestellt.")
+
     # Crossing Constraints basierend auf Kantenpaaren
     for (i, j) in edges:
         for (k, l) in edges:
-            if i < j and k < l and i < k and j != l:  # Grundbedingung für mögliche Kreuzungen
-                if j < l:
-                    prob += -c[(i, j, k, l)] <= y[(j, l)] - x[(i, k)] <= c[(i, j, k, l)]
+            if i < k:  # Nur Kantenpaare betrachten, wo i < k
+                if (i, j, k, l) not in c:
+                    c[(i, j, k, l)] = LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary')
+
+                # Sicherstellen, dass nur gültige y-Variable-Zugriffe stattfinden
+                if j > l:
+                    prob += c[(i, j, k, l)] == y[(l, j)]  # Verwende .get() für sichere Zugriffe
                 if l > j:
-                    prob += 1 - c[(i, j, k, l)] <= y[(l, j)] + x[(i, k)] <= 1 + c[(i, j, k, l)]
-   
-    for i in range(n0 + 1, n0 + n1 - 1):
-        for j in range(i + 1, n0 + n1):
-            for k in range(j + 1, n0 + n1 + 1):
-                prob += 0 <= y[(i, j)] + y[(j, k)] - y[(i, k)] <= 1
+                    prob += c[(i, j, k, l)] == 1 - y[(j, l)]  # Verwende .get() für sichere Zugriffe
+    logging.info("Crossing Constraints aufgestellt.")
 
-    # Constraints für die relative Ordnung innerhalb der Partitionen
-    for (i, j) in y:
-        prob += y[(i, j)] + y[(j, i)] == 1  # genau einer muss wahr sein
+    # Transitivitäts-Constraints für x-Variable, wenn x die Reihenfolge in A darstellt
+    for i in range(1, n0 + 1):
+        for j in range(i + 1, n0 + 1):
+            prob += x[(i, j)] == 1, f"fix_order_{i}_{j}"
+    logging.info("X fest Constraints aufgestellt.")
 
     initial_crossings = count_initial_crossings(edges)
-    print(f"Initial crossings edges: {initial_crossings}")
+    logging.info(f"Initial crossings edges: {initial_crossings}")
 
     initial_crossings1 = count_crossings_via_variables(c)
-    print(f"Initial crossings VAR (before solving): {initial_crossings1}")
+    logging.info(f"Initial crossings VAR (before solving): {initial_crossings1}")
 
     prob.writeLP("prob.lp")
+    count_crossings_via_variables(c)
     prob.solve()
-    
+    logging.info(f"Status der Lösung: {LpStatus[prob.status]}")
+
+    """
+    for key, var in x.items():
+        print(f"x[{key}] = {var.varValue}")
+
+    for key, var in y.items():
+        print(f"y[{key}] = {var.varValue}")
+
     for key, var in c.items():
         print(f"c[{key}] = {var.varValue}")
-
+    """
 
     final_crossings1 = count_crossings_via_variables(c)
-    print(f"Final crossings VAR (after solving): {final_crossings1}")
-
-    print("Status:", LpStatus[prob.status])
+    logging.info(f"Final crossings VAR (after solving): {final_crossings1}")
     
     for v in prob.variables():
         print(v.name, "=", v.varValue)
 
-    # Check if a solution exists and print the results
-    if  prob.status == LpStatusOptimal:
-        print("Optimal arrangement of B:")
-
-        # Berechne zuerst die Summen in einer Liste
-        position_sum = [(j, sum(y[(j, k)].value() for k in range(n0+1, n0+n1+1) if j != k)) for j in range(n0+1, n0+n1+1)]
-
-        # Nutze diese Liste dann im sorted() Aufruf
-        sorted_b = sorted(position_sum, key=lambda x: -x[1])
-
-        # Stelle sicher, dass das Verzeichnis existiert
+    if prob.status == LpStatusOptimal:
+        logging.info("Optimale Lösung gefunden. Ergebnisse werden gespeichert. Optimal arrangement of B:")
+
+        graph = defaultdict(list)
+        in_degree = defaultdict(int)
+
+        nodes = range(n0+1, n0+n1+1)
+        for i in nodes:
+            for j in nodes:
+                if i != j:
+                    y_ij = y.get((i, j))
+                    
+                    # Hinzufügen einer Kante basierend auf y_ij-Werten
+                    if y_ij is not None:
+                        if y_ij.value() == 1:
+                            # i kommt vor j
+                            graph[i].append(j)
+                            in_degree[j] += 1
+                        elif y_ij.value() == 0:
+                            # j kommt vor i
+                            graph[j].append(i)
+                            in_degree[i] += 1
+
+        # Topologische Sortierung
+        zero_in_degree_queue = deque([i for i in nodes if in_degree[i] == 0])
+        sorted_b = []
+        while zero_in_degree_queue:
+            node = zero_in_degree_queue.popleft()
+            sorted_b.append(node)
+            for neighbor in graph[node]:
+                in_degree[neighbor] -= 1
+                if in_degree[neighbor] == 0:
+                    zero_in_degree_queue.append(neighbor)
+
+        # Ausgabe der sortierten Knoten
         os.makedirs(os.path.dirname(output_file), exist_ok=True)
-
-        # Speichere die sortierten Ergebnisse in der Ausgabedatei
         with open(output_file, 'w') as f:
-            for b, _ in sorted_b:
+            for b in sorted_b:
                 f.write(f"{b}\n")
                 print(f"{b}")
-        print(f"Results saved to {output_file}")
+        count_crossings_via_variables(c)
+        logging.info(f"Ergebnisse in {output_file} gespeichert")
     else:
-        print("No optimal solution found.")
+        logging.warning("Keine optimale Lösung gefunden.")
 
 
-#test_file = 'githubtests/tiny_test_set/instances/cycle_8_shuffled.gr'
-test_file = 'test_instances/0.gr'
+test_file = 'githubtests/tiny_test_set/instances/website_20.gr'
+#test_file = 'test_instances/0.gr'
 solve_bipartite_minimization(test_file)
diff --git a/src/main.py b/src/main.py
index b28bc1a..998a002 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,12 +1,14 @@
 import os
 import logging
+from pulp import *
+# Erstellen eines Graphen zur Bestimmung der Knotenreihenfolge
+from collections import defaultdict, deque
+
 # Konfiguriere Logging
 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
-from pulp import *
 
 def solve_bipartite_minimization(graph_file):
     logging.info(f"Prozess für {graph_file} gestartet")
-
     # Extrahiere den Basisnamen der Eingabedatei
     base_name = os.path.basename(graph_file)
     new_base_name = base_name.replace('.gr', '.sol')
@@ -28,74 +30,104 @@ def solve_bipartite_minimization(graph_file):
                 x, y = map(int, line.split())
                 edges.append((x, y))
     logging.info(f"{len(edges)} Kanten geladen.")
-    
+
     prob = LpProblem("Minimize_Crossings", LpMinimize)
 
     # Boolesche Variablen für relative Positionen innerhalb jeder Partition
     x = {(i, j): LpVariable(f"x_{i}_{j}", 0, 1, cat='Binary') for i in range(1, n0 + 1) for j in range(1, n0 + 1) if i < j}
-    y = {(i, j): LpVariable(f"y_{i}_{j}", 0, 1, cat='Binary') for i in range(n0 + 1, n0 + n1 + 1) for j in range(n0 + 1, n0 + n1 + 1) if i != j}
-    logging.info("x und y geladen.")
-
+    y = {(i, j): LpVariable(f"y_{i}_{j}", 0, 1, cat='Binary') for i in range(n0 + 1, n0 + n1 + 1) for j in range(n0 + 1, n0 + n1 + 1) if i < j}
+    c = {(i, j, k, l): LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary') for (i, j) in edges for (k, l) in edges if i < j and k < l and i < k and j != l}
+    logging.info("x, y und c geladen.")
+    """
     # Crossing Variables
     c = {}
     for (i, j) in edges:
         for (k, l) in edges:
             if i < j and k < l and i < k and j != l:
                 c[(i, j, k, l)] = LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary')
-    logging.info("c geladen.")
+    """
     # Zielfunktion, die minimiert werden soll
     prob += lpSum(c.values())
     logging.info("Zielfunktion aufgestellt.")
-    # Crossing Constraints
-    for (i, j, k, l) in c:
-        if j < l:
-            prob += -c[(i, j, k, l)] <= y[(j, l)] - x[(i, k)] <= c[(i, j, k, l)]
-        if l > j:
-            prob += 1 - c[(i, j, k, l)] <= y[(l, j)] + x[(i, k)] <= 1 + c[(i, j, k, l)]
+
+    # Crossing Constraints basierend auf Kantenpaaren
+    for (i, j) in edges:
+        for (k, l) in edges:
+            if i < k:  # Nur Kantenpaare betrachten, wo i < k
+                if (i, j, k, l) not in c:
+                    c[(i, j, k, l)] = LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary')
+
+                # Sicherstellen, dass nur gültige y-Variable-Zugriffe stattfinden
+                if j > l:
+                    prob += c[(i, j, k, l)] == y[(l, j)]  # Verwende .get() für sichere Zugriffe
+                if l > j:
+                    prob += c[(i, j, k, l)] == 1 - y[(j, l)]  # Verwende .get() für sichere Zugriffe
     logging.info("Crossing Constraints aufgestellt.")
 
-    # Constraints für x und y (ZU LANGE LAUFZEIT)
-    for i in range(1, n0):
+    # Transitivitäts-Constraints für x-Variable, wenn x die Reihenfolge in A darstellt
+    for i in range(1, n0 + 1):
         for j in range(i + 1, n0 + 1):
-            for k in range(j + 1, n0 + 1):
-                prob += 0 <= x[(i, j)] + x[(j, k)] - x[(i, k)] == 1
+            prob += x[(i, j)] == 1, f"fix_order_{i}_{j}"
     logging.info("X fest Constraints aufgestellt.")
 
-    for i in range(n0 + 1, n0 + n1):
-        for j in range(i + 1, n0 + n1 + 1):
-            for k in range(j + 1, n0 + n1 + 1):
-                prob +=  0 <= y[(i, j)] + y[(j, k)] - y[(i, k)] <= 1
-    logging.info("Y variable Constraints aufgestellt.")
-
-    # Constraints für die relative Ordnung innerhalb der Partitionen
-    for (i, j) in y:
-        prob += y[(i, j)] + y[(j, i)] == 1  # genau einer muss wahr sein
-    logging.info("Relative Ordnung muss wahr sein.")
-
     prob.solve()
     logging.info(f"Status der Lösung: {LpStatus[prob.status]}")
 
-    # Check if a solution exists and print the results
-    if  prob.status == LpStatusOptimal:
+    """
+    for key, var in x.items():
+        print(f"x[{key}] = {var.varValue}")
+
+    for key, var in y.items():
+        print(f"y[{key}] = {var.varValue}")
+
+    for key, var in c.items():
+        print(f"c[{key}] = {var.varValue}")
+    """
+
+    if prob.status == LpStatusOptimal:
         logging.info("Optimale Lösung gefunden. Ergebnisse werden gespeichert.")
-        # Berechne zuerst die Summen in einer Liste
-        position_sum = [(j, sum(y[(j, k)].value() for k in range(n0+1, n0+n1+1) if j != k)) for j in range(n0+1, n0+n1+1)]
 
-        # Nutze diese Liste dann im sorted() Aufruf
-        sorted_b = sorted(position_sum, key=lambda x: -x[1])
+        graph = defaultdict(list)
+        in_degree = defaultdict(int)
 
-        # Stelle sicher, dass das Verzeichnis existiert
-        os.makedirs(os.path.dirname(output_file), exist_ok=True)
+        nodes = range(n0+1, n0+n1+1)
+        for i in nodes:
+            for j in nodes:
+                if i != j:
+                    y_ij = y.get((i, j))
+                    
+                    # Hinzufügen einer Kante basierend auf y_ij-Werten
+                    if y_ij is not None:
+                        if y_ij.value() == 1:
+                            # i kommt vor j
+                            graph[i].append(j)
+                            in_degree[j] += 1
+                        elif y_ij.value() == 0:
+                            # j kommt vor i
+                            graph[j].append(i)
+                            in_degree[i] += 1
 
-        # Speichere die sortierten Ergebnisse in der Ausgabedatei
+        # Topologische Sortierung
+        zero_in_degree_queue = deque([i for i in nodes if in_degree[i] == 0])
+        sorted_b = []
+        while zero_in_degree_queue:
+            node = zero_in_degree_queue.popleft()
+            sorted_b.append(node)
+            for neighbor in graph[node]:
+                in_degree[neighbor] -= 1
+                if in_degree[neighbor] == 0:
+                    zero_in_degree_queue.append(neighbor)
+
+        # Ausgabe der sortierten Knoten
+        os.makedirs(os.path.dirname(output_file), exist_ok=True)
         with open(output_file, 'w') as f:
-            for b, _ in sorted_b:
+            for b in sorted_b:
                 f.write(f"{b}\n")
         logging.info(f"Ergebnisse in {output_file} gespeichert")
     else:
         logging.warning("Keine optimale Lösung gefunden.")
 
 
-test_file = 'githubtests/tiny_test_set/instances/cycle_8_sorted.gr'
+test_file = 'githubtests/tiny_test_set/instances/grid_9_shuffled.gr'
 #test_file = 'test_instances/0.gr'
 solve_bipartite_minimization(test_file)
diff --git a/src/prob.lp b/src/prob.lp
index 5933c9e..125d6b7 100644
--- a/src/prob.lp
+++ b/src/prob.lp
@@ -1,29 +1,277 @@
 \* Minimize_Crossings *\
 Minimize
-OBJ: c_1_5_2_4 + c_1_5_3_6 + c_2_4_3_6
+OBJ: c_1_15_10_16 + c_1_15_2_17 + c_1_15_3_18 + c_1_15_4_19 + c_1_15_5_20
+ + c_1_15_6_11 + c_1_15_7_12 + c_1_15_8_13 + c_1_15_9_14 + c_1_16_10_15
+ + c_1_16_2_17 + c_1_16_3_18 + c_1_16_4_19 + c_1_16_5_20 + c_1_16_6_11
+ + c_1_16_7_12 + c_1_16_8_13 + c_1_16_9_14 + c_2_17_10_15 + c_2_17_10_16
+ + c_2_17_3_18 + c_2_17_4_19 + c_2_17_5_20 + c_2_17_6_11 + c_2_17_7_12
+ + c_2_17_8_13 + c_2_17_9_14 + c_3_18_10_15 + c_3_18_10_16 + c_3_18_4_19
+ + c_3_18_5_20 + c_3_18_6_11 + c_3_18_7_12 + c_3_18_8_13 + c_3_18_9_14
+ + c_4_19_10_15 + c_4_19_10_16 + c_4_19_5_20 + c_4_19_6_11 + c_4_19_7_12
+ + c_4_19_8_13 + c_4_19_9_14 + c_5_20_10_15 + c_5_20_10_16 + c_5_20_6_11
+ + c_5_20_7_12 + c_5_20_8_13 + c_5_20_9_14 + c_6_11_10_15 + c_6_11_10_16
+ + c_6_11_7_12 + c_6_11_8_13 + c_6_11_9_14 + c_7_12_10_15 + c_7_12_10_16
+ + c_7_12_8_13 + c_7_12_9_14 + c_8_13_10_15 + c_8_13_10_16 + c_8_13_9_14
+ + c_9_14_10_15 + c_9_14_10_16
 Subject To
-_C1: - c_1_5_3_6 - x_1_3 + y_5_6 <= 0
-_C10: y_5_6 + y_6_5 = 1
-_C11: y_4_6 + y_6_4 = 1
-_C12: y_5_6 + y_6_5 = 1
-_C2: - c_1_5_3_6 + x_1_3 + y_6_5 <= 1
-_C3: - c_2_4_3_6 - x_2_3 + y_4_6 <= 0
-_C4: - c_2_4_3_6 + x_2_3 + y_6_4 <= 1
-_C5: y_4_5 - y_4_6 + y_5_6 <= 1
-_C6: y_4_5 - y_4_6 + y_5_6 >= 0
-_C7: y_4_5 + y_5_4 = 1
-_C8: y_4_6 + y_6_4 = 1
-_C9: y_4_5 + y_5_4 = 1
+_C1: c_1_15_2_17 + y_15_17 = 1
+_C10: c_1_16_2_17 + y_16_17 = 1
+_C11: c_1_16_3_18 + y_16_18 = 1
+_C12: c_1_16_4_19 + y_16_19 = 1
+_C13: c_1_16_5_20 + y_16_20 = 1
+_C14: c_1_16_6_11 - y_11_16 = 0
+_C15: c_1_16_7_12 - y_12_16 = 0
+_C16: c_1_16_8_13 - y_13_16 = 0
+_C17: c_1_16_9_14 - y_14_16 = 0
+_C18: c_1_16_10_15 - y_15_16 = 0
+_C19: c_2_17_3_18 + y_17_18 = 1
+_C2: c_1_15_3_18 + y_15_18 = 1
+_C20: c_2_17_4_19 + y_17_19 = 1
+_C21: c_2_17_5_20 + y_17_20 = 1
+_C22: c_2_17_6_11 - y_11_17 = 0
+_C23: c_2_17_7_12 - y_12_17 = 0
+_C24: c_2_17_8_13 - y_13_17 = 0
+_C25: c_2_17_9_14 - y_14_17 = 0
+_C26: c_2_17_10_15 - y_15_17 = 0
+_C27: c_2_17_10_16 - y_16_17 = 0
+_C28: c_3_18_4_19 + y_18_19 = 1
+_C29: c_3_18_5_20 + y_18_20 = 1
+_C3: c_1_15_4_19 + y_15_19 = 1
+_C30: c_3_18_6_11 - y_11_18 = 0
+_C31: c_3_18_7_12 - y_12_18 = 0
+_C32: c_3_18_8_13 - y_13_18 = 0
+_C33: c_3_18_9_14 - y_14_18 = 0
+_C34: c_3_18_10_15 - y_15_18 = 0
+_C35: c_3_18_10_16 - y_16_18 = 0
+_C36: c_4_19_5_20 + y_19_20 = 1
+_C37: c_4_19_6_11 - y_11_19 = 0
+_C38: c_4_19_7_12 - y_12_19 = 0
+_C39: c_4_19_8_13 - y_13_19 = 0
+_C4: c_1_15_5_20 + y_15_20 = 1
+_C40: c_4_19_9_14 - y_14_19 = 0
+_C41: c_4_19_10_15 - y_15_19 = 0
+_C42: c_4_19_10_16 - y_16_19 = 0
+_C43: c_5_20_6_11 - y_11_20 = 0
+_C44: c_5_20_7_12 - y_12_20 = 0
+_C45: c_5_20_8_13 - y_13_20 = 0
+_C46: c_5_20_9_14 - y_14_20 = 0
+_C47: c_5_20_10_15 - y_15_20 = 0
+_C48: c_5_20_10_16 - y_16_20 = 0
+_C49: c_6_11_7_12 + y_11_12 = 1
+_C5: c_1_15_6_11 - y_11_15 = 0
+_C50: c_6_11_8_13 + y_11_13 = 1
+_C51: c_6_11_9_14 + y_11_14 = 1
+_C52: c_6_11_10_15 + y_11_15 = 1
+_C53: c_6_11_10_16 + y_11_16 = 1
+_C54: c_7_12_8_13 + y_12_13 = 1
+_C55: c_7_12_9_14 + y_12_14 = 1
+_C56: c_7_12_10_15 + y_12_15 = 1
+_C57: c_7_12_10_16 + y_12_16 = 1
+_C58: c_8_13_9_14 + y_13_14 = 1
+_C59: c_8_13_10_15 + y_13_15 = 1
+_C6: c_1_15_7_12 - y_12_15 = 0
+_C60: c_8_13_10_16 + y_13_16 = 1
+_C61: c_9_14_10_15 + y_14_15 = 1
+_C62: c_9_14_10_16 + y_14_16 = 1
+_C7: c_1_15_8_13 - y_13_15 = 0
+_C8: c_1_15_9_14 - y_14_15 = 0
+_C9: c_1_15_10_16 + y_15_16 = 1
+fix_order_1_10: x_1_10 = 1
+fix_order_1_2: x_1_2 = 1
+fix_order_1_3: x_1_3 = 1
+fix_order_1_4: x_1_4 = 1
+fix_order_1_5: x_1_5 = 1
+fix_order_1_6: x_1_6 = 1
+fix_order_1_7: x_1_7 = 1
+fix_order_1_8: x_1_8 = 1
+fix_order_1_9: x_1_9 = 1
+fix_order_2_10: x_2_10 = 1
+fix_order_2_3: x_2_3 = 1
+fix_order_2_4: x_2_4 = 1
+fix_order_2_5: x_2_5 = 1
+fix_order_2_6: x_2_6 = 1
+fix_order_2_7: x_2_7 = 1
+fix_order_2_8: x_2_8 = 1
+fix_order_2_9: x_2_9 = 1
+fix_order_3_10: x_3_10 = 1
+fix_order_3_4: x_3_4 = 1
+fix_order_3_5: x_3_5 = 1
+fix_order_3_6: x_3_6 = 1
+fix_order_3_7: x_3_7 = 1
+fix_order_3_8: x_3_8 = 1
+fix_order_3_9: x_3_9 = 1
+fix_order_4_10: x_4_10 = 1
+fix_order_4_5: x_4_5 = 1
+fix_order_4_6: x_4_6 = 1
+fix_order_4_7: x_4_7 = 1
+fix_order_4_8: x_4_8 = 1
+fix_order_4_9: x_4_9 = 1
+fix_order_5_10: x_5_10 = 1
+fix_order_5_6: x_5_6 = 1
+fix_order_5_7: x_5_7 = 1
+fix_order_5_8: x_5_8 = 1
+fix_order_5_9: x_5_9 = 1
+fix_order_6_10: x_6_10 = 1
+fix_order_6_7: x_6_7 = 1
+fix_order_6_8: x_6_8 = 1
+fix_order_6_9: x_6_9 = 1
+fix_order_7_10: x_7_10 = 1
+fix_order_7_8: x_7_8 = 1
+fix_order_7_9: x_7_9 = 1
+fix_order_8_10: x_8_10 = 1
+fix_order_8_9: x_8_9 = 1
+fix_order_9_10: x_9_10 = 1
 Binaries
-c_1_5_2_4
-c_1_5_3_6
-c_2_4_3_6
+c_1_15_10_16
+c_1_15_2_17
+c_1_15_3_18
+c_1_15_4_19
+c_1_15_5_20
+c_1_15_6_11
+c_1_15_7_12
+c_1_15_8_13
+c_1_15_9_14
+c_1_16_10_15
+c_1_16_2_17
+c_1_16_3_18
+c_1_16_4_19
+c_1_16_5_20
+c_1_16_6_11
+c_1_16_7_12
+c_1_16_8_13
+c_1_16_9_14
+c_2_17_10_15
+c_2_17_10_16
+c_2_17_3_18
+c_2_17_4_19
+c_2_17_5_20
+c_2_17_6_11
+c_2_17_7_12
+c_2_17_8_13
+c_2_17_9_14
+c_3_18_10_15
+c_3_18_10_16
+c_3_18_4_19
+c_3_18_5_20
+c_3_18_6_11
+c_3_18_7_12
+c_3_18_8_13
+c_3_18_9_14
+c_4_19_10_15
+c_4_19_10_16
+c_4_19_5_20
+c_4_19_6_11
+c_4_19_7_12
+c_4_19_8_13
+c_4_19_9_14
+c_5_20_10_15
+c_5_20_10_16
+c_5_20_6_11
+c_5_20_7_12
+c_5_20_8_13
+c_5_20_9_14
+c_6_11_10_15
+c_6_11_10_16
+c_6_11_7_12
+c_6_11_8_13
+c_6_11_9_14
+c_7_12_10_15
+c_7_12_10_16
+c_7_12_8_13
+c_7_12_9_14
+c_8_13_10_15
+c_8_13_10_16
+c_8_13_9_14
+c_9_14_10_15
+c_9_14_10_16
+x_1_10
+x_1_2
 x_1_3
+x_1_4
+x_1_5
+x_1_6
+x_1_7
+x_1_8
+x_1_9
+x_2_10
 x_2_3
-y_4_5
-y_4_6
-y_5_4
-y_5_6
-y_6_4
-y_6_5
+x_2_4
+x_2_5
+x_2_6
+x_2_7
+x_2_8
+x_2_9
+x_3_10
+x_3_4
+x_3_5
+x_3_6
+x_3_7
+x_3_8
+x_3_9
+x_4_10
+x_4_5
+x_4_6
+x_4_7
+x_4_8
+x_4_9
+x_5_10
+x_5_6
+x_5_7
+x_5_8
+x_5_9
+x_6_10
+x_6_7
+x_6_8
+x_6_9
+x_7_10
+x_7_8
+x_7_9
+x_8_10
+x_8_9
+x_9_10
+y_11_12
+y_11_13
+y_11_14
+y_11_15
+y_11_16
+y_11_17
+y_11_18
+y_11_19
+y_11_20
+y_12_13
+y_12_14
+y_12_15
+y_12_16
+y_12_17
+y_12_18
+y_12_19
+y_12_20
+y_13_14
+y_13_15
+y_13_16
+y_13_17
+y_13_18
+y_13_19
+y_13_20
+y_14_15
+y_14_16
+y_14_17
+y_14_18
+y_14_19
+y_14_20
+y_15_16
+y_15_17
+y_15_18
+y_15_19
+y_15_20
+y_16_17
+y_16_18
+y_16_19
+y_16_20
+y_17_18
+y_17_19
+y_17_20
+y_18_19
+y_18_20
+y_19_20
 End
diff --git a/src/solution_instances/1.gr b/src/solution_instances/1.gr
deleted file mode 100644
index 6fd715b..0000000
--- a/src/solution_instances/1.gr
+++ /dev/null
@@ -1,122 +0,0 @@
-193
-256
-255
-254
-253
-252
-251
-250
-249
-248
-247
-246
-245
-244
-243
-242
-241
-240
-239
-238
-237
-236
-235
-234
-233
-232
-231
-230
-229
-228
-227
-226
-225
-224
-223
-222
-221
-220
-219
-218
-217
-216
-215
-214
-213
-212
-211
-210
-209
-208
-207
-206
-205
-204
-203
-202
-201
-200
-199
-198
-197
-196
-195
-194
-192
-191
-190
-189
-188
-187
-186
-185
-184
-183
-182
-181
-180
-179
-178
-177
-176
-175
-174
-173
-172
-171
-170
-169
-168
-167
-166
-165
-164
-163
-162
-161
-160
-159
-158
-157
-156
-155
-154
-153
-152
-151
-150
-149
-148
-147
-146
-145
-144
-143
-142
-141
-140
-139
-138
-137
-257
-258
diff --git a/src/solution_instances/cycle_8_shuffled.sol b/src/solution_instances/cycle_8_shuffled.sol
index 5957c0f..3590b12 100644
--- a/src/solution_instances/cycle_8_shuffled.sol
+++ b/src/solution_instances/cycle_8_shuffled.sol
@@ -1,4 +1,4 @@
-5
-7
 6
+7
 8
+5
diff --git a/src/solution_instances/cycle_8_sorted.sol b/src/solution_instances/cycle_8_sorted.sol
index 3aac70f..5957c0f 100644
--- a/src/solution_instances/cycle_8_sorted.sol
+++ b/src/solution_instances/cycle_8_sorted.sol
@@ -1,4 +1,4 @@
 5
-6
 7
+6
 8
diff --git a/src/solution_instances/complete_4_5.gr b/src/solution_instances/grid_9_shuffled.sol
similarity index 100%
rename from src/solution_instances/complete_4_5.gr
rename to src/solution_instances/grid_9_shuffled.sol
index 66f816c..486c190 100644
--- a/src/solution_instances/complete_4_5.gr
+++ b/src/solution_instances/grid_9_shuffled.sol
@@ -1,5 +1,5 @@
-5
-6
-7
 8
 9
+7
+5
+6
diff --git a/src/solution_instances/cycle_8_shuffled.gr b/src/solution_instances/ladder_4_4_shuffled.sol
similarity index 100%
rename from src/solution_instances/cycle_8_shuffled.gr
rename to src/solution_instances/ladder_4_4_shuffled.sol
index 3173b89..c213181 100644
--- a/src/solution_instances/cycle_8_shuffled.gr
+++ b/src/solution_instances/ladder_4_4_shuffled.sol
@@ -1,4 +1,4 @@
-8
 6
-7
+8
 5
+7
diff --git a/src/solution_instances/0.gr b/src/solution_instances/ladder_4_4_sorted.sol
similarity index 50%
rename from src/solution_instances/0.gr
rename to src/solution_instances/ladder_4_4_sorted.sol
index 292ff76..701bf8a 100644
--- a/src/solution_instances/0.gr
+++ b/src/solution_instances/ladder_4_4_sorted.sol
@@ -1,3 +1,4 @@
 5
-4
+8
+7
 6
diff --git a/src/solution_instances/matching_4_4.sol b/src/solution_instances/matching_4_4.sol
new file mode 100644
index 0000000..95fc5e4
--- /dev/null
+++ b/src/solution_instances/matching_4_4.sol
@@ -0,0 +1,4 @@
+7
+5
+6
+8
diff --git a/src/solution_instances/path_9_shuffled.sol b/src/solution_instances/path_9_shuffled.sol
new file mode 100644
index 0000000..e8af654
--- /dev/null
+++ b/src/solution_instances/path_9_shuffled.sol
@@ -0,0 +1,4 @@
+8
+6
+7
+9
diff --git a/src/solution_instances/path_9_sorted.sol b/src/solution_instances/path_9_sorted.sol
new file mode 100644
index 0000000..b86e099
--- /dev/null
+++ b/src/solution_instances/path_9_sorted.sol
@@ -0,0 +1,4 @@
+7
+9
+6
+8
diff --git a/src/solution_instances/plane_5_6.sol b/src/solution_instances/plane_5_6.sol
new file mode 100644
index 0000000..e70e8bf
--- /dev/null
+++ b/src/solution_instances/plane_5_6.sol
@@ -0,0 +1,6 @@
+9
+11
+6
+10
+7
+8
diff --git a/src/solution_instances/star_6.sol b/src/solution_instances/star_6.sol
new file mode 100644
index 0000000..dd866a9
--- /dev/null
+++ b/src/solution_instances/star_6.sol
@@ -0,0 +1,6 @@
+3
+5
+7
+4
+6
+8
diff --git a/src/solution_instances/tree_6_10.sol b/src/solution_instances/tree_6_10.sol
new file mode 100644
index 0000000..c8e2fc5
--- /dev/null
+++ b/src/solution_instances/tree_6_10.sol
@@ -0,0 +1,10 @@
+9
+10
+11
+7
+12
+13
+8
+14
+15
+16
diff --git a/src/solution_instances/website_20.sol b/src/solution_instances/website_20.sol
new file mode 100644
index 0000000..4d5dc4b
--- /dev/null
+++ b/src/solution_instances/website_20.sol
@@ -0,0 +1,10 @@
+17
+18
+19
+20
+11
+12
+13
+14
+16
+15
-- 
GitLab