Sorting network class. From Wikipedia : A sorting network is an abstract mathematical model of a network of wires and comparator modules that is used to sort a sequence of numbers. Each comparator connects two wires and sort the values by outputting the smaller value to one wire, an
| 17 | from itertools import product |
| 18 | |
| 19 | class SortingNetwork(list): |
| 20 | """Sorting network class. |
| 21 | |
| 22 | From Wikipedia : A sorting network is an abstract mathematical model |
| 23 | of a network of wires and comparator modules that is used to sort a |
| 24 | sequence of numbers. Each comparator connects two wires and sort the |
| 25 | values by outputting the smaller value to one wire, and a larger |
| 26 | value to the other. |
| 27 | """ |
| 28 | def __init__(self, dimension, connectors = []): |
| 29 | self.dimension = dimension |
| 30 | for wire1, wire2 in connectors: |
| 31 | self.addConnector(wire1, wire2) |
| 32 | |
| 33 | def addConnector(self, wire1, wire2): |
| 34 | """Add a connector between wire1 and wire2 in the network.""" |
| 35 | if wire1 == wire2: |
| 36 | return |
| 37 | |
| 38 | if wire1 > wire2: |
| 39 | wire1, wire2 = wire2, wire1 |
| 40 | |
| 41 | index = 0 |
| 42 | for level in reversed(self): |
| 43 | if self.checkConflict(level, wire1, wire2): |
| 44 | break |
| 45 | index -= 1 |
| 46 | |
| 47 | if index == 0: |
| 48 | self.append([(wire1, wire2)]) |
| 49 | else: |
| 50 | self[index].append((wire1, wire2)) |
| 51 | |
| 52 | def checkConflict(self, level, wire1, wire2): |
| 53 | """Check if a connection between `wire1` and `wire2` can be |
| 54 | added on this `level`.""" |
| 55 | for wires in level: |
| 56 | if wires[1] >= wire1 and wires[0] <= wire2: |
| 57 | return True |
| 58 | |
| 59 | def sort(self, values): |
| 60 | """Sort the values in-place based on the connectors in the network.""" |
| 61 | for level in self: |
| 62 | for wire1, wire2 in level: |
| 63 | if values[wire1] > values[wire2]: |
| 64 | values[wire1], values[wire2] = values[wire2], values[wire1] |
| 65 | |
| 66 | def assess(self, cases=None): |
| 67 | """Try to sort the **cases** using the network, return the number of |
| 68 | misses. If **cases** is None, test all possible cases according to |
| 69 | the network dimensionality. |
| 70 | """ |
| 71 | if cases is None: |
| 72 | cases = product((0, 1), repeat=self.dimension) |
| 73 | |
| 74 | misses = 0 |
| 75 | ordered = [[0]*(self.dimension-i) + [1]*i for i in range(self.dimension+1)] |
| 76 | for sequence in cases: |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…