Graphs/src/management/commands/create_cycle.py
2025-03-09 15:23:18 +01:00

116 lines
4 KiB
Python

from django.core.management.base import BaseCommand
from django.db import transaction
from src.management.commands.default import delete_graphs
from src.management.commands.core import create_arc, get_arc
from src.models import Graph, Vertex, Arc
import time
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('min', type=int)
parser.add_argument('max', type=int)
def handle(self, *args, **options):
delete_graphs(Graph.CYCLE)
min = options['min']
max = options['max']
s_time = time.time()
for n in range(min, max + 1):
start_time = time.time()
self.create_cycle(n)
end_time = time.time()
elapsed_time = end_time - start_time
print("Čas trvání", n, "vrcholů:", elapsed_time, "sekund")
e_time = time.time()
eed_time = e_time - s_time
print("Celkový čas trvání:", eed_time, "sekund")
def create_cycle(self, n):
with transaction.atomic():
for i in range(2 ** n):
binary_number = bin(i)[2:].zfill(n)
if binary_number[:2] not in ['01', '10']:
continue
graph = self.create_graph(binary_number)
vertex = None
vertices = Vertex.objects.filter(graph=graph)
vertices_list = []
for num, v in enumerate(vertices):
vertices_list.append(v)
if v.max_degree == 2 and not vertex:
vertex = v
right = vertices_list.index(vertex)
left = vertices_list.index(vertex)-1
section = True
right_ark = vertices_list[right % n]
left_ark = vertices_list[right % n]
for idx in range(n):
location = (right % n) if section else left
now = vertices_list[location]
now.index = idx + 1
now.save()
if section:
if right_ark != now:
right_ark = get_arc(first=right_ark, second=now, n=n, idx=idx)
right += 1
else:
left_ark = get_arc(first=left_ark, second=now, n=n, idx=idx)
left -= 1
if now.max_degree == 2:
section = not section
if Arc.objects.filter(vertex_out=right_ark, vertex_in=left_ark).exists():
arc = Arc.objects.get(vertex_out=right_ark, vertex_in=left_ark)
else:
arc = Arc.objects.get(vertex_out=left_ark, vertex_in=right_ark)
arc.label = n + n
arc.save()
sorted_vertices = sorted(vertices_list, key=lambda vertex: (vertex.max_degree, vertex.index))
for num, v in enumerate(sorted_vertices):
v.label = num + 1
v.save()
graph.update()
@staticmethod
def create_graph(binary_number):
prev_vertex = None
first_vertex = None
first_bit = None
arc_num = 1
graph = Graph.objects.create(
graph_type=Graph.CYCLE,
binary=binary_number,
)
for j, bit in enumerate(binary_number):
vertex = Vertex.objects.create(graph=graph, label=j + 1)
if prev_vertex:
arc_num = create_arc(
vertex_in=prev_vertex if bit == '0' else vertex,
vertex_out=vertex if bit == '0' else prev_vertex,
arc_num=arc_num
)
else:
first_vertex = vertex
first_bit = bit
prev_vertex = vertex
create_arc(
vertex_in=prev_vertex if first_bit == '0' else first_vertex,
vertex_out=first_vertex if first_bit == '0' else prev_vertex,
arc_num=arc_num
)
return graph