def getUnitDiskGraph(n): """ Funkcja zwracajaca macierz sasiedztwa dla grafu unit disk Argumenty: n - ilosc wierzcholkow """ def correctMatrixForPoint(adjacencyMatrix, points, pointIndex, radius, n): """ Metoda poprawia macierz sasiedztwa dla jednego punktu Argumenty: adjacencyMatrix - macierz sasiedztwa points - lista punktow pointIndex - indeks punktu dla ktorego nanoszone sa poprawki radius - promien w zasiegu ktorego wierzcholek widzi swoich sasiadow n - ilosc wierzcholkow w grafie """ # 1 - wymazywanie dotychczasowych sasiadow z punktu # 2 - wymazywanie informacji o sasiedztwie z punktem # 3 - obliczanie nowych sasiadow for i in xrange(n): # zawor bezpieczenstwa if i == pointIndex: continue dist = getDist(points[i], points[pointIndex]) if dist <= radius: adjacencyMatrix[i][pointIndex] = 1 adjacencyMatrix[pointIndex][i] = 1 else: adjacencyMatrix[i][pointIndex] = 0 adjacencyMatrix[pointIndex][i] = 0 return adjacencyMatrix def constructNewMatrix(points, radius, n): """ Funkcja konstruuje nowa macierz sasiedztwa dla grafu unit disk. Macierz jest poprawiana dopoki graf nie bedzie spojny. """ adjacencyMatrix = [[0 for i in xrange(n)] for j in xrange(n)] for i in xrange(n-1): for j in xrange(i+1, n): # zawor bezpieczenstwa if i == j: continue dist = getDist(points[i], points[j]) if dist <= radius: adjacencyMatrix[i][j] = 1 adjacencyMatrix[j][i] = 1 return adjacencyMatrix # 1 - wybierz losowo 2n punktow n2 = 2*n points = [(randint(0, n2), randint(0, n2)) for i in xrange(n)] # 2 - ocen promien radius = n/5 adjacencyMatrix = constructNewMatrix(points, radius, n) # ewentualne poprawianie macierzy while True: result = checkReachability(adjacencyMatrix) if result == None: # jesli wszystkie wezly sa osiagalne break # zbliz punkt do punktu nr 0 x0 = points[0][0] y0 = points[0][1] oldX = points[result][0] oldY = points[result][1] if oldX < x0: oldX +=1 else: oldX -=1 if oldY < y0: oldY +=1 else: oldY -=1 points[result] = (oldX, oldY) adjacencyMatrix = correctMatrixForPoint(adjacencyMatrix, points, result, radius, n) return adjacencyMatrix
def getYaoGraph(n, k): """ Funkcja zwraca macierz sasiedztwa da grafu Yao Argumenty: n - ilosc wierzcholkow k - ilosc sektorow dla kazdego wierzcholka """ def getDegree(checkedPoint, point2): """ Funkcja zwraca polozenie punktu point2 wzgledem punktu checkedPoint w stopniach Argumenty: checkedPoint - punkt wzgledem ktorego okreslamy polozenie point2 - punkt, ktorego polozenie okreslamy """ deg = atan2(checkedPoint[0] - point2[0], checkedPoint[1] - point2[1]) deg = degrees(deg) deg += 180 return deg def checkForPoint(pointIndex, p, sectors, adjacencyMatrix): """ Funkcja znajduje najblizszego sasiada dla danego punktu w kazdym sektorze. Argumenty: pointIndex - indeks rozpatrywanego punktu p - lista punktow w grafie sectors - lista sektorow adjacencyMatrix - macierz sasiedztwa """ neighSectors = [[] for i in range(k)] # sprawdzamy dla kazdego sektora for i in xrange(k): sector = sectors[i] # rozpatruje dla pojedynczego punktu for j in xrange(n): if j == pointIndex: continue deg = getDegree(p[pointIndex], p[j]) if (deg >= sector[0]) and (deg < sector[1]): neighSectors[i].append(p[j]) # teraz wyznaczanie najblizszego punktu for row in neighSectors: dists = [ hypot((p[pointIndex][0] - i[0]), (p[pointIndex][1] - i[1])) for i in row ] if not dists: continue minDist = min(dists) neighborIndex = dists.index(minDist) neighbor = row[neighborIndex][2] adjacencyMatrix[neighbor][pointIndex] = 1 adjacencyMatrix[pointIndex][neighbor] = 1 # 1 - wybor punktow # punkty maja strukture: (wsp. X, wsp. Y, nr punktu) n2 = 2*n p = [(randint(0, n2), randint(0, n2), i) for i in xrange(n)] # 2 - wyznaczenie k sektorow # 360 stopni / k sectorWidth = float(360.0/k) sectors = [(i * sectorWidth, (i+1) * sectorWidth) for i in xrange(k)] # wyznaczenie polozenia kazdego punktu wzgledem punktu 0 adjacencyMatrix = [[0 for i in xrange(n)] for j in xrange(n)] for i in xrange(n): checkForPoint(i, p, sectors, adjacencyMatrix) # sprawdzenie spojnosci result = None while True: result = checkReachability(adjacencyMatrix) # jesli jest dobrze if result == None: break # w p.p. funkcja zwrocila indeks punktu do ktorego nie mozna dotrzec # punkt musi zostac przesuniety blizej losowego punktu randomVert = result while randomVert == result: randomVert = randint(0, n-1) oldX = p[result][0] oldY = p[result][1] if oldX > p[randomVert][0]: oldX -=1 else: oldX +=1 if oldY > p[randomVert][1]: oldY -=1 else: oldY +=1 p[result][0] = oldX p[result][1] = oldY adjacencyMatrix = [[0 for i in xrange(n)] for j in xrange(n)] for i in range(n): checkForPoint(i, p, sectors, adjacencyMatrix) return adjacencyMatrix