def check_diagram(sparse_diagram, ext_possible_chords, ext_min, ext_max): # Skip diagrams with 1, 2 or 3 moves compressed_diag = get_compressed_diagram(sparse_diagram) if (contains_one_move(compressed_diag) or contains_two_move(compressed_diag) or contains_three_move(compressed_diag)): return (sparse_diagram, [], []) # Find the permitted single chord extensions invariant_chords = get_invariant_chords_for_diagram( sparse_diagram, ext_possible_chords, diagram_filter=diagram_filter, doScale=False) if len(invariant_chords) == 0: # Skip diagrams with no invariant chords return (sparse_diagram, invariant_chords, []) # Test planarability of sparse_diag plus combinations of min..max chords planarable_extension_sets = [] for n_extensions in range(ext_min, ext_max+1): for extensions in combinations(invariant_chords, n_extensions): # Skip extension chord pair if they share any nodes uniq_nodes = {node for ext in extensions for node in ext} if len(uniq_nodes) != n_extensions * 2: continue diag = Diagram(sparse_diagram + list(extensions)) if diag.is_planarable(): planarable_extension_sets.append((timestamp(), extensions)) return (sparse_diagram, invariant_chords, planarable_extension_sets)
def diagram_filter(orig_sparse_diag, extension_chord, extended_sparse_diag): diag = Diagram(extended_sparse_diag) diag.compress() if (contains_one_move(diag) or contains_three_move(diag)): return False # Skip this diagram return True # Use this diagram
def check_123_planarable(diagram): # Skip diagrams with 1, 2 or 3 moves if (contains_one_move(diagram) or contains_two_move(diagram) or contains_three_move(diagram)): return (diagram, False) # Test planarability of sparse_diag diag = Diagram(diagram) rv = diag.is_planarable() return (diagram, rv)
def diagram_filter(diagram): ''' Filter function that gets passed into gen_possible_diagrams to filter at generation time. The filter applies two basic tests: 1. Skip diagrams containing 2 or 3 moves 2. Skip if other-ends of chords with adjacent nodes are 1 or 2 nodes apart This test is known as the parallel with defect 3 test. Closure arguments: filter_two_moves: Filter out two moves when True filter_three_moves: Filter out three moves when True Arguments: diagram: Diagram to check. Assumption: diagram is compressed, i.e. all 1..2*n_chords nodes are part of a chord. Returns: True (keep diagram) if the diagram meets the requirements False (discard diagram) if the diagram fails either test Raises: None ''' # Allow access to globals set in main. Necessary with multiprocessing.Pool global filter_two_moves global filter_three_moves global max_parallel_defect # Remove diagram nodes with no chord compressed_diag = get_compressed_diagram(diagram) # Filter out 2 and 3 moves. One moves are pre-filtered in chord list if (filter_two_moves and contains_two_move(compressed_diag) or filter_three_moves and contains_three_move(compressed_diag)): return False # Skip diagram # Filter out parallel chords with defect chords_by_node = {node: chord for chord in diagram for node in chord} n_nodes = len(chords_by_node) for node1 in range(1, n_nodes + 1): node2 = node1 % n_nodes + 1 # Adjacent chord chord1 = chords_by_node[node1] chord2 = chords_by_node[node2] if chord_length( (get_other_node(chord1, node1), get_other_node(chord2, node2)), n_nodes) < max_parallel_defect: return False # Skip diagram return True # Keep diagram
def diagram_filter(diagram): # Skip diagrams with 2 or 3 moves # or if other ends of chords with adjacent nodes are too close # Filter out 2 and 3 moves. One moves are pre-filtered in chord list if (contains_two_move(diagram) or contains_three_move(diagram)): return False # Skip diagram # Filter out parallel chords with defect defect_length = 3 chords_by_node = { node:chord for chord in diagram for node in chord} n_nodes = len(chords_by_node) for node1 in range(1, n_nodes+1): node2 = node1 % n_nodes + 1 # Adjacent chord chord1 = chords_by_node[node1] chord2 = chords_by_node[node2] if chord_length((get_other_node(chord1, node1), get_other_node(chord2, node2)), n_nodes) < defect_length: return False # Skip diagram return True # Keep diagram
def main(argv): "Process command line arguments and kick things off" progname = argv[0].split('/')[-1] print_all = False # Print detail on each move type # Parse command line options try: (opts, args) = getopt.getopt(argv[1:], "ha") except getopt.GetoptError as err: print >>sys.stderr, str(err) usage(progname) for opt, _ in opts: if opt == '-a': print_all = True if opt == '-h': usage(progname) diag_files = args if len(diag_files) == 0: diag_files.append(None) # Read from stdin # Do the work count = 0 for diag_file in diag_files: diag_gen = load_diagrams_from_file(diag_file) for diagram in diag_gen: count += 1 diag_compressed = get_compressed_diagram(diagram) one = contains_one_move(diag_compressed) two = contains_two_move(diag_compressed) three = contains_three_move(diag_compressed) if print_all: print "{}{}{}: {}".format( '1' if one else '-', '2' if two else '-', '3' if three else '-', diagram) elif not (one or two or three): print diagram