https://en.wikipedia.org/wiki/Independent_set_(graph_theory)
Zbiór niezależny (ang. independent set) grafu nieskierowanego G=(V,E) jest to podzbiór S zbioru wierzchołków V, taki że żadne dwa wierzchołki z S nie są połączone krawędzią z E. 'Maksymalny zbiór niezależny' (ang. maximal independent set) nie jest podzbiorem większego zbioru niezależnego. 'Największy zbiór niezależny' (ang. maximum independent set) jest zbiorem niezależnym o największej liczności w G. Problem znalezienia największego zbioru niezależnego jest NP-trudny.
# Testowanie zbioru niezależnego. import unittest def find_independent_set(graph): pass class TestIndependentSet(unittest.TestCase): def setUp(self): self.G = dict() self.edges = [] # wstawiamy 3-krotki, graf ważony # Wstawiamy wierzchołki i krawędzie do G. def test_independent_set(self): iset = find_independent_set(self.G) for edge in self.edges: source, target, weight = edge self.assertFalse(source in iset and target in iset)
Liczba potencjanych rozwiązań to 2^N, bo każdy wierzchołek może należeć lub nie do zbioru niezależnego.
# 0 --- 1 --- 2 graf nie jest dwudzielny, bo są trójkąty # | / | | # | / | | niezależne: 0, 4, 2 (najlepszy) # | / | | # 3 --- 4 --- 5 N = 6 # liczba wierzchołków import sys recursionlimit = sys.getrecursionlimit() sys.setrecursionlimit(max(N*2, recursionlimit)) # Definicja prostego grafu spójnego. graph = dict() edges = [(0, 1, 1), (0, 3, 1), (1, 3, 1), (1, 4, 1), (1, 2, 1), (2, 5, 1), (3, 4, 1), (4, 5, 1)] for edge in edges: add_edge_undirected(graph, edge) node_list = list(graph) used = dict((node, 0) for node in graph) # pokrycie wierzcholka tmp_set = set() # kandydat na największy zbiór niezależny independent_set = set() # największy zbiór niezależny def add_iset(source): """Add a source to iset.""" tmp_set.add(source) used[source] += 1 for target in graph[source]: used[target] += 1 def remove_iset(source): """Remove a source from iset.""" tmp_set.remove(source) used[source] -= 1 for target in graph[source]: used[target] -= 1 def graph_iset(k): """Try to add a node k to an iset.""" global independent_set, tmp_set, node_list, N node = node_list[k] if used[node] > 0: # mogę wstawiać tylko że nie należy if k < N-1: graph_iset(k+1) else: if len(tmp_set) > len(independent_set): independent_set = set(tmp_set) else: # used[node]==0 # Najpierw sprawdzam możliwość, że należy do iset. add_iset(node) if k < N-1: graph_iset(k+1) else: if len(tmp_set) > len(independent_set): independent_set = set(tmp_set) remove_iset(node) # Teraz sprawdzam możliwość, że nie należy do iset. if k < N-1: graph_iset(k+1) else: if len(tmp_set) > len(independent_set): independent_set = set(tmp_set) # Uruchomienie poszukiwania największego zbioru niezależnego. graph_iset(0)