def bruteforce(graph): max_size = 0 max_is = None for subset in subsets(graph.vertices): if size(subset) > max_size and is_independent(graph, subset): max_is = subset max_size = size(subset) return max_is
def save(self, filename): with open(filename, 'w') as f: f.write('p edges {} {}\n'.format(size(self.vertices), len(list(self.edges)))) f.writelines( 'n {}\n'.format(index(v)) for v in self ) f.writelines( 'e {} {}\n'.format(index(v), index(w)) for v, w in self.edges )
def heuristic(graph): subset = 0 while is_independent(graph, subset): # Find valid vertex with the least new neighbors existing_neighbors = graph(subset) min_new_neighbors = Infinity new_vertex = None for v in iterate(subtract(graph.vertices, subset)): if not graph(v) & subset: new_neighbors = subtract(graph(v), existing_neighbors) if size(new_neighbors) < min_new_neighbors: min_new_neighbors = size(new_neighbors) new_vertex = v if new_vertex == None: return subset else: subset |= new_vertex
def greedy_step(G, left, right, un_left, booldim_left, un_table, bound): best_vertex = None best_booldim = Infinity best_un = None if size(right) == 1: return right, {0}, 1 assert size(right) > 1 candidates = get_neighborhood_2(G.neighborhoods, left) & right # Trivial cases are slow for v in iterate(candidates): if trivial_case(G.neighborhoods, left, right, v): new_un = increment_un(G, left, un_left, v) new_booldim = len(new_un) return v, new_un, new_booldim for v in iterate(candidates): if left | v not in un_table: un_table[left | v] = increment_un(G, left, un_left, v) new_un = un_table[left | v] new_booldim = len(new_un) # Apply pruning if new_booldim >= bound: # print('pruning') continue if new_booldim < best_booldim: best_vertex = v best_booldim = new_booldim best_un = new_un # If nothing found if best_vertex == None: best_un = increment_un(G, left, un_left, v) best_booldim = len(best_un) best_vertex = v assert best_vertex != None return best_vertex, best_un, best_booldim
def split(self, v, w): """Split edge between two vertices.""" if not v in self: raise ValueError if not w in self: raise ValueError if w == v: raise ValueError('{} and {} are the same vertex.'.format(v, w)) if contains(self(v), w): raise ValueError('{} and {} are not connected.'.format(v, w)) # Only support undirected edges assert contains(self(w), v) new = bit(size(self.vertices)) self.add(new) self.disconnect(v, w) self.connect(v, new) self.connect(w, new)
def incremental_un_heuristic(G): lboolw_components = [] decomposition_components = [] for component in components(G): best_lboolw = Infinity best_decomposition = None for i, start in enumerate([first(component)]): #for i, start in enumerate(iterate(component)): print('{}th starting vertex'.format(i)) right = subtract(component, start) left = start un_left = increment_un(G, 0, {0}, start) booldim_left = 1 decomposition = [start] lboolw = len(un_left) for _ in range(size(component) - 1): best_vertex, best_un, _ = greedy_step(G, left, right, un_left, booldim_left, {}, Infinity) booldim_left = len(best_un) lboolw = max(lboolw, booldim_left) un_left = best_un decomposition.append(best_vertex) right = subtract(right, best_vertex) left = left | best_vertex if lboolw < best_lboolw: best_lboolw = lboolw best_decomposition = decomposition lboolw_components.append(best_lboolw) decomposition_components.append(best_decomposition) total_lboolw = max(lboolw_components) total_decomposition = [v for part in decomposition_components for v in part] return total_lboolw, total_decomposition
#grid = matrix_to_dict([ #[0, 0, 5, 5, 5], #[0, 0, 0, 1, 5], #[2, 2, 4, 1, 5], #[3, 2, 3, 1, 5], #[3, 3, 3, 3, 6], #]) while 1: width = randint(5, 25) height = randint(5, 25) max_field_size = randint(5, 25) grid = random_walk(width, height, max_field_size) graph = PixelGraph(grid) width, decomposition = incremental_un_heuristic(graph) heuristic_solution = heuristic(graph) exact_solution = from_decomposition(graph, decomposition) if size(heuristic_solution) < size(exact_solution) / 1.2: break print(graph) print(tostring(heuristic_solution)) print(tostring(exact_solution)) #Possible engines: dot, neato, fdp, sfdp, twopi, circo plot(graph, 'neato') #print(tostring(from_decomposition(graph, iterate(graph.vertices)))) #print(tostring(bruteforce(graph)))
def __len__(self): """Iterate over all vertices.""" return size(self.vertices)
def density(self): n = size(self.vertices) m = len(list(self.edges)) return float(2 * m) / float(n * (n - 1))
def add(collection, solution): key = graph(solution) & right if key not in collection or size(collection[key]) < size(solution): collection[key] = solution
#grid = matrix_to_dict([ #[0, 0, 5, 5, 5], #[0, 0, 0, 1, 5], #[2, 2, 4, 1, 5], #[3, 2, 3, 1, 5], #[3, 3, 3, 3, 6], #]) while 1: width = randint(5, 35) height = 40 - width max_field_size = randint(5, 25) grid = random_walk(width, height, max_field_size) graph = PixelGraph(grid) width, decomposition = incremental_un_heuristic(graph) heuristic_solution = heuristic(graph) exact_solution = from_decomposition(graph, decomposition) if size(heuristic_solution) < size(exact_solution) - 3: break print(graph) print(tostring(heuristic_solution)) print(tostring(exact_solution)) #Possible engines: dot, neato, fdp, sfdp, twopi, circo plot(graph, 'neato') #print(tostring(from_decomposition(graph, iterate(graph.vertices)))) #print(tostring(bruteforce(graph)))