From 8fddbbb103eeb8beed780419bb5deaa15e6d9f6e Mon Sep 17 00:00:00 2001 From: konog98 <konog98@mi.fu-berlin.de> Date: Sat, 11 May 2024 20:36:56 +0200 Subject: [PATCH] =?UTF-8?q?Hinzuf=C3=BCgung=20von=20Batch=20scripts,=20sod?= =?UTF-8?q?ass=20der=20pace2024tester=20in=20Windows=20verwendet=20werden?= =?UTF-8?q?=20kann.=20Hinzuf=C3=BCgung=20des=20archives,=20sowie=20Umstruk?= =?UTF-8?q?turieung=20der=20Tests,=20sodass=20Sie=20mit=20dem=20pace2024te?= =?UTF-8?q?ster=20verwendet=20werden=20k=C3=B6nnen.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __pycache__/visualizer.cpython-311.pyc | Bin 0 -> 48545 bytes src/README.md | 8 +- src/archive/logfile.log | 26 + src/fortesting.py | 8 +- src/main.py | 93 ++-- .../0.sol => mytests/crossings/0.cros} | 3 - src/mytests/crossings/1.cros | 1 + .../crossings/complete_4_5.cros} | 5 - .../crossings/cycle_8_shuffled.cros} | 4 - .../crossings/cycle_8_sorted.cros} | 4 - .../crossings/grid_9_shuffled.cros} | 5 - .../crossings/ladder_4_4_shuffled.cros} | 4 - .../crossings/ladder_4_4_sorted.cros} | 4 - .../crossings/matching_4_4.cros} | 4 - .../crossings/path_9_shuffled.cros} | 4 - .../crossings/path_9_sorted.cros} | 4 - .../crossings/plane_5_6.cros} | 6 - src/mytests/crossings/star_6.cros | 1 + src/mytests/crossings/tree_6_10.cros | 1 + src/mytests/crossings/website_20.cros | 1 + .../instances}/0.gr | 0 .../instances}/1.gr | 0 .../instances}/10.gr | 0 .../instances}/100.gr | 0 .../instances}/11.gr | 0 .../instances}/12.gr | 0 .../instances}/13.gr | 0 .../instances}/14.gr | 0 .../instances}/15.gr | 0 .../instances}/16.gr | 0 .../instances}/17.gr | 0 .../instances}/18.gr | 0 .../instances}/19.gr | 0 .../instances}/2.gr | 0 .../instances}/20.gr | 0 .../instances}/21.gr | 0 .../instances}/22.gr | 0 .../instances}/23.gr | 0 .../instances}/24.gr | 0 .../instances}/25.gr | 0 .../instances}/26.gr | 0 .../instances}/27.gr | 0 .../instances}/28.gr | 0 .../instances}/29.gr | 0 .../instances}/3.gr | 0 .../instances}/30.gr | 0 .../instances}/31.gr | 0 .../instances}/32.gr | 0 .../instances}/33.gr | 0 .../instances}/34.gr | 0 .../instances}/35.gr | 0 .../instances}/36.gr | 0 .../instances}/37.gr | 0 .../instances}/38.gr | 0 .../instances}/39.gr | 0 .../instances}/4.gr | 0 .../instances}/40.gr | 0 .../instances}/41.gr | 0 .../instances}/42.gr | 0 .../instances}/43.gr | 0 .../instances}/44.gr | 0 .../instances}/45.gr | 0 .../instances}/46.gr | 0 .../instances}/47.gr | 0 .../instances}/48.gr | 0 .../instances}/49.gr | 0 .../instances}/5.gr | 0 .../instances}/50.gr | 0 .../instances}/51.gr | 0 .../instances}/52.gr | 0 .../instances}/53.gr | 0 .../instances}/54.gr | 0 .../instances}/55.gr | 0 .../instances}/56.gr | 0 .../instances}/57.gr | 0 .../instances}/58.gr | 0 .../instances}/59.gr | 0 .../instances}/6.gr | 0 .../instances}/60.gr | 0 .../instances}/61.gr | 0 .../instances}/62.gr | 0 .../instances}/63.gr | 0 .../instances}/64.gr | 0 .../instances}/65.gr | 0 .../instances}/66.gr | 0 .../instances}/67.gr | 0 .../instances}/68.gr | 0 .../instances}/69.gr | 0 .../instances}/7.gr | 0 .../instances}/70.gr | 0 .../instances}/71.gr | 0 .../instances}/72.gr | 0 .../instances}/73.gr | 0 .../instances}/74.gr | 0 .../instances}/75.gr | 0 .../instances}/76.gr | 0 .../instances}/77.gr | 0 .../instances}/78.gr | 0 .../instances}/79.gr | 0 .../instances}/8.gr | 0 .../instances}/80.gr | 0 .../instances}/81.gr | 0 .../instances}/82.gr | 0 .../instances}/83.gr | 0 .../instances}/84.gr | 0 .../instances}/85.gr | 0 .../instances}/86.gr | 0 .../instances}/87.gr | 0 .../instances}/88.gr | 0 .../instances}/89.gr | 0 .../instances}/9.gr | 0 .../instances}/90.gr | 0 .../instances}/91.gr | 0 .../instances}/92.gr | 0 .../instances}/93.gr | 0 .../instances}/94.gr | 0 .../instances}/95.gr | 0 .../instances}/96.gr | 0 .../instances}/97.gr | 0 .../instances}/98.gr | 0 .../instances}/99.gr | 0 src/mytests/solutions/0.sol | 3 + .../solutions}/1.sol | 0 src/mytests/solutions/complete_4_5.sol | 5 + .../solutions/cycle_8_shuffled.sol} | 3 +- src/mytests/solutions/cycle_8_sorted.sol | 4 + src/mytests/solutions/grid_9_shuffled.sol | 5 + src/mytests/solutions/ladder_4_4_shuffled.sol | 4 + src/mytests/solutions/ladder_4_4_sorted.sol | 4 + src/mytests/solutions/matching_4_4.sol | 4 + src/mytests/solutions/path_9_shuffled.sol | 4 + src/mytests/solutions/path_9_sorted.sol | 4 + .../solutions}/plane_5_6.sol | 1 - src/mytests/solutions/star_6.sol | 6 + .../solutions}/tree_6_10.sol | 1 - .../solutions}/website_20.sol | 1 - src/prob.lp | 452 +++++++++++------- src/solver.bat | 4 + src/solver.py | 122 +++++ 139 files changed, 531 insertions(+), 282 deletions(-) create mode 100644 __pycache__/visualizer.cpython-311.pyc create mode 100644 src/archive/logfile.log rename src/{solution_instances/0.sol => mytests/crossings/0.cros} (68%) create mode 100644 src/mytests/crossings/1.cros rename src/{solution_instances/complete_4_5.sol => mytests/crossings/complete_4_5.cros} (58%) rename src/{solution_instances/cycle_8_shuffled.sol => mytests/crossings/cycle_8_shuffled.cros} (61%) rename src/{solution_instances/cycle_8_sorted.sol => mytests/crossings/cycle_8_sorted.cros} (61%) rename src/{solution_instances/grid_9_shuffled.sol => mytests/crossings/grid_9_shuffled.cros} (58%) rename src/{solution_instances/ladder_4_4_shuffled.sol => mytests/crossings/ladder_4_4_shuffled.cros} (63%) rename src/{solution_instances/ladder_4_4_sorted.sol => mytests/crossings/ladder_4_4_sorted.cros} (61%) rename src/{solution_instances/matching_4_4.sol => mytests/crossings/matching_4_4.cros} (61%) rename src/{solution_instances/path_9_shuffled.sol => mytests/crossings/path_9_shuffled.cros} (61%) rename src/{solution_instances/path_9_sorted.sol => mytests/crossings/path_9_sorted.cros} (61%) rename src/{solution_instances/star_6.sol => mytests/crossings/plane_5_6.cros} (52%) create mode 100644 src/mytests/crossings/star_6.cros create mode 100644 src/mytests/crossings/tree_6_10.cros create mode 100644 src/mytests/crossings/website_20.cros rename src/{test_instances => mytests/instances}/0.gr (100%) rename src/{test_instances => mytests/instances}/1.gr (100%) rename src/{test_instances => mytests/instances}/10.gr (100%) rename src/{test_instances => mytests/instances}/100.gr (100%) rename src/{test_instances => mytests/instances}/11.gr (100%) rename src/{test_instances => mytests/instances}/12.gr (100%) rename src/{test_instances => mytests/instances}/13.gr (100%) rename src/{test_instances => mytests/instances}/14.gr (100%) rename src/{test_instances => mytests/instances}/15.gr (100%) rename src/{test_instances => mytests/instances}/16.gr (100%) rename src/{test_instances => mytests/instances}/17.gr (100%) rename src/{test_instances => mytests/instances}/18.gr (100%) rename src/{test_instances => mytests/instances}/19.gr (100%) rename src/{test_instances => mytests/instances}/2.gr (100%) rename src/{test_instances => mytests/instances}/20.gr (100%) rename src/{test_instances => mytests/instances}/21.gr (100%) rename src/{test_instances => mytests/instances}/22.gr (100%) rename src/{test_instances => mytests/instances}/23.gr (100%) rename src/{test_instances => mytests/instances}/24.gr (100%) rename src/{test_instances => mytests/instances}/25.gr (100%) rename src/{test_instances => mytests/instances}/26.gr (100%) rename src/{test_instances => mytests/instances}/27.gr (100%) rename src/{test_instances => mytests/instances}/28.gr (100%) rename src/{test_instances => mytests/instances}/29.gr (100%) rename src/{test_instances => mytests/instances}/3.gr (100%) rename src/{test_instances => mytests/instances}/30.gr (100%) rename src/{test_instances => mytests/instances}/31.gr (100%) rename src/{test_instances => mytests/instances}/32.gr (100%) rename src/{test_instances => mytests/instances}/33.gr (100%) rename src/{test_instances => mytests/instances}/34.gr (100%) rename src/{test_instances => mytests/instances}/35.gr (100%) rename src/{test_instances => mytests/instances}/36.gr (100%) rename src/{test_instances => mytests/instances}/37.gr (100%) rename src/{test_instances => mytests/instances}/38.gr (100%) rename src/{test_instances => mytests/instances}/39.gr (100%) rename src/{test_instances => mytests/instances}/4.gr (100%) rename src/{test_instances => mytests/instances}/40.gr (100%) rename src/{test_instances => mytests/instances}/41.gr (100%) rename src/{test_instances => mytests/instances}/42.gr (100%) rename src/{test_instances => mytests/instances}/43.gr (100%) rename src/{test_instances => mytests/instances}/44.gr (100%) rename src/{test_instances => mytests/instances}/45.gr (100%) rename src/{test_instances => mytests/instances}/46.gr (100%) rename src/{test_instances => mytests/instances}/47.gr (100%) rename src/{test_instances => mytests/instances}/48.gr (100%) rename src/{test_instances => mytests/instances}/49.gr (100%) rename src/{test_instances => mytests/instances}/5.gr (100%) rename src/{test_instances => mytests/instances}/50.gr (100%) rename src/{test_instances => mytests/instances}/51.gr (100%) rename src/{test_instances => mytests/instances}/52.gr (100%) rename src/{test_instances => mytests/instances}/53.gr (100%) rename src/{test_instances => mytests/instances}/54.gr (100%) rename src/{test_instances => mytests/instances}/55.gr (100%) rename src/{test_instances => mytests/instances}/56.gr (100%) rename src/{test_instances => mytests/instances}/57.gr (100%) rename src/{test_instances => mytests/instances}/58.gr (100%) rename src/{test_instances => mytests/instances}/59.gr (100%) rename src/{test_instances => mytests/instances}/6.gr (100%) rename src/{test_instances => mytests/instances}/60.gr (100%) rename src/{test_instances => mytests/instances}/61.gr (100%) rename src/{test_instances => mytests/instances}/62.gr (100%) rename src/{test_instances => mytests/instances}/63.gr (100%) rename src/{test_instances => mytests/instances}/64.gr (100%) rename src/{test_instances => mytests/instances}/65.gr (100%) rename src/{test_instances => mytests/instances}/66.gr (100%) rename src/{test_instances => mytests/instances}/67.gr (100%) rename src/{test_instances => mytests/instances}/68.gr (100%) rename src/{test_instances => mytests/instances}/69.gr (100%) rename src/{test_instances => mytests/instances}/7.gr (100%) rename src/{test_instances => mytests/instances}/70.gr (100%) rename src/{test_instances => mytests/instances}/71.gr (100%) rename src/{test_instances => mytests/instances}/72.gr (100%) rename src/{test_instances => mytests/instances}/73.gr (100%) rename src/{test_instances => mytests/instances}/74.gr (100%) rename src/{test_instances => mytests/instances}/75.gr (100%) rename src/{test_instances => mytests/instances}/76.gr (100%) rename src/{test_instances => mytests/instances}/77.gr (100%) rename src/{test_instances => mytests/instances}/78.gr (100%) rename src/{test_instances => mytests/instances}/79.gr (100%) rename src/{test_instances => mytests/instances}/8.gr (100%) rename src/{test_instances => mytests/instances}/80.gr (100%) rename src/{test_instances => mytests/instances}/81.gr (100%) rename src/{test_instances => mytests/instances}/82.gr (100%) rename src/{test_instances => mytests/instances}/83.gr (100%) rename src/{test_instances => mytests/instances}/84.gr (100%) rename src/{test_instances => mytests/instances}/85.gr (100%) rename src/{test_instances => mytests/instances}/86.gr (100%) rename src/{test_instances => mytests/instances}/87.gr (100%) rename src/{test_instances => mytests/instances}/88.gr (100%) rename src/{test_instances => mytests/instances}/89.gr (100%) rename src/{test_instances => mytests/instances}/9.gr (100%) rename src/{test_instances => mytests/instances}/90.gr (100%) rename src/{test_instances => mytests/instances}/91.gr (100%) rename src/{test_instances => mytests/instances}/92.gr (100%) rename src/{test_instances => mytests/instances}/93.gr (100%) rename src/{test_instances => mytests/instances}/94.gr (100%) rename src/{test_instances => mytests/instances}/95.gr (100%) rename src/{test_instances => mytests/instances}/96.gr (100%) rename src/{test_instances => mytests/instances}/97.gr (100%) rename src/{test_instances => mytests/instances}/98.gr (100%) rename src/{test_instances => mytests/instances}/99.gr (100%) create mode 100644 src/mytests/solutions/0.sol rename src/{solution_instances => mytests/solutions}/1.sol (100%) create mode 100644 src/mytests/solutions/complete_4_5.sol rename src/{githubtests/tiny_test_set/solutions/complete_4_5.sol => mytests/solutions/cycle_8_shuffled.sol} (88%) create mode 100644 src/mytests/solutions/cycle_8_sorted.sol create mode 100644 src/mytests/solutions/grid_9_shuffled.sol create mode 100644 src/mytests/solutions/ladder_4_4_shuffled.sol create mode 100644 src/mytests/solutions/ladder_4_4_sorted.sol create mode 100644 src/mytests/solutions/matching_4_4.sol create mode 100644 src/mytests/solutions/path_9_shuffled.sol create mode 100644 src/mytests/solutions/path_9_sorted.sol rename src/{solution_instances => mytests/solutions}/plane_5_6.sol (51%) create mode 100644 src/mytests/solutions/star_6.sol rename src/{solution_instances => mytests/solutions}/tree_6_10.sol (65%) rename src/{solution_instances => mytests/solutions}/website_20.sol (68%) create mode 100644 src/solver.bat create mode 100644 src/solver.py diff --git a/__pycache__/visualizer.cpython-311.pyc b/__pycache__/visualizer.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3644ac9b9c653403cbe4f1b02b6d6cd3d978a06e GIT binary patch literal 48545 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ƺr%e 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 literal 0 HcmV?d00001 diff --git a/src/README.md b/src/README.md index 758aa43..66911e8 100644 --- a/src/README.md +++ b/src/README.md @@ -7,5 +7,11 @@ xij = 1 bedeutet, dass π1(i) < π1(j) — Knoten i kommt vor Knoten j in der er yij = 1 bedeutet, dass π2(i) < π2(j) — Knoten i kommt vor Knoten j in der zweiten Permutation. main: logged nur das wesentliche + backupmain: aktuelles backup -foretesting: gleiches wie main, nur mit konsolen output, was nur für kleine graphen etwas bringt. \ No newline at end of file + +foretesting: gleiches wie main, nur mit konsolen output, was nur für kleine graphen etwas bringt. + +solver.py: Funktion die 2 Argumente übernimmt, Inputgraph und Outputgraph. Wird für den pace2024tester genutzt. + +solver.bat: Script für windwos, welches die solver.py mit den beiden Konsolen Inputs ausführt. \ No newline at end of file diff --git a/src/archive/logfile.log b/src/archive/logfile.log new file mode 100644 index 0000000..ebd0169 --- /dev/null +++ b/src/archive/logfile.log @@ -0,0 +1,26 @@ +2024-05-10 18:20:35,031 - INFO - Prozess f�r test_instances/0.gr gestartet +2024-05-10 18:20:35,032 - INFO - Die Ausgabedatei wird solution_instances\0.sol sein +2024-05-10 18:20:35,032 - INFO - Gr��en der Partitionen: A=3, B=3 +2024-05-10 18:20:35,033 - INFO - 3 Kanten geladen. +2024-05-10 18:20:35,033 - INFO - x, y und c geladen. +2024-05-10 18:20:35,033 - INFO - Zielfunktion aufgestellt. +2024-05-10 18:20:35,034 - INFO - Crossing Constraints aufgestellt. +2024-05-10 18:20:35,050 - INFO - Status der L�sung: Optimal +2024-05-10 18:20:35,050 - INFO - Optimale L�sung gefunden. Ergebnisse werden gespeichert. +2024-05-10 18:20:35,051 - INFO - Ergebnisse in solution_instances\0.sol gespeichert +2024-05-10 18:20:35,052 - INFO - Crossings: 0, in solution_instances\0.cros gespeichert +2024-05-10 18:20:35,052 - INFO - Verstrichene Zeit: 0:00:00.021 (h:m:s.ms) + +2024-05-10 18:20:35,053 - INFO - Verarbeitung abgeschlossen f�r test_instances/0.gr +2024-05-10 18:20:35,053 - INFO - Prozess f�r test_instances/1.gr gestartet +2024-05-10 18:20:35,053 - INFO - Die Ausgabedatei wird solution_instances\1.sol sein +2024-05-10 18:20:35,053 - INFO - Gr��en der Partitionen: A=780, B=743 +2024-05-10 18:20:35,055 - INFO - 1522 Kanten geladen. +2024-05-10 18:20:37,375 - INFO - x, y und c geladen. +2024-05-10 18:20:37,648 - INFO - Zielfunktion aufgestellt. +2024-05-10 18:20:44,635 - INFO - Crossing Constraints aufgestellt. +2024-05-10 18:51:32,831 - INFO - Status der L�sung: Optimal +2024-05-10 18:51:32,832 - INFO - Optimale L�sung gefunden. Ergebnisse werden gespeichert. +2024-05-10 18:51:32,990 - INFO - Ergebnisse in solution_instances\1.sol gespeichert +2024-05-10 18:51:33,029 - INFO - Crossings: 1482, in solution_instances\1.cros gespeichert +2024-05-10 18:51:33,030 - INFO - Verstrichene Zeit: 0:30:57.977 (h:m:s.ms) \ No newline at end of file diff --git a/src/fortesting.py b/src/fortesting.py index 880385c..4a3b585 100644 --- a/src/fortesting.py +++ b/src/fortesting.py @@ -174,10 +174,10 @@ def process_directory(directory_path): solve_bipartite_minimization(file_path) # Rufe die Verarbeitungsfunktion für jede .gr Datei auf logging.info(f"Verarbeitung abgeschlossen für {file_path}") - +""" directory_path = 'githubtests/tiny_test_set/instances/' process_directory(directory_path) - -#test_file = 'githubtests/tiny_test_set/instances/complete_4_5.gr' +""" +test_file = 'githubtests/tiny_test_set/instances/complete_4_5.gr' #test_file = 'test_instances/0.gr' -#solve_bipartite_minimization(test_file) +solve_bipartite_minimization(test_file) diff --git a/src/main.py b/src/main.py index 9c03128..27e69b0 100644 --- a/src/main.py +++ b/src/main.py @@ -1,19 +1,34 @@ import os import logging +import time +from datetime import datetime, timedelta 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') + +# Erstelle einen FileHandler und einen StreamHandler +file_handler = logging.FileHandler('logfile.log') +console_handler = logging.StreamHandler() +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[file_handler, console_handler]) + +def count_crossings_via_variables(c_vars): + crossings = 0 + for c_var in c_vars.values(): + if c_var.varValue == 1: + crossings += 1 + return(crossings) def solve_bipartite_minimization(graph_file): + start_time = time() 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') + new_base_name1 = base_name.replace('.gr', '.cros') # Erstelle den Ausgabepfad - output_file = os.path.join('solution_instances', new_base_name) + output_file = os.path.join('mytests/solutions', new_base_name) + output_file1 = os.path.join('mytests/crossings', new_base_name1) logging.info(f"Die Ausgabedatei wird {output_file} sein") edges = [] @@ -37,18 +52,11 @@ def solve_bipartite_minimization(graph_file): 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') - """ + # Zielfunktion, die minimiert werden soll prob += lpSum(c.values()) logging.info("Zielfunktion aufgestellt.") - """ + edges.sort(key=lambda x: x[0]) # Sortieren der Kanten nach dem Startknoten for idx, (i, j) in enumerate(edges): for (k, l) in edges[idx + 1:]: @@ -60,36 +68,10 @@ def solve_bipartite_minimization(graph_file): elif l > j: prob += c[(i, j, k, l)] == 1 - y[(j, l)] logging.info("Crossing Constraints aufgestellt.") - """ - # 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.") - - 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}") - """ if prob.status == LpStatusOptimal: logging.info("Optimale Lösung gefunden. Ergebnisse werden gespeichert.") @@ -128,11 +110,34 @@ def solve_bipartite_minimization(graph_file): os.makedirs(os.path.dirname(output_file), exist_ok=True) with open(output_file, 'w') as f: for b in sorted_b: - f.write(f"{b}\n") + f.write(f"{b}\n") logging.info(f"Ergebnisse in {output_file} gespeichert") + # Ausgabe der sortierten Knoten + + a = count_crossings_via_variables(c) + + os.makedirs(os.path.dirname(output_file1), exist_ok=True) + with open(output_file1, 'w') as f: + f.write(f"Crossings: {a}\n") + logging.info(f"Crossings: {a}, in {output_file1} gespeichert") + + end_time = time() + elapsed_time = end_time - start_time + elapsed_time_td = timedelta(seconds=elapsed_time) + formatted_time = str(elapsed_time_td) # '0:00:01.234000' für das obige Beispiel + formatted_time = formatted_time[:-3] + logging.info(f"Verstrichene Zeit: {formatted_time} (h:m:s.ms) \n") else: logging.warning("Keine optimale Lösung gefunden.") + end_time = time() + elapsed_time = end_time - start_time + elapsed_time_td = timedelta(seconds=elapsed_time) + formatted_time = str(elapsed_time_td) # '0:00:01.234000' für das obige Beispiel + formatted_time = formatted_time[:-3] + logging.info(f"Verstrichene Zeit: {formatted_time} (h:m:s.ms) \n") + + def process_directory(directory_path): # Durchlaufe alle Dateien im angegebenen Verzeichnis for filename in os.listdir(directory_path): @@ -141,11 +146,13 @@ def process_directory(directory_path): solve_bipartite_minimization(file_path) # Rufe die Verarbeitungsfunktion für jede .gr Datei auf logging.info(f"Verarbeitung abgeschlossen für {file_path}") -""" + directory_path = 'githubtests/tiny_test_set/instances/' +#directory_path = 'mytests/instances/' process_directory(directory_path) -""" -#test_file = 'githubtests/tiny_test_set/instances/grid_9_shuffled.gr' -test_file = 'test_instances/1.gr' +""" +test_file = 'githubtests/tiny_test_set/instances/complete_4_5.gr' +#test_file = 'mytests/instances/2.gr' solve_bipartite_minimization(test_file) +""" \ No newline at end of file diff --git a/src/solution_instances/0.sol b/src/mytests/crossings/0.cros similarity index 68% rename from src/solution_instances/0.sol rename to src/mytests/crossings/0.cros index c9a1c67..edbe1c0 100644 --- a/src/solution_instances/0.sol +++ b/src/mytests/crossings/0.cros @@ -1,4 +1 @@ -5 -4 -6 Crossings: 0 diff --git a/src/mytests/crossings/1.cros b/src/mytests/crossings/1.cros new file mode 100644 index 0000000..b168036 --- /dev/null +++ b/src/mytests/crossings/1.cros @@ -0,0 +1 @@ +Crossings: 1482 diff --git a/src/solution_instances/complete_4_5.sol b/src/mytests/crossings/complete_4_5.cros similarity index 58% rename from src/solution_instances/complete_4_5.sol rename to src/mytests/crossings/complete_4_5.cros index ea99ee2..40161bc 100644 --- a/src/solution_instances/complete_4_5.sol +++ b/src/mytests/crossings/complete_4_5.cros @@ -1,6 +1 @@ -9 -8 -7 -6 -5 Crossings: 60 diff --git a/src/solution_instances/cycle_8_shuffled.sol b/src/mytests/crossings/cycle_8_shuffled.cros similarity index 61% rename from src/solution_instances/cycle_8_shuffled.sol rename to src/mytests/crossings/cycle_8_shuffled.cros index b2cb16c..b4ce40d 100644 --- a/src/solution_instances/cycle_8_shuffled.sol +++ b/src/mytests/crossings/cycle_8_shuffled.cros @@ -1,5 +1 @@ -6 -7 -8 -5 Crossings: 4 diff --git a/src/solution_instances/cycle_8_sorted.sol b/src/mytests/crossings/cycle_8_sorted.cros similarity index 61% rename from src/solution_instances/cycle_8_sorted.sol rename to src/mytests/crossings/cycle_8_sorted.cros index ce4c234..4ec4c4e 100644 --- a/src/solution_instances/cycle_8_sorted.sol +++ b/src/mytests/crossings/cycle_8_sorted.cros @@ -1,5 +1 @@ -5 -7 -6 -8 Crossings: 3 diff --git a/src/solution_instances/grid_9_shuffled.sol b/src/mytests/crossings/grid_9_shuffled.cros similarity index 58% rename from src/solution_instances/grid_9_shuffled.sol rename to src/mytests/crossings/grid_9_shuffled.cros index 24d0b71..add6133 100644 --- a/src/solution_instances/grid_9_shuffled.sol +++ b/src/mytests/crossings/grid_9_shuffled.cros @@ -1,6 +1 @@ -8 -9 -7 -5 -6 Crossings: 17 diff --git a/src/solution_instances/ladder_4_4_shuffled.sol b/src/mytests/crossings/ladder_4_4_shuffled.cros similarity index 63% rename from src/solution_instances/ladder_4_4_shuffled.sol rename to src/mytests/crossings/ladder_4_4_shuffled.cros index d20ccb4..7caca1e 100644 --- a/src/solution_instances/ladder_4_4_shuffled.sol +++ b/src/mytests/crossings/ladder_4_4_shuffled.cros @@ -1,5 +1 @@ -6 -8 -5 -7 Crossings: 11 diff --git a/src/solution_instances/ladder_4_4_sorted.sol b/src/mytests/crossings/ladder_4_4_sorted.cros similarity index 61% rename from src/solution_instances/ladder_4_4_sorted.sol rename to src/mytests/crossings/ladder_4_4_sorted.cros index 35f149c..4ec4c4e 100644 --- a/src/solution_instances/ladder_4_4_sorted.sol +++ b/src/mytests/crossings/ladder_4_4_sorted.cros @@ -1,5 +1 @@ -5 -8 -7 -6 Crossings: 3 diff --git a/src/solution_instances/matching_4_4.sol b/src/mytests/crossings/matching_4_4.cros similarity index 61% rename from src/solution_instances/matching_4_4.sol rename to src/mytests/crossings/matching_4_4.cros index 1370cd6..edbe1c0 100644 --- a/src/solution_instances/matching_4_4.sol +++ b/src/mytests/crossings/matching_4_4.cros @@ -1,5 +1 @@ -7 -5 -6 -8 Crossings: 0 diff --git a/src/solution_instances/path_9_shuffled.sol b/src/mytests/crossings/path_9_shuffled.cros similarity index 61% rename from src/solution_instances/path_9_shuffled.sol rename to src/mytests/crossings/path_9_shuffled.cros index a12444e..7b687de 100644 --- a/src/solution_instances/path_9_shuffled.sol +++ b/src/mytests/crossings/path_9_shuffled.cros @@ -1,5 +1 @@ -8 -6 -7 -9 Crossings: 6 diff --git a/src/solution_instances/path_9_sorted.sol b/src/mytests/crossings/path_9_sorted.cros similarity index 61% rename from src/solution_instances/path_9_sorted.sol rename to src/mytests/crossings/path_9_sorted.cros index 082ab63..edbe1c0 100644 --- a/src/solution_instances/path_9_sorted.sol +++ b/src/mytests/crossings/path_9_sorted.cros @@ -1,5 +1 @@ -7 -9 -6 -8 Crossings: 0 diff --git a/src/solution_instances/star_6.sol b/src/mytests/crossings/plane_5_6.cros similarity index 52% rename from src/solution_instances/star_6.sol rename to src/mytests/crossings/plane_5_6.cros index 835c636..edbe1c0 100644 --- a/src/solution_instances/star_6.sol +++ b/src/mytests/crossings/plane_5_6.cros @@ -1,7 +1 @@ -3 -5 -7 -4 -6 -8 Crossings: 0 diff --git a/src/mytests/crossings/star_6.cros b/src/mytests/crossings/star_6.cros new file mode 100644 index 0000000..edbe1c0 --- /dev/null +++ b/src/mytests/crossings/star_6.cros @@ -0,0 +1 @@ +Crossings: 0 diff --git a/src/mytests/crossings/tree_6_10.cros b/src/mytests/crossings/tree_6_10.cros new file mode 100644 index 0000000..2568636 --- /dev/null +++ b/src/mytests/crossings/tree_6_10.cros @@ -0,0 +1 @@ +Crossings: 13 diff --git a/src/mytests/crossings/website_20.cros b/src/mytests/crossings/website_20.cros new file mode 100644 index 0000000..add6133 --- /dev/null +++ b/src/mytests/crossings/website_20.cros @@ -0,0 +1 @@ +Crossings: 17 diff --git a/src/test_instances/0.gr b/src/mytests/instances/0.gr similarity index 100% rename from src/test_instances/0.gr rename to src/mytests/instances/0.gr diff --git a/src/test_instances/1.gr b/src/mytests/instances/1.gr similarity index 100% rename from src/test_instances/1.gr rename to src/mytests/instances/1.gr diff --git a/src/test_instances/10.gr b/src/mytests/instances/10.gr similarity index 100% rename from src/test_instances/10.gr rename to src/mytests/instances/10.gr diff --git a/src/test_instances/100.gr b/src/mytests/instances/100.gr similarity index 100% rename from src/test_instances/100.gr rename to src/mytests/instances/100.gr diff --git a/src/test_instances/11.gr b/src/mytests/instances/11.gr similarity index 100% rename from src/test_instances/11.gr rename to src/mytests/instances/11.gr diff --git a/src/test_instances/12.gr b/src/mytests/instances/12.gr similarity index 100% rename from src/test_instances/12.gr rename to src/mytests/instances/12.gr diff --git a/src/test_instances/13.gr b/src/mytests/instances/13.gr similarity index 100% rename from src/test_instances/13.gr rename to src/mytests/instances/13.gr diff --git a/src/test_instances/14.gr b/src/mytests/instances/14.gr similarity index 100% rename from src/test_instances/14.gr rename to src/mytests/instances/14.gr diff --git a/src/test_instances/15.gr b/src/mytests/instances/15.gr similarity index 100% rename from src/test_instances/15.gr rename to src/mytests/instances/15.gr diff --git a/src/test_instances/16.gr b/src/mytests/instances/16.gr similarity index 100% rename from src/test_instances/16.gr rename to src/mytests/instances/16.gr diff --git a/src/test_instances/17.gr b/src/mytests/instances/17.gr similarity index 100% rename from src/test_instances/17.gr rename to src/mytests/instances/17.gr diff --git a/src/test_instances/18.gr b/src/mytests/instances/18.gr similarity index 100% rename from src/test_instances/18.gr rename to src/mytests/instances/18.gr diff --git a/src/test_instances/19.gr b/src/mytests/instances/19.gr similarity index 100% rename from src/test_instances/19.gr rename to src/mytests/instances/19.gr diff --git a/src/test_instances/2.gr b/src/mytests/instances/2.gr similarity index 100% rename from src/test_instances/2.gr rename to src/mytests/instances/2.gr diff --git a/src/test_instances/20.gr b/src/mytests/instances/20.gr similarity index 100% rename from src/test_instances/20.gr rename to src/mytests/instances/20.gr diff --git a/src/test_instances/21.gr b/src/mytests/instances/21.gr similarity index 100% rename from src/test_instances/21.gr rename to src/mytests/instances/21.gr diff --git a/src/test_instances/22.gr b/src/mytests/instances/22.gr similarity index 100% rename from src/test_instances/22.gr rename to src/mytests/instances/22.gr diff --git a/src/test_instances/23.gr b/src/mytests/instances/23.gr similarity index 100% rename from src/test_instances/23.gr rename to src/mytests/instances/23.gr diff --git a/src/test_instances/24.gr b/src/mytests/instances/24.gr similarity index 100% rename from src/test_instances/24.gr rename to src/mytests/instances/24.gr diff --git a/src/test_instances/25.gr b/src/mytests/instances/25.gr similarity index 100% rename from src/test_instances/25.gr rename to src/mytests/instances/25.gr diff --git a/src/test_instances/26.gr b/src/mytests/instances/26.gr similarity index 100% rename from src/test_instances/26.gr rename to src/mytests/instances/26.gr diff --git a/src/test_instances/27.gr b/src/mytests/instances/27.gr similarity index 100% rename from src/test_instances/27.gr rename to src/mytests/instances/27.gr diff --git a/src/test_instances/28.gr b/src/mytests/instances/28.gr similarity index 100% rename from src/test_instances/28.gr rename to src/mytests/instances/28.gr diff --git a/src/test_instances/29.gr b/src/mytests/instances/29.gr similarity index 100% rename from src/test_instances/29.gr rename to src/mytests/instances/29.gr diff --git a/src/test_instances/3.gr b/src/mytests/instances/3.gr similarity index 100% rename from src/test_instances/3.gr rename to src/mytests/instances/3.gr diff --git a/src/test_instances/30.gr b/src/mytests/instances/30.gr similarity index 100% rename from src/test_instances/30.gr rename to src/mytests/instances/30.gr diff --git a/src/test_instances/31.gr b/src/mytests/instances/31.gr similarity index 100% rename from src/test_instances/31.gr rename to src/mytests/instances/31.gr diff --git a/src/test_instances/32.gr b/src/mytests/instances/32.gr similarity index 100% rename from src/test_instances/32.gr rename to src/mytests/instances/32.gr diff --git a/src/test_instances/33.gr b/src/mytests/instances/33.gr similarity index 100% rename from src/test_instances/33.gr rename to src/mytests/instances/33.gr diff --git a/src/test_instances/34.gr b/src/mytests/instances/34.gr similarity index 100% rename from src/test_instances/34.gr rename to src/mytests/instances/34.gr diff --git a/src/test_instances/35.gr b/src/mytests/instances/35.gr similarity index 100% rename from src/test_instances/35.gr rename to src/mytests/instances/35.gr diff --git a/src/test_instances/36.gr b/src/mytests/instances/36.gr similarity index 100% rename from src/test_instances/36.gr rename to src/mytests/instances/36.gr diff --git a/src/test_instances/37.gr b/src/mytests/instances/37.gr similarity index 100% rename from src/test_instances/37.gr rename to src/mytests/instances/37.gr diff --git a/src/test_instances/38.gr b/src/mytests/instances/38.gr similarity index 100% rename from src/test_instances/38.gr rename to src/mytests/instances/38.gr diff --git a/src/test_instances/39.gr b/src/mytests/instances/39.gr similarity index 100% rename from src/test_instances/39.gr rename to src/mytests/instances/39.gr diff --git a/src/test_instances/4.gr b/src/mytests/instances/4.gr similarity index 100% rename from src/test_instances/4.gr rename to src/mytests/instances/4.gr diff --git a/src/test_instances/40.gr b/src/mytests/instances/40.gr similarity index 100% rename from src/test_instances/40.gr rename to src/mytests/instances/40.gr diff --git a/src/test_instances/41.gr b/src/mytests/instances/41.gr similarity index 100% rename from src/test_instances/41.gr rename to src/mytests/instances/41.gr diff --git a/src/test_instances/42.gr b/src/mytests/instances/42.gr similarity index 100% rename from src/test_instances/42.gr rename to src/mytests/instances/42.gr diff --git a/src/test_instances/43.gr b/src/mytests/instances/43.gr similarity index 100% rename from src/test_instances/43.gr rename to src/mytests/instances/43.gr diff --git a/src/test_instances/44.gr b/src/mytests/instances/44.gr similarity index 100% rename from src/test_instances/44.gr rename to src/mytests/instances/44.gr diff --git a/src/test_instances/45.gr b/src/mytests/instances/45.gr similarity index 100% rename from src/test_instances/45.gr rename to src/mytests/instances/45.gr diff --git a/src/test_instances/46.gr b/src/mytests/instances/46.gr similarity index 100% rename from src/test_instances/46.gr rename to src/mytests/instances/46.gr diff --git a/src/test_instances/47.gr b/src/mytests/instances/47.gr similarity index 100% rename from src/test_instances/47.gr rename to src/mytests/instances/47.gr diff --git a/src/test_instances/48.gr b/src/mytests/instances/48.gr similarity index 100% rename from src/test_instances/48.gr rename to src/mytests/instances/48.gr diff --git a/src/test_instances/49.gr b/src/mytests/instances/49.gr similarity index 100% rename from src/test_instances/49.gr rename to src/mytests/instances/49.gr diff --git a/src/test_instances/5.gr b/src/mytests/instances/5.gr similarity index 100% rename from src/test_instances/5.gr rename to src/mytests/instances/5.gr diff --git a/src/test_instances/50.gr b/src/mytests/instances/50.gr similarity index 100% rename from src/test_instances/50.gr rename to src/mytests/instances/50.gr diff --git a/src/test_instances/51.gr b/src/mytests/instances/51.gr similarity index 100% rename from src/test_instances/51.gr rename to src/mytests/instances/51.gr diff --git a/src/test_instances/52.gr b/src/mytests/instances/52.gr similarity index 100% rename from src/test_instances/52.gr rename to src/mytests/instances/52.gr diff --git a/src/test_instances/53.gr b/src/mytests/instances/53.gr similarity index 100% rename from src/test_instances/53.gr rename to src/mytests/instances/53.gr diff --git a/src/test_instances/54.gr b/src/mytests/instances/54.gr similarity index 100% rename from src/test_instances/54.gr rename to src/mytests/instances/54.gr diff --git a/src/test_instances/55.gr b/src/mytests/instances/55.gr similarity index 100% rename from src/test_instances/55.gr rename to src/mytests/instances/55.gr diff --git a/src/test_instances/56.gr b/src/mytests/instances/56.gr similarity index 100% rename from src/test_instances/56.gr rename to src/mytests/instances/56.gr diff --git a/src/test_instances/57.gr b/src/mytests/instances/57.gr similarity index 100% rename from src/test_instances/57.gr rename to src/mytests/instances/57.gr diff --git a/src/test_instances/58.gr b/src/mytests/instances/58.gr similarity index 100% rename from src/test_instances/58.gr rename to src/mytests/instances/58.gr diff --git a/src/test_instances/59.gr b/src/mytests/instances/59.gr similarity index 100% rename from src/test_instances/59.gr rename to src/mytests/instances/59.gr diff --git a/src/test_instances/6.gr b/src/mytests/instances/6.gr similarity index 100% rename from src/test_instances/6.gr rename to src/mytests/instances/6.gr diff --git a/src/test_instances/60.gr b/src/mytests/instances/60.gr similarity index 100% rename from src/test_instances/60.gr rename to src/mytests/instances/60.gr diff --git a/src/test_instances/61.gr b/src/mytests/instances/61.gr similarity index 100% rename from src/test_instances/61.gr rename to src/mytests/instances/61.gr diff --git a/src/test_instances/62.gr b/src/mytests/instances/62.gr similarity index 100% rename from src/test_instances/62.gr rename to src/mytests/instances/62.gr diff --git a/src/test_instances/63.gr b/src/mytests/instances/63.gr similarity index 100% rename from src/test_instances/63.gr rename to src/mytests/instances/63.gr diff --git a/src/test_instances/64.gr b/src/mytests/instances/64.gr similarity index 100% rename from src/test_instances/64.gr rename to src/mytests/instances/64.gr diff --git a/src/test_instances/65.gr b/src/mytests/instances/65.gr similarity index 100% rename from src/test_instances/65.gr rename to src/mytests/instances/65.gr diff --git a/src/test_instances/66.gr b/src/mytests/instances/66.gr similarity index 100% rename from src/test_instances/66.gr rename to src/mytests/instances/66.gr diff --git a/src/test_instances/67.gr b/src/mytests/instances/67.gr similarity index 100% rename from src/test_instances/67.gr rename to src/mytests/instances/67.gr diff --git a/src/test_instances/68.gr b/src/mytests/instances/68.gr similarity index 100% rename from src/test_instances/68.gr rename to src/mytests/instances/68.gr diff --git a/src/test_instances/69.gr b/src/mytests/instances/69.gr similarity index 100% rename from src/test_instances/69.gr rename to src/mytests/instances/69.gr diff --git a/src/test_instances/7.gr b/src/mytests/instances/7.gr similarity index 100% rename from src/test_instances/7.gr rename to src/mytests/instances/7.gr diff --git a/src/test_instances/70.gr b/src/mytests/instances/70.gr similarity index 100% rename from src/test_instances/70.gr rename to src/mytests/instances/70.gr diff --git a/src/test_instances/71.gr b/src/mytests/instances/71.gr similarity index 100% rename from src/test_instances/71.gr rename to src/mytests/instances/71.gr diff --git a/src/test_instances/72.gr b/src/mytests/instances/72.gr similarity index 100% rename from src/test_instances/72.gr rename to src/mytests/instances/72.gr diff --git a/src/test_instances/73.gr b/src/mytests/instances/73.gr similarity index 100% rename from src/test_instances/73.gr rename to src/mytests/instances/73.gr diff --git a/src/test_instances/74.gr b/src/mytests/instances/74.gr similarity index 100% rename from src/test_instances/74.gr rename to src/mytests/instances/74.gr diff --git a/src/test_instances/75.gr b/src/mytests/instances/75.gr similarity index 100% rename from src/test_instances/75.gr rename to src/mytests/instances/75.gr diff --git a/src/test_instances/76.gr b/src/mytests/instances/76.gr similarity index 100% rename from src/test_instances/76.gr rename to src/mytests/instances/76.gr diff --git a/src/test_instances/77.gr b/src/mytests/instances/77.gr similarity index 100% rename from src/test_instances/77.gr rename to src/mytests/instances/77.gr diff --git a/src/test_instances/78.gr b/src/mytests/instances/78.gr similarity index 100% rename from src/test_instances/78.gr rename to src/mytests/instances/78.gr diff --git a/src/test_instances/79.gr b/src/mytests/instances/79.gr similarity index 100% rename from src/test_instances/79.gr rename to src/mytests/instances/79.gr diff --git a/src/test_instances/8.gr b/src/mytests/instances/8.gr similarity index 100% rename from src/test_instances/8.gr rename to src/mytests/instances/8.gr diff --git a/src/test_instances/80.gr b/src/mytests/instances/80.gr similarity index 100% rename from src/test_instances/80.gr rename to src/mytests/instances/80.gr diff --git a/src/test_instances/81.gr b/src/mytests/instances/81.gr similarity index 100% rename from src/test_instances/81.gr rename to src/mytests/instances/81.gr diff --git a/src/test_instances/82.gr b/src/mytests/instances/82.gr similarity index 100% rename from src/test_instances/82.gr rename to src/mytests/instances/82.gr diff --git a/src/test_instances/83.gr b/src/mytests/instances/83.gr similarity index 100% rename from src/test_instances/83.gr rename to src/mytests/instances/83.gr diff --git a/src/test_instances/84.gr b/src/mytests/instances/84.gr similarity index 100% rename from src/test_instances/84.gr rename to src/mytests/instances/84.gr diff --git a/src/test_instances/85.gr b/src/mytests/instances/85.gr similarity index 100% rename from src/test_instances/85.gr rename to src/mytests/instances/85.gr diff --git a/src/test_instances/86.gr b/src/mytests/instances/86.gr similarity index 100% rename from src/test_instances/86.gr rename to src/mytests/instances/86.gr diff --git a/src/test_instances/87.gr b/src/mytests/instances/87.gr similarity index 100% rename from src/test_instances/87.gr rename to src/mytests/instances/87.gr diff --git a/src/test_instances/88.gr b/src/mytests/instances/88.gr similarity index 100% rename from src/test_instances/88.gr rename to src/mytests/instances/88.gr diff --git a/src/test_instances/89.gr b/src/mytests/instances/89.gr similarity index 100% rename from src/test_instances/89.gr rename to src/mytests/instances/89.gr diff --git a/src/test_instances/9.gr b/src/mytests/instances/9.gr similarity index 100% rename from src/test_instances/9.gr rename to src/mytests/instances/9.gr diff --git a/src/test_instances/90.gr b/src/mytests/instances/90.gr similarity index 100% rename from src/test_instances/90.gr rename to src/mytests/instances/90.gr diff --git a/src/test_instances/91.gr b/src/mytests/instances/91.gr similarity index 100% rename from src/test_instances/91.gr rename to src/mytests/instances/91.gr diff --git a/src/test_instances/92.gr b/src/mytests/instances/92.gr similarity index 100% rename from src/test_instances/92.gr rename to src/mytests/instances/92.gr diff --git a/src/test_instances/93.gr b/src/mytests/instances/93.gr similarity index 100% rename from src/test_instances/93.gr rename to src/mytests/instances/93.gr diff --git a/src/test_instances/94.gr b/src/mytests/instances/94.gr similarity index 100% rename from src/test_instances/94.gr rename to src/mytests/instances/94.gr diff --git a/src/test_instances/95.gr b/src/mytests/instances/95.gr similarity index 100% rename from src/test_instances/95.gr rename to src/mytests/instances/95.gr diff --git a/src/test_instances/96.gr b/src/mytests/instances/96.gr similarity index 100% rename from src/test_instances/96.gr rename to src/mytests/instances/96.gr diff --git a/src/test_instances/97.gr b/src/mytests/instances/97.gr similarity index 100% rename from src/test_instances/97.gr rename to src/mytests/instances/97.gr diff --git a/src/test_instances/98.gr b/src/mytests/instances/98.gr similarity index 100% rename from src/test_instances/98.gr rename to src/mytests/instances/98.gr diff --git a/src/test_instances/99.gr b/src/mytests/instances/99.gr similarity index 100% rename from src/test_instances/99.gr rename to src/mytests/instances/99.gr diff --git a/src/mytests/solutions/0.sol b/src/mytests/solutions/0.sol new file mode 100644 index 0000000..292ff76 --- /dev/null +++ b/src/mytests/solutions/0.sol @@ -0,0 +1,3 @@ +5 +4 +6 diff --git a/src/solution_instances/1.sol b/src/mytests/solutions/1.sol similarity index 100% rename from src/solution_instances/1.sol rename to src/mytests/solutions/1.sol diff --git a/src/mytests/solutions/complete_4_5.sol b/src/mytests/solutions/complete_4_5.sol new file mode 100644 index 0000000..b040bdf --- /dev/null +++ b/src/mytests/solutions/complete_4_5.sol @@ -0,0 +1,5 @@ +9 +8 +7 +6 +5 diff --git a/src/githubtests/tiny_test_set/solutions/complete_4_5.sol b/src/mytests/solutions/cycle_8_shuffled.sol similarity index 88% rename from src/githubtests/tiny_test_set/solutions/complete_4_5.sol rename to src/mytests/solutions/cycle_8_shuffled.sol index 56593e1..3590b12 100644 --- a/src/githubtests/tiny_test_set/solutions/complete_4_5.sol +++ b/src/mytests/solutions/cycle_8_shuffled.sol @@ -1,5 +1,4 @@ -5 6 7 8 -9 \ No newline at end of file +5 diff --git a/src/mytests/solutions/cycle_8_sorted.sol b/src/mytests/solutions/cycle_8_sorted.sol new file mode 100644 index 0000000..5957c0f --- /dev/null +++ b/src/mytests/solutions/cycle_8_sorted.sol @@ -0,0 +1,4 @@ +5 +7 +6 +8 diff --git a/src/mytests/solutions/grid_9_shuffled.sol b/src/mytests/solutions/grid_9_shuffled.sol new file mode 100644 index 0000000..486c190 --- /dev/null +++ b/src/mytests/solutions/grid_9_shuffled.sol @@ -0,0 +1,5 @@ +8 +9 +7 +5 +6 diff --git a/src/mytests/solutions/ladder_4_4_shuffled.sol b/src/mytests/solutions/ladder_4_4_shuffled.sol new file mode 100644 index 0000000..c213181 --- /dev/null +++ b/src/mytests/solutions/ladder_4_4_shuffled.sol @@ -0,0 +1,4 @@ +6 +8 +5 +7 diff --git a/src/mytests/solutions/ladder_4_4_sorted.sol b/src/mytests/solutions/ladder_4_4_sorted.sol new file mode 100644 index 0000000..701bf8a --- /dev/null +++ b/src/mytests/solutions/ladder_4_4_sorted.sol @@ -0,0 +1,4 @@ +5 +8 +7 +6 diff --git a/src/mytests/solutions/matching_4_4.sol b/src/mytests/solutions/matching_4_4.sol new file mode 100644 index 0000000..95fc5e4 --- /dev/null +++ b/src/mytests/solutions/matching_4_4.sol @@ -0,0 +1,4 @@ +7 +5 +6 +8 diff --git a/src/mytests/solutions/path_9_shuffled.sol b/src/mytests/solutions/path_9_shuffled.sol new file mode 100644 index 0000000..e8af654 --- /dev/null +++ b/src/mytests/solutions/path_9_shuffled.sol @@ -0,0 +1,4 @@ +8 +6 +7 +9 diff --git a/src/mytests/solutions/path_9_sorted.sol b/src/mytests/solutions/path_9_sorted.sol new file mode 100644 index 0000000..b86e099 --- /dev/null +++ b/src/mytests/solutions/path_9_sorted.sol @@ -0,0 +1,4 @@ +7 +9 +6 +8 diff --git a/src/solution_instances/plane_5_6.sol b/src/mytests/solutions/plane_5_6.sol similarity index 51% rename from src/solution_instances/plane_5_6.sol rename to src/mytests/solutions/plane_5_6.sol index 44592e2..e70e8bf 100644 --- a/src/solution_instances/plane_5_6.sol +++ b/src/mytests/solutions/plane_5_6.sol @@ -4,4 +4,3 @@ 10 7 8 -Crossings: 0 diff --git a/src/mytests/solutions/star_6.sol b/src/mytests/solutions/star_6.sol new file mode 100644 index 0000000..dd866a9 --- /dev/null +++ b/src/mytests/solutions/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/mytests/solutions/tree_6_10.sol similarity index 65% rename from src/solution_instances/tree_6_10.sol rename to src/mytests/solutions/tree_6_10.sol index dedff8a..c8e2fc5 100644 --- a/src/solution_instances/tree_6_10.sol +++ b/src/mytests/solutions/tree_6_10.sol @@ -8,4 +8,3 @@ 14 15 16 -Crossings: 13 diff --git a/src/solution_instances/website_20.sol b/src/mytests/solutions/website_20.sol similarity index 68% rename from src/solution_instances/website_20.sol rename to src/mytests/solutions/website_20.sol index 37dd3ec..4d5dc4b 100644 --- a/src/solution_instances/website_20.sol +++ b/src/mytests/solutions/website_20.sol @@ -8,4 +8,3 @@ 14 16 15 -Crossings: 17 diff --git a/src/prob.lp b/src/prob.lp index 0949b7c..f4c2742 100644 --- a/src/prob.lp +++ b/src/prob.lp @@ -1,187 +1,275 @@ \* Minimize_Crossings *\ Minimize -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 +OBJ: c_1_5_2_6 + c_1_5_2_7 + c_1_5_2_8 + c_1_5_2_9 + c_1_5_3_6 + c_1_5_3_7 + + c_1_5_3_8 + c_1_5_3_9 + c_1_5_4_6 + c_1_5_4_7 + c_1_5_4_8 + c_1_5_4_9 + + c_1_6_2_5 + c_1_6_2_7 + c_1_6_2_8 + c_1_6_2_9 + c_1_6_3_5 + c_1_6_3_7 + + c_1_6_3_8 + c_1_6_3_9 + c_1_6_4_5 + c_1_6_4_7 + c_1_6_4_8 + c_1_6_4_9 + + c_1_7_2_5 + c_1_7_2_6 + c_1_7_2_8 + c_1_7_2_9 + c_1_7_3_5 + c_1_7_3_6 + + c_1_7_3_8 + c_1_7_3_9 + c_1_7_4_5 + c_1_7_4_6 + c_1_7_4_8 + c_1_7_4_9 + + c_1_8_2_5 + c_1_8_2_6 + c_1_8_2_7 + c_1_8_2_9 + c_1_8_3_5 + c_1_8_3_6 + + c_1_8_3_7 + c_1_8_3_9 + c_1_8_4_5 + c_1_8_4_6 + c_1_8_4_7 + c_1_8_4_9 + + c_1_9_2_5 + c_1_9_2_6 + c_1_9_2_7 + c_1_9_2_8 + c_1_9_3_5 + c_1_9_3_6 + + c_1_9_3_7 + c_1_9_3_8 + c_1_9_4_5 + c_1_9_4_6 + c_1_9_4_7 + c_1_9_4_8 + + c_2_5_3_6 + c_2_5_3_7 + c_2_5_3_8 + c_2_5_3_9 + c_2_5_4_6 + c_2_5_4_7 + + c_2_5_4_8 + c_2_5_4_9 + c_2_6_3_5 + c_2_6_3_7 + c_2_6_3_8 + c_2_6_3_9 + + c_2_6_4_5 + c_2_6_4_7 + c_2_6_4_8 + c_2_6_4_9 + c_2_7_3_5 + c_2_7_3_6 + + c_2_7_3_8 + c_2_7_3_9 + c_2_7_4_5 + c_2_7_4_6 + c_2_7_4_8 + c_2_7_4_9 + + c_2_8_3_5 + c_2_8_3_6 + c_2_8_3_7 + c_2_8_3_9 + c_2_8_4_5 + c_2_8_4_6 + + c_2_8_4_7 + c_2_8_4_9 + c_2_9_3_5 + c_2_9_3_6 + c_2_9_3_7 + c_2_9_3_8 + + c_2_9_4_5 + c_2_9_4_6 + c_2_9_4_7 + c_2_9_4_8 + c_3_5_4_6 + c_3_5_4_7 + + c_3_5_4_8 + c_3_5_4_9 + c_3_6_4_5 + c_3_6_4_7 + c_3_6_4_8 + c_3_6_4_9 + + c_3_7_4_5 + c_3_7_4_6 + c_3_7_4_8 + c_3_7_4_9 + c_3_8_4_5 + c_3_8_4_6 + + c_3_8_4_7 + c_3_8_4_9 + c_3_9_4_5 + c_3_9_4_6 + c_3_9_4_7 + c_3_9_4_8 Subject To -_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 +_C1: c_1_5_2_6 + y_5_6 = 1 +_C10: c_1_5_4_7 + y_5_7 = 1 +_C100: c_2_9_4_8 - y_8_9 = 0 +_C101: c_3_5_4_6 + y_5_6 = 1 +_C102: c_3_5_4_7 + y_5_7 = 1 +_C103: c_3_5_4_8 + y_5_8 = 1 +_C104: c_3_5_4_9 + y_5_9 = 1 +_C105: c_3_6_4_5 - y_5_6 = 0 +_C106: c_3_6_4_7 + y_6_7 = 1 +_C107: c_3_6_4_8 + y_6_8 = 1 +_C108: c_3_6_4_9 + y_6_9 = 1 +_C109: c_3_7_4_5 - y_5_7 = 0 +_C11: c_1_5_4_8 + y_5_8 = 1 +_C110: c_3_7_4_6 - y_6_7 = 0 +_C111: c_3_7_4_8 + y_7_8 = 1 +_C112: c_3_7_4_9 + y_7_9 = 1 +_C113: c_3_8_4_5 - y_5_8 = 0 +_C114: c_3_8_4_6 - y_6_8 = 0 +_C115: c_3_8_4_7 - y_7_8 = 0 +_C116: c_3_8_4_9 + y_8_9 = 1 +_C117: c_3_9_4_5 - y_5_9 = 0 +_C118: c_3_9_4_6 - y_6_9 = 0 +_C119: c_3_9_4_7 - y_7_9 = 0 +_C12: c_1_5_4_9 + y_5_9 = 1 +_C120: c_3_9_4_8 - y_8_9 = 0 +_C13: c_1_6_2_5 - y_5_6 = 0 +_C14: c_1_6_2_7 + y_6_7 = 1 +_C15: c_1_6_2_8 + y_6_8 = 1 +_C16: c_1_6_2_9 + y_6_9 = 1 +_C17: c_1_6_3_5 - y_5_6 = 0 +_C18: c_1_6_3_7 + y_6_7 = 1 +_C19: c_1_6_3_8 + y_6_8 = 1 +_C2: c_1_5_2_7 + y_5_7 = 1 +_C20: c_1_6_3_9 + y_6_9 = 1 +_C21: c_1_6_4_5 - y_5_6 = 0 +_C22: c_1_6_4_7 + y_6_7 = 1 +_C23: c_1_6_4_8 + y_6_8 = 1 +_C24: c_1_6_4_9 + y_6_9 = 1 +_C25: c_1_7_2_5 - y_5_7 = 0 +_C26: c_1_7_2_6 - y_6_7 = 0 +_C27: c_1_7_2_8 + y_7_8 = 1 +_C28: c_1_7_2_9 + y_7_9 = 1 +_C29: c_1_7_3_5 - y_5_7 = 0 +_C3: c_1_5_2_8 + y_5_8 = 1 +_C30: c_1_7_3_6 - y_6_7 = 0 +_C31: c_1_7_3_8 + y_7_8 = 1 +_C32: c_1_7_3_9 + y_7_9 = 1 +_C33: c_1_7_4_5 - y_5_7 = 0 +_C34: c_1_7_4_6 - y_6_7 = 0 +_C35: c_1_7_4_8 + y_7_8 = 1 +_C36: c_1_7_4_9 + y_7_9 = 1 +_C37: c_1_8_2_5 - y_5_8 = 0 +_C38: c_1_8_2_6 - y_6_8 = 0 +_C39: c_1_8_2_7 - y_7_8 = 0 +_C4: c_1_5_2_9 + y_5_9 = 1 +_C40: c_1_8_2_9 + y_8_9 = 1 +_C41: c_1_8_3_5 - y_5_8 = 0 +_C42: c_1_8_3_6 - y_6_8 = 0 +_C43: c_1_8_3_7 - y_7_8 = 0 +_C44: c_1_8_3_9 + y_8_9 = 1 +_C45: c_1_8_4_5 - y_5_8 = 0 +_C46: c_1_8_4_6 - y_6_8 = 0 +_C47: c_1_8_4_7 - y_7_8 = 0 +_C48: c_1_8_4_9 + y_8_9 = 1 +_C49: c_1_9_2_5 - y_5_9 = 0 +_C5: c_1_5_3_6 + y_5_6 = 1 +_C50: c_1_9_2_6 - y_6_9 = 0 +_C51: c_1_9_2_7 - y_7_9 = 0 +_C52: c_1_9_2_8 - y_8_9 = 0 +_C53: c_1_9_3_5 - y_5_9 = 0 +_C54: c_1_9_3_6 - y_6_9 = 0 +_C55: c_1_9_3_7 - y_7_9 = 0 +_C56: c_1_9_3_8 - y_8_9 = 0 +_C57: c_1_9_4_5 - y_5_9 = 0 +_C58: c_1_9_4_6 - y_6_9 = 0 +_C59: c_1_9_4_7 - y_7_9 = 0 +_C6: c_1_5_3_7 + y_5_7 = 1 +_C60: c_1_9_4_8 - y_8_9 = 0 +_C61: c_2_5_3_6 + y_5_6 = 1 +_C62: c_2_5_3_7 + y_5_7 = 1 +_C63: c_2_5_3_8 + y_5_8 = 1 +_C64: c_2_5_3_9 + y_5_9 = 1 +_C65: c_2_5_4_6 + y_5_6 = 1 +_C66: c_2_5_4_7 + y_5_7 = 1 +_C67: c_2_5_4_8 + y_5_8 = 1 +_C68: c_2_5_4_9 + y_5_9 = 1 +_C69: c_2_6_3_5 - y_5_6 = 0 +_C7: c_1_5_3_8 + y_5_8 = 1 +_C70: c_2_6_3_7 + y_6_7 = 1 +_C71: c_2_6_3_8 + y_6_8 = 1 +_C72: c_2_6_3_9 + y_6_9 = 1 +_C73: c_2_6_4_5 - y_5_6 = 0 +_C74: c_2_6_4_7 + y_6_7 = 1 +_C75: c_2_6_4_8 + y_6_8 = 1 +_C76: c_2_6_4_9 + y_6_9 = 1 +_C77: c_2_7_3_5 - y_5_7 = 0 +_C78: c_2_7_3_6 - y_6_7 = 0 +_C79: c_2_7_3_8 + y_7_8 = 1 +_C8: c_1_5_3_9 + y_5_9 = 1 +_C80: c_2_7_3_9 + y_7_9 = 1 +_C81: c_2_7_4_5 - y_5_7 = 0 +_C82: c_2_7_4_6 - y_6_7 = 0 +_C83: c_2_7_4_8 + y_7_8 = 1 +_C84: c_2_7_4_9 + y_7_9 = 1 +_C85: c_2_8_3_5 - y_5_8 = 0 +_C86: c_2_8_3_6 - y_6_8 = 0 +_C87: c_2_8_3_7 - y_7_8 = 0 +_C88: c_2_8_3_9 + y_8_9 = 1 +_C89: c_2_8_4_5 - y_5_8 = 0 +_C9: c_1_5_4_6 + y_5_6 = 1 +_C90: c_2_8_4_6 - y_6_8 = 0 +_C91: c_2_8_4_7 - y_7_8 = 0 +_C92: c_2_8_4_9 + y_8_9 = 1 +_C93: c_2_9_3_5 - y_5_9 = 0 +_C94: c_2_9_3_6 - y_6_9 = 0 +_C95: c_2_9_3_7 - y_7_9 = 0 +_C96: c_2_9_3_8 - y_8_9 = 0 +_C97: c_2_9_4_5 - y_5_9 = 0 +_C98: c_2_9_4_6 - y_6_9 = 0 +_C99: c_2_9_4_7 - y_7_9 = 0 Binaries -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 -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 +c_1_5_2_6 +c_1_5_2_7 +c_1_5_2_8 +c_1_5_2_9 +c_1_5_3_6 +c_1_5_3_7 +c_1_5_3_8 +c_1_5_3_9 +c_1_5_4_6 +c_1_5_4_7 +c_1_5_4_8 +c_1_5_4_9 +c_1_6_2_5 +c_1_6_2_7 +c_1_6_2_8 +c_1_6_2_9 +c_1_6_3_5 +c_1_6_3_7 +c_1_6_3_8 +c_1_6_3_9 +c_1_6_4_5 +c_1_6_4_7 +c_1_6_4_8 +c_1_6_4_9 +c_1_7_2_5 +c_1_7_2_6 +c_1_7_2_8 +c_1_7_2_9 +c_1_7_3_5 +c_1_7_3_6 +c_1_7_3_8 +c_1_7_3_9 +c_1_7_4_5 +c_1_7_4_6 +c_1_7_4_8 +c_1_7_4_9 +c_1_8_2_5 +c_1_8_2_6 +c_1_8_2_7 +c_1_8_2_9 +c_1_8_3_5 +c_1_8_3_6 +c_1_8_3_7 +c_1_8_3_9 +c_1_8_4_5 +c_1_8_4_6 +c_1_8_4_7 +c_1_8_4_9 +c_1_9_2_5 +c_1_9_2_6 +c_1_9_2_7 +c_1_9_2_8 +c_1_9_3_5 +c_1_9_3_6 +c_1_9_3_7 +c_1_9_3_8 +c_1_9_4_5 +c_1_9_4_6 +c_1_9_4_7 +c_1_9_4_8 +c_2_5_3_6 +c_2_5_3_7 +c_2_5_3_8 +c_2_5_3_9 +c_2_5_4_6 +c_2_5_4_7 +c_2_5_4_8 +c_2_5_4_9 +c_2_6_3_5 +c_2_6_3_7 +c_2_6_3_8 +c_2_6_3_9 +c_2_6_4_5 +c_2_6_4_7 +c_2_6_4_8 +c_2_6_4_9 +c_2_7_3_5 +c_2_7_3_6 +c_2_7_3_8 +c_2_7_3_9 +c_2_7_4_5 +c_2_7_4_6 +c_2_7_4_8 +c_2_7_4_9 +c_2_8_3_5 +c_2_8_3_6 +c_2_8_3_7 +c_2_8_3_9 +c_2_8_4_5 +c_2_8_4_6 +c_2_8_4_7 +c_2_8_4_9 +c_2_9_3_5 +c_2_9_3_6 +c_2_9_3_7 +c_2_9_3_8 +c_2_9_4_5 +c_2_9_4_6 +c_2_9_4_7 +c_2_9_4_8 +c_3_5_4_6 +c_3_5_4_7 +c_3_5_4_8 +c_3_5_4_9 +c_3_6_4_5 +c_3_6_4_7 +c_3_6_4_8 +c_3_6_4_9 +c_3_7_4_5 +c_3_7_4_6 +c_3_7_4_8 +c_3_7_4_9 +c_3_8_4_5 +c_3_8_4_6 +c_3_8_4_7 +c_3_8_4_9 +c_3_9_4_5 +c_3_9_4_6 +c_3_9_4_7 +c_3_9_4_8 +y_5_6 +y_5_7 +y_5_8 +y_5_9 +y_6_7 +y_6_8 +y_6_9 +y_7_8 +y_7_9 +y_8_9 End diff --git a/src/solver.bat b/src/solver.bat new file mode 100644 index 0000000..4139868 --- /dev/null +++ b/src/solver.bat @@ -0,0 +1,4 @@ +@echo off +call .\.venv\Scripts\activate +python solver.py %* +call deactivate diff --git a/src/solver.py b/src/solver.py new file mode 100644 index 0000000..863d6ad --- /dev/null +++ b/src/solver.py @@ -0,0 +1,122 @@ +import os +import logging +from datetime import timedelta +import time +import argparse +from pulp import * +from collections import defaultdict, deque + +# Konfiguriere Logging +file_handler = logging.FileHandler('logfile.log') +console_handler = logging.StreamHandler() +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[file_handler, console_handler]) + +def count_crossings_via_variables(c_vars): + crossings = 0 + for c_var in c_vars.values(): + if c_var.varValue == 1: + crossings += 1 + return crossings + +def solve_bipartite_minimization(input_file, output_file): + start_time = time() + logging.info(f"Prozess für {input_file} gestartet") + + # Dateinamen basierend auf input_file generieren + output_crossings_file = output_file.replace('.sol', '.cros') + + edges = [] + with open(input_file, "r") as file: + for line in file: + if line.startswith('c'): + continue + elif line.startswith('p'): + parts = line.split() + n0 = int(parts[2]) + n1 = int(parts[3]) + 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) + + 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("Variablen für y und c geladen.") + + prob += lpSum(c.values()) + logging.info("Zielfunktion aufgestellt.") + + edges.sort(key=lambda x: x[0]) # Sortierung der Kanten nach dem Startknoten + for idx, (i, j) in enumerate(edges): + for (k, l) in edges[idx + 1:]: + if k > i: # Prüfung nur, wenn k > i nach Sortierung + if (i, j, k, l) not in c: + c[(i, j, k, l)] = LpVariable(f"c_{i}_{j}_{k}_{l}", 0, 1, cat='Binary') + if j > l: + prob += c[(i, j, k, l)] == y[(l, j)] + elif l > j: + prob += c[(i, j, k, l)] == 1 - y[(j, l)] + logging.info("Crossing Constraints aufgestellt.") + + prob.solve() + logging.info(f"Status der Lösung: {LpStatus[prob.status]}") + + if prob.status == LpStatusOptimal: + logging.info("Optimale Lösung gefunden. Ergebnisse werden gespeichert.") + 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)) + if y_ij is not None and y_ij.varValue == 1: + graph[i].append(j) + in_degree[j] += 1 + elif y_ij is not None and y_ij.varValue == 0: + graph[j].append(i) + in_degree[i] += 1 + + 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) + + os.makedirs(os.path.dirname(output_file), exist_ok=True) + with open(output_file, 'w') as f: + for b in sorted_b: + f.write(f"{b}\n") + logging.info(f"Ergebnisse in {output_file} gespeichert") + + crossings_count = count_crossings_via_variables(c) + with open(output_crossings_file, 'w') as f: + f.write(f"Crossings: {crossings_count}\n") + logging.info(f"Crossings: {crossings_count}, in {output_crossings_file} gespeichert") + + end_time = time() + elapsed_time = end_time - start_time + elapsed_time_td = timedelta(seconds=elapsed_time) + logging.info(f"Verstrichene Zeit: {elapsed_time_td.total_seconds()} Sekunden.\n") + else: + logging.warning("Keine optimale Lösung gefunden.\n") + + +def main(): + parser = argparse.ArgumentParser(description="Solve Bipartite Minimization Problem") + parser.add_argument('input_file', type=str, help="The path to the input file") + parser.add_argument('output_file', type=str, help="The path to the output file") + args = parser.parse_args() + + solve_bipartite_minimization(args.input_file, args.output_file) + +if __name__ == "__main__": + main() -- GitLab