Skip to content
Snippets Groups Projects
Commit 08958b32 authored by konog98's avatar konog98
Browse files

Main und fortesting.py funktionieren nun für alle tiny sets, lösung manchmal...

Main und fortesting.py funktionieren nun für alle tiny sets, lösung manchmal anders, aber gleiche minimale crossings.
parent 3accc9df
Branches
No related tags found
1 merge request!1Kleines Framework aufgestellt, bereitgestellter Tester noch nicht getestet,...
Showing
with 483 additions and 235 deletions
test.py
test?.py
*alt.py
*test.py
\ No newline at end of file
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 l > j:
prob += 1 - c[(i, j, k, l)] <= y[(l, j)] + x[(i, k)] <= 1 + 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')
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
# 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 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
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)
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')
......@@ -33,69 +35,99 @@ def solve_bipartite_minimization(graph_file):
# 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)]
# 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 += 1 - c[(i, j, k, l)] <= y[(l, j)] + x[(i, k)] <= 1 + c[(i, j, k, l)]
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
"""
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])
# Stelle sicher, dass das Verzeichnis existiert
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")
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)
\* 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
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
5
7
6
7
8
5
5
6
7
6
8
7
5
6
8
8
6
7
9
7
9
6
8
9
11
6
10
7
8
3
5
7
4
6
8
9
10
11
7
12
13
8
14
15
16
17
18
19
20
11
12
13
14
16
15
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment