Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- # -*- coding: utf-8 -*-
- from ctypes import *
- # Grafy reprezentowane przy pomocy macierzy sąsiedztwa.
- class AdjacencyMatrix64bit:
- # Wyjątek pojawiający się przy próbie konwersji z błędnej reprezentacji tekstowej.
- class G6Error(Exception):
- pass
- # Wyjątek pojawiający się przy próbie stworzenia grafu bez wierzchołków lub posiadającego > 10 wierzchołków.
- class LimitError(Exception):
- pass
- # Tworzy graf o podanej reprezentacji tekstowej (domyślnie: 1-wierzchołkowy graf pusty).
- def __init__(self, text="@"):
- self.__matrix = c_ulonglong(0)
- self.__order = 1
- self.fromString(text)
- # Zwraca liczbę wierzchołków grafu.
- def order(self):
- return self.__order
- # Dodaje do grafu nowy izolowany wierzchołek.
- def addVertex(self):
- if self.__order == 11:
- raise AdjacencyMatrix64bit.LimitError("Graf nie może mieć więcej niż 11 wierzchołków")
- for v in range(0, self.__order):
- self.__matrix.value &= ~(1 << self.__indexInMatrix__(v, self.__order))
- self.__order += 1
- """
- for v in range(self.__order):
- self.__matrix[v] += [False]
- self.__order += 1
- self.__matrix += [[False] * self.__order]
- """
- # Usuwa z grafu wskazany wierzchołek.
- def deleteVertex(self, u):
- if self.__order == 1:
- raise AdjacencyMatrix64bit.LimitError("Graf musi mieć wierzchołki")
- if type(u) != int or u < 0 or u >= self.__order:
- raise ValueError
- #wywala wszelkie krawedzie z tym wierzcholkiem
- for v in range(0, self.__order):
- if u != v:
- self.__matrix.value &= ~(1 << self.__indexInMatrix__(v, u))
- #wyzeruj temp
- temp = c_ulonglong(0)
- for i in range(1, self.__order):
- for j in range(i):
- if j!= i:
- temp.value &= ~(1 << self.__indexInMatrix__(i, j))
- for i in range(0, self.__order):
- for j in range(0, self.__order):
- if i == j:
- continue
- k = i
- l = j
- if k >= u:
- k -= 1
- if l >= u:
- l -= 1
- if self.isEdge(i, j):
- temp.value |= (1 << self.__indexInMatrix__(k, l))
- self.__order -= 1
- self.__matrix = temp
- # Zwraca informację o tym, czy podane wierzchołki sąsiadują z sobą.
- def isEdge(self, u, v):
- return (self.__matrix.value & (1 << self.__indexInMatrix__(u, v))) != 0
- # Dodaje podaną krawędź.
- def addEdge(self, u, v):
- if type(u) != int or u < 0 or u >= self.__order:
- raise ValueError
- if type(v) != int or v < 0 or v >= self.__order:
- raise ValueError
- self.__matrix.value |= (1 << self.__indexInMatrix__(u, v))
- # Usuwa podaną krawędź.
- def deleteEdge(self, u, v):
- if type(u) != int or u < 0 or u >= self.__order:
- raise ValueError
- if type(u) != int or u < 0 or u >= self.__order:
- raise ValueError
- #self.__matrix[u][v] = self.__matrix[v][u] = False
- self.__matrix.value &= ~(1 << self.__indexInMatrix__(u, v))
- # Przekształca reprezentację tekstową grafu w graf.
- def fromString(self, text):
- try:
- t, k = iter(text), 0
- c = ord(next(t)) - 63
- if c < 1 or c > 11:
- raise AdjacencyMatrix64bit.G6Error("niewłaściwa liczba wierzchołków: {0}".format(c))
- self.__order = c
- self.__matrix = c_ulonglong(0)
- for v in range(1, self.__order):
- for u in range(v):
- self.__matrix.value &= ~(1 << self.__indexInMatrix__(v, u))
- for v in range(1, self.__order):
- for u in range(v):
- if k == 0:
- c = ord(next(t)) - 63
- if c < 0 or c > 63:
- raise AdjacencyMatrix64bit.G6Error("zakazany znak o kodzie {0}".format(c + 63))
- k = 6
- k -= 1
- if (c & (1 << k)) != 0:
- #self.__matrix.value &= (1 << self.__indexInMatrix__(u, v))
- #self.__matrix[u][v] = self.__matrix[v][u] = True
- self.addEdge(u, v)
- except StopIteration:
- raise AdjacencyMatrix64bit.G6Error("niekompletny napis")
- try:
- c = ord(next(t))
- raise AdjacencyMatrix64bit.G6Error("nadmiarowy znak o kodzie {0}".format(c))
- except StopIteration:
- pass
- # Przekształca graf w reprezentację tekstową.
- def __str__(self):
- text, k, c = chr(self.__order + 63), 5, 0
- for v in range(1, self.__order):
- for u in range(v):
- if (self.__matrix.value & (1 << self.__indexInMatrix__(u, v))) != 0:
- c |= (1 << k)
- if k == 0:
- text += chr(c + 63)
- k, c = 6, 0
- k -= 1
- if k != 5:
- text += chr(c + 63)
- return text
- # Test równości dwóch reprezentacji grafów.
- def __eq__(self, other):
- if self.__order != other.order():
- return False
- for v in range(1, self.__order):
- for u in range(v):
- if self.isEdge(u, v) != other.isEdge(u, v):
- return False
- return True
- # Test różności dwóch reprezentacji grafów.
- def __ne__(self, other):
- if self.__order != other.order():
- return True
- for v in range(1, self.__order):
- for u in range(v):
- if self.isEdge(u, v) != other.isEdge(u, v):
- return True
- return False
- def __indexInMatrix__(self, v1, v2):
- if v1 == v2:
- return -1
- v3 = 0
- v4 = 0
- if v2 > v1:
- v3 = v1
- v4 = v2
- else:
- v3 = v2
- v4 = v1
- #v3 to mniejszy, v4 to wiekszy
- index = 0
- step = 9
- for i in range(0, v3):
- index += step
- step -= 1
- return index + v4 - 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement