예제 #1
0
    def run_on_edge(self, edge):
        """
        Run Kempe Path Algorithm on an error edge.

        :returns:
            length of path involved - If error is reduced
            -length of path involved - If no error is reduced
        """
        # not an error, stop
        if not edge.is_error():
            return -1

        (a, b) = edge.get_endpoints()
        ca = edge.get_link(a).color
        cb = edge.get_link(b).color
        if random.random() < 0.5:
            p = create_path(self.graph, a, cb, ca)
        else:
            p = create_path(self.graph, b, ca, cb)
            # meet start edge, stop
        if p.is_closed():
            return -len(p)
            # flip whole path
        p.swap_colors(ca, cb)
        return len(p)
예제 #2
0
 def check_cycles(self):
     ((c, a, d), (e, b, f)) = self.removed
     if self.graph.get_color(c, d) != self.graph.get_color(e, f):
         self.put_back_edge()
         return False
     self.put_back_edge()
     self.last_removed = ((c, a, d), (e, b, f))
     c0 = self.graph.get_color(c, a)
     colors = [1, 2, 3]
     colors.remove(c0)
     c1, c2 = tuple(colors)
     # try 1st
     self.graph.set_color(a, c, c1)
     self.graph.set_color(b, e, c1)
     self.graph.set_color(a, b, c2)
     self.graph.set_color(b, a, c2)
     p1 = create_path(self.graph, self.graph.get_edge(a, c), a, c0, c1)
     p2 = create_path(self.graph, self.graph.get_edge(b, e), b, c0, c1)
     if not p1.is_closed() or not p2.is_closed():
         return False
     self.bicycle_configs = [(c0, c1, c2, p1, p2)]
     # try 2nd
     self.graph.set_color(a, c, c2)
     self.graph.set_color(b, e, c2)
     self.graph.set_color(a, b, c1)
     self.graph.set_color(b, a, c1)
     p1 = create_path(self.graph, self.graph.get_edge(a, c), a, c0, c2)
     p2 = create_path(self.graph, self.graph.get_edge(b, e), b, c0, c2)
     if not p1.is_closed() or not p2.is_closed():
         return False
     self.bicycle_configs.append((c0, c2, c1, p1, p2))
     return True
    def _sub_routine_for_resolve(self, path1):
        a, b = path1.c2, path1.c1
        v1 = path1.begin
        v2 = path1.end

        c = 6 - a - b
        path_ac = create_path(self.graph, v1, c, a)
        path_bc = create_path(self.graph, v2, c, b)
        v_ac = []
        v_bc = []
        for ve in self.graph.vertices:
            if ve.id not in path_ac:
                v_ac.append(ve.id)
            if ve.id not in path_bc:
                v_bc.append(ve.id)

        ac_cycle = self.factor_cycle(v_ac, a, c)
        bc_cycle = self.factor_cycle(v_bc, b, c)
        cycles = ac_cycle + bc_cycle

        for x in cycles:
            x.invert_colors()
            temp = create_path(self.graph, v1, b, a)
            if temp.is_closed() != True:
                x.invert_colors()
                return True
            x.invert_colors()

        return False
 def check_cycles(self):
     ((c, a, d), (e, b, f)) = self.removed
     if self.graph.get_color(c, d) != self.graph.get_color(e, f):
         self.put_back_edge()
         return False
     self.put_back_edge()
     self.last_removed = ((c, a, d), (e, b, f))
     c0 = self.graph.get_color(c, a)
     colors = [1, 2, 3]
     colors.remove(c0)
     c1, c2 = tuple(colors)
     # try 1st
     self.graph.set_color(a, c, c1)
     self.graph.set_color(b, e, c1)
     self.graph.set_color(a, b, c2)
     self.graph.set_color(b, a, c2)
     p1 = create_path(self.graph, self.graph.get_edge(a, c), a, c0, c1)
     p2 = create_path(self.graph, self.graph.get_edge(b, e), b, c0, c1)
     if not p1.is_closed() or not p2.is_closed():
         return False
     self.bicycle_configs = [(c0, c1, c2, p1, p2)]
     # try 2nd
     self.graph.set_color(a, c, c2)
     self.graph.set_color(b, e, c2)
     self.graph.set_color(a, b, c1)
     self.graph.set_color(b, a, c1)
     p1 = create_path(self.graph, self.graph.get_edge(a, c), a, c0, c2)
     p2 = create_path(self.graph, self.graph.get_edge(b, e), b, c0, c2)
     if not p1.is_closed() or not p2.is_closed():
         return False
     self.bicycle_configs.append((c0, c2, c1, p1, p2))
     return True
    def highlight_bc_cycles(self):
        if not hasattr(self, "state") or self.state != "bc cycles":
            cycles = self.find_two_cycle()
            if cycles == None:
                print "not has two cycles"
                return False
            else:
                self.state = "bc cycles"
                left, right = cycles
                if left.c1 == 1:
                    path_bc = create_path(self.graph, left.begin, 3, 2)
                else:
                    path_bc = create_path(self.graph, left.end, 3, 2)

                v_bc = []
                for v in self.graph.vertices:
                    if v.id not in path_bc:
                        v_bc.append(v.id)

                self.bc_cycles = self.factor_cycle(v_bc, 2, 3)

        self.highlighted = []
        if len(self.bc_cycles) > 0:
            self.highlighted.append(self.bc_cycles[0])
            self.bc_cycles = self.bc_cycles[1:] + self.bc_cycles[0:1]

        return self.prepare_highlight_data()
    def _sub_routine_for_count(self, path1):
        a, b = path1.c2, path1.c1
        v1 = path1.begin
        v2 = path1.end
     
        c = 6 - a - b
        path_ac = create_path(self.graph, v1, c, a)
        path_bc = create_path(self.graph, v2, c, b)
        v_ac = []
        v_bc = []
        for ve in self.graph.vertices:
            if ve.id not in path_ac:
                v_ac.append(ve.id)
            if ve.id not in path_bc:
                v_bc.append(ve.id)
        
        ac_cycle = self.factor_cycle(v_ac, a, c)
        bc_cycle = self.factor_cycle(v_bc, b, c)
        cycles = ac_cycle + bc_cycle

        for x in cycles:
            x.invert_colors()
            temp = create_path(self.graph, v1, b, a)
            if temp.is_closed() != True:
                x.invert_colors()
                return True
            x.invert_colors()
        
        return False
    def run_on_edge(self, edge):
        """
        Run Kempe Path Algorithm on an error edge.

        :returns:
            length of path involved - If error is reduced
            -length of path involved - If no error is reduced
        """
        # not an error, stop
        if not edge.is_error():
            return -1

        (a, b) = edge.get_endpoints()
        ca = edge.get_link(a).color
        cb = edge.get_link(b).color
        if random.random() < 0.5:
            p = create_path(self.graph, a, cb, ca)
        else:
            p = create_path(self.graph, b, ca, cb)
            # meet start edge, stop
        if p.is_closed():
            return -len(p)
            # flip whole path
        p.swap_colors(ca, cb)
        return len(p)
    def highlight_bc_cycles(self):
        if not hasattr(self, 'state') or self.state != "bc cycles":
            cycles = self.find_two_cycle()
            if cycles == None:
                print("not has two cycles")
                return False
            else:
                self.state = "bc cycles"
                left, right = cycles
                if left.c1 == 1:
                    path_bc = create_path(self.graph, left.begin, 3, 2)
                else:
                    path_bc = create_path(self.graph, left.end, 3, 2)

                v_bc = []
                for v in self.graph.vertices:
                    if v.id not in path_bc:
                        v_bc.append(v.id)

                self.bc_cycles = self.factor_cycle(v_bc, 2, 3)

        self.highlighted = []
        if len(self.bc_cycles) > 0:
            self.highlighted.append(self.bc_cycles[0])
            self.bc_cycles = self.bc_cycles[1:] + self.bc_cycles[0:1]

        return self.prepare_highlight_data()
예제 #9
0
    def find_two_cycle(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        
        if len(errors) != 2:
            print ("errors not equal 2, return false")
            return None

        (v1, v2) = errors[0].get_endpoints()
        (x1, y1) = self.graph._positions[v1]
        (x2, y2) = self.graph._positions[v2]
        mid1 = x1 + x2
        
        (v3, v4) = errors[1].get_endpoints()
        (x3, y3) = self.graph._positions[v3]
        (x4, y4) = self.graph._positions[v4]
        mid2 = x3 + x4

        if mid1 <= mid2:
            left = errors[0]
            right = errors[1]
        else:
            left = errors[1]
            right = errors[0]

        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        if la + lb != ra + rb:
            print ("Two variable not same, return false")
            return None

        left_p = create_path(self.graph, v1, lb, la)
        if left_p.is_closed() != True:
            print ("two variables are adjacent, return False")
            return None
        right_p = create_path(self.graph, v3, rb, ra)

        c = 6 - la - lb
        if c != 3:
            self.graph.swap_colors(c, 3)
            if left_p.c1 == 3:
                left_p.c1 = c;
            else:
                left_p.c2 = c;
            if right_p.c1 == 3:
                right_p.c1 = c;
            else:
                right_p.c2 = c;
        
        return (left_p, right_p)
    def find_two_cycle(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        
        if len(errors) != 2:
            print "errors not equal 2, return false"
            return None

        (v1, v2) = errors[0].get_endpoints()
        (x1, y1) = self.graph._positions[v1]
        (x2, y2) = self.graph._positions[v2]
        mid1 = x1 + x2
        
        (v3, v4) = errors[1].get_endpoints()
        (x3, y3) = self.graph._positions[v3]
        (x4, y4) = self.graph._positions[v4]
        mid2 = x3 + x4

        if mid1 <= mid2:
            left = errors[0]
            right = errors[1]
        else:
            left = errors[1]
            right = errors[0]

        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        if la + lb != ra + rb:
            print "Two variable not same, return false"
            return None

        left_p = create_path(self.graph, v1, lb, la)
        if left_p.is_closed() != True:
            print "two variables are adjacent, return False"
            return None
        right_p = create_path(self.graph, v3, rb, ra)

        c = 6 - la - lb
        if c != 3:
            self.graph.swap_colors(c, 3)
            if left_p.c1 == 3:
                left_p.c1 = c;
            else:
                left_p.c2 = c;
            if right_p.c1 == 3:
                right_p.c1 = c;
            else:
                right_p.c2 = c;
        
        return (left_p, right_p)
    def bicycle_algorithm(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            print "errors not equal 2, return false"
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            print "Two variable not same, return false"
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            count_utility.count(-1)
            left_p.swap_colors(b, a)
            return True
        
        right_p = create_path(self.graph, v3, b, a)
        
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        steps = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self.sub_routine_for_bicycle_algorithm(left_p, right_p):
                    count_utility.count(steps)
                    return True
                right_p.move_one_step()
                steps = steps + 1
            left_p.move_one_step()
        
        return False
예제 #12
0
    def bicycle_algorithm(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            print ("errors not equal 2, return false")
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            print ("Two variable not same, return false")
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            count_utility.count(-1)
            left_p.swap_colors(b, a)
            return True
        
        right_p = create_path(self.graph, v3, b, a)
        
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        steps = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self.sub_routine_for_bicycle_algorithm(left_p, right_p):
                    count_utility.count(steps)
                    return True
                right_p.move_one_step()
                steps = steps + 1
            left_p.move_one_step()
        
        return False
예제 #13
0
    def not_finished_cycles_algorithm(self):
        cycles = self.find_locking_cycles()
        if cycles == False:
            return
        while len(cycles) > 0:
            cyc1 = random.choice(cycles)
 
            a, b = cyc1.c2, cyc1.c1
            v1 = cyc1.begin
            v2 = cyc1.end
            c = 6 - a - b

            ac_cycle = self.factor_graph(a, c)
            bc_cycle = self.factor_graph(b, c)
            resolutions = ac_cycle + bc_cycle
            
            for x in resolutions:
                x.invert_colors()
                temp = create_path(self.graph, v1, b, a)
                if temp.is_closed() != True:
                    temp.invert_colors()
                    for cc in cycles:
                        if temp.end in cc:
                            cycles.remove(cc)
                    print ("resolve two variables")
                    break
                x.invert_colors()

            return False

        return True
    def not_finished_cycles_algorithm(self):
        cycles = self.find_locking_cycles()
        if cycles == False:
            return
        while len(cycles) > 0:
            cyc1 = random.choice(cycles)
 
            a, b = cyc1.c2, cyc1.c1
            v1 = cyc1.begin
            v2 = cyc1.end
            c = 6 - a - b

            ac_cycle = self.factor_graph(a, c)
            bc_cycle = self.factor_graph(b, c)
            resolutions = ac_cycle + bc_cycle
            
            for x in resolutions:
                x.invert_colors()
                temp = create_path(self.graph, v1, b, a)
                if temp.is_closed() != True:
                    temp.invert_colors()
                    for cc in cycles:
                        if temp.end in cc:
                            cycles.remove(cc)
                    print "resolve two variables"
                    break
                x.invert_colors()

            return False

        return True
    def check_resolvable(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        if len(errors) != 2:
            print "errors not equal 2, return false"
            return False

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)

        if (la + lb) != (ra + rb):
            print "Two variable not same, return false"
            return False

        path_1 = create_path(self.graph, v1, lb, la)
        if path_1.is_closed() != True:
            print "Two variables are connected!"
            return True

        return self._sub_routine_for_resolve(path_1)
    def find_locking_cycles(self, standard = True):
        etype = None
        variables = []
        for edge in self.graph.errors:
            variables.append(edge)
            if etype == None:
                etype = edge.edge_type
            elif edge.edge_type != etype:
                print "Not homogeneous configuration!"
                return False # different variables found
        
        if standard == True:
            if etype == "ac":
                self.graph.swap_colors(1, 3)
            elif etype == "bc":
                self.graph.swap_colors(2, 3)

        cycles = []
        while len(variables) > 0:
            edge = variables.pop()
            (a, b) = edge.get_endpoints()
            ca = edge.link_color(a)
            cb = edge.link_color(b)
            temp = create_path(self.graph, a, cb, ca)
            if temp.is_closed() == True:
                cycles.append(temp)
            else:
                end = temp.end
                temp.invert_colors()
                for xx in variables:
                    if end in xx:
                        variables.remove(xx)
                        break
        return cycles
    def check_resolvable(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        if len(errors) != 2:
            print("errors not equal 2, return false")
            return False

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)

        if (la + lb) != (ra + rb):
            print("Two variable not same, return false")
            return False

        path_1 = create_path(self.graph, v1, lb, la)
        if path_1.is_closed() != True:
            print("Two variables are connected!")
            return True

        return self._sub_routine_for_resolve(path_1)
예제 #18
0
    def find_locking_cycles(self, standard = True):
        etype = None
        variables = []
        for edge in self.graph.errors:
            variables.append(edge)
            if etype == None:
                etype = edge.edge_type
            elif edge.edge_type != etype:
                print ("Not homogeneous configuration!")
                return False # different variables found
        
        if standard == True:
            if etype == "ac":
                self.graph.swap_colors(1, 3)
            elif etype == "bc":
                self.graph.swap_colors(2, 3)

        cycles = []
        while len(variables) > 0:
            edge = variables.pop()
            (a, b) = edge.get_endpoints()
            ca = edge.link_color(a)
            cb = edge.link_color(b)
            temp = create_path(self.graph, a, cb, ca)
            if temp.is_closed() == True:
                cycles.append(temp)
            else:
                end = temp.end
                temp.invert_colors()
                for xx in variables:
                    if end in xx:
                        variables.remove(xx)
                        break
        return cycles
    def bicycle_layout(self, width=600, height=600, margin=20):
        if not hasattr(self, 'state') or self.state != "two cycles":
            cycles = self.find_two_cycle()
            if cycles == None:
                print("not has two cycles")
                return False
            else:
                self.state = "two cycles"
                self.left_p, self.right_p = cycles

        left_top = self.left_p.begin
        right_top = self.right_p.begin
        radius = width * 0.6
        import math
        rad = 2 * math.asin(0.5 * float(height - 2 * margin) / radius)

        for index in range(0, len(self.left_p), 1):
            p_rad = index * rad / (len(self.left_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 -
                                                                p_rad) * radius
            p_x = margin + math.cos(rad / 2 - p_rad) * radius - math.cos(
                rad / 2) * radius
            self.graph._positions[self.left_p._vertices[index]] = (p_x, p_y)

        for index in range(0, len(self.right_p), 1):
            p_rad = index * rad / (len(self.right_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 -
                                                                p_rad) * radius
            p_x = width - margin - (math.cos(rad / 2 - p_rad) * radius -
                                    math.cos(rad / 2) * radius)
            self.graph._positions[self.right_p._vertices[index]] = (p_x, p_y)

        color_a = self.left_p.c1
        color_b = self.left_p.c2

        other_vertices = []
        for vertex in self.graph._vertices:
            if (vertex not in self.left_p) and (vertex not in self.right_p):
                other_vertices.append(int(vertex))

        cycle = []
        while len(other_vertices) > 0:
            start = other_vertices[0]
            p = create_path(self.graph, start, color_a, color_b)
            for x in p._vertices:
                other_vertices.remove(int(x))
            cycle.append(p._vertices)

        x0 = width / 2
        step = (height - 2 * margin) / (len(cycle) + 1)
        for i in range(0, len(cycle), 1):
            y0 = margin + (i + 1) * step
            step_angle = 2 * math.pi / len(cycle[i])
            for j in range(0, len(cycle[i]), 1):
                x = x0 + math.cos(j * step_angle) * (width - 2 * margin) / 6
                y = y0 + math.sin(j * step_angle) * (width - 2 * margin) / 6
                self.graph._positions[cycle[i][j]] = (x, y)

        return True
    def highlight_bc_exclusive_chain(self):
        if not hasattr(self, "state") or self.state != "exclusive chain":
            cycles = self.find_two_cycle()
            if cycles == None:
                print "not has two cycles"
                return False
            else:
                self.state = "exclusive chain"
                if cycles[0].c1 == 1:
                    self.ac_chain = create_path(self.graph, cycles[0].end, 3, 1)
                    self.bc_chain = create_path(self.graph, cycles[0].begin, 3, 2)
                else:
                    self.ac_chain = create_path(self.graph, cycles[0].begin, 3, 1)
                    self.bc_chain = create_path(self.graph, cycles[0].end, 3, 2)

        self.highlighted = [self.bc_chain]
        return self.prepare_highlight_data()
예제 #21
0
 def highlight_bc_exclusive_chain(self):
     if not hasattr(self, 'state') or self.state != "exclusive chain":
         cycles = self.find_two_cycle()
         if cycles == None:
             print "not has two cycles"
             return False
         else:
             self.state = "exclusive chain"
             if cycles[0].c1 == 1:
                 self.ac_chain = create_path(self.graph, cycles[0].end, 3, 1)
                 self.bc_chain = create_path(self.graph, cycles[0].begin, 3, 2)
             else:
                 self.ac_chain = create_path(self.graph, cycles[0].begin, 3, 1)
                 self.bc_chain = create_path(self.graph, cycles[0].end, 3, 2)
     
     self.highlighted = [self.bc_chain]
     return self.prepare_highlight_data()
    def format_location(cls, graph, kaixuanmen, width=600, height=600, margin=20):
        left, right, left_top, right_top, ceil = kaixuanmen
        radius = width
        import math
        rad = 2 * math.asin( 0.5 * float(height - 2 * margin) / radius )
        
        left_p = create_path(graph, left_top, left.link_color(left.get_another_vertex(left_top)), left.link_color(left_top))
        for index in range(0, len(left_p), 1):
            p_rad = index * rad / (len(left_p)-1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 - p_rad) * radius
            p_x = margin + math.cos(rad /2 - p_rad) * radius - math.cos(rad / 2) * radius
            graph._positions[left_p._vertices[index]] = (p_x, p_y)
       
        right_p = create_path(graph, right_top, right.link_color(right.get_another_vertex(right_top)), right.link_color(right_top))
        for index in range(0, len(right_p), 1):
            p_rad = index * rad / (len(right_p)-1)
            p_y = margin + (height - 2 * margin) /2 - math.sin(rad / 2 - p_rad) * radius
            p_x = width - margin - (math.cos(rad / 2 - p_rad) * radius - math.cos(rad / 2) * radius)
            graph._positions[right_p._vertices[index]] = (p_x, p_y)

        (la, lb) = left.links
        color_a = la.color
        color_b = lb.color

        other_vertices = []
        for vertex in graph._vertices:
            if (vertex not in left_p) and (vertex not in right_p):
                other_vertices.append(int(vertex))
         
        cycle = []
        while len(other_vertices) > 0:
            start = other_vertices[0]
            p = create_path(graph, start, color_a, color_b)
            for x in p._vertices:
                other_vertices.remove(int(x))
            cycle.append(p._vertices)

        x0 = width / 2
        step = (height - 2 * margin) / (len(cycle) + 1)
        for i in range(0,len(cycle),1):
            y0 = margin + (i + 1) * step
            step_angle = 2 * math.pi / len(cycle[i])
            for j in range(0, len(cycle[i]), 1):
                x = x0 + math.cos(j * step_angle) * (width - 2 * margin)/4
                y = y0 + math.sin(j * step_angle) * (width - 2 * margin)/4
                graph._positions[cycle[i][j]] = (x,y)
    def count_resolve(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        if len(errors) != 2:
            print("errors not equal 2, return false")
            return

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)

        if la + lb != ra + rb:
            print("Two variable not same, return false")
            return

        left_p = create_path(self.graph, v1, lb, la)
        if left_p.is_closed() != True:
            print("Error: Two variables are connected!")
            return
        right_p = create_path(self.graph, v3, rb, ra)

        count = 0

        for i in range(0, 2 * len(left_p)):
            for j in range(0, 2 * len(right_p)):
                if self._sub_routine_for_resolve(left_p):
                    count = count + 1
                right_p.move_one_step()
            left_p.move_one_step()

        print(
            "Total: ",
            4,
            "*",
            len(left_p),
            "*",
            len(right_p),
        )
        print(" = ", 4 * len(left_p) * len(right_p))
        print("Solution #: ", count)
예제 #24
0
 def invert_right_xy(cls, graph):
     result, err_msg, left, right, left_top, right_top, ceil = cls(
     ).find_KaiXuanMen(graph)
     right_bottom = right.get_another_vertex(right_top)
     path = create_path(graph, right_top, right.link_color(right_bottom),
                        right.link_color(right_top))
     path.swap_colors(right.link_color(right_bottom),
                      right.link_color(right_top))
예제 #25
0
    def count_solutions(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            return -1
        
        right_p = create_path(self.graph, v3, b, a)
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        count = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self._sub_routine_for_count(left_p):
                    count = count + 1
                right_p.move_one_step()
            left_p.move_one_step()
        
        return float(count) / (4 * len_left * len_right)
    def count_solutions(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            return -1
        
        right_p = create_path(self.graph, v3, b, a)
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        count = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self._sub_routine_for_count(left_p):
                    count = count + 1
                right_p.move_one_step()
            left_p.move_one_step()
        
        return float(count) / (4 * len_left * len_right)
    def bicycle_layout(self, width=600, height=600, margin=20):
        if not hasattr(self, "state") or self.state != "two cycles":
            cycles = self.find_two_cycle()
            if cycles == None:
                print "not has two cycles"
                return False
            else:
                self.state = "two cycles"
                self.left_p, self.right_p = cycles

        left_top = self.left_p.begin
        right_top = self.right_p.begin
        radius = width * 0.6
        import math

        rad = 2 * math.asin(0.5 * float(height - 2 * margin) / radius)

        for index in range(0, len(self.left_p), 1):
            p_rad = index * rad / (len(self.left_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 - p_rad) * radius
            p_x = margin + math.cos(rad / 2 - p_rad) * radius - math.cos(rad / 2) * radius
            self.graph._positions[self.left_p._vertices[index]] = (p_x, p_y)

        for index in range(0, len(self.right_p), 1):
            p_rad = index * rad / (len(self.right_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 - p_rad) * radius
            p_x = width - margin - (math.cos(rad / 2 - p_rad) * radius - math.cos(rad / 2) * radius)
            self.graph._positions[self.right_p._vertices[index]] = (p_x, p_y)

        color_a = self.left_p.c1
        color_b = self.left_p.c2

        other_vertices = []
        for vertex in self.graph._vertices:
            if (vertex not in self.left_p) and (vertex not in self.right_p):
                other_vertices.append(int(vertex))

        cycle = []
        while len(other_vertices) > 0:
            start = other_vertices[0]
            p = create_path(self.graph, start, color_a, color_b)
            for x in p._vertices:
                other_vertices.remove(int(x))
            cycle.append(p._vertices)

        x0 = width / 2
        step = (height - 2 * margin) / (len(cycle) + 1)
        for i in range(0, len(cycle), 1):
            y0 = margin + (i + 1) * step
            step_angle = 2 * math.pi / len(cycle[i])
            for j in range(0, len(cycle[i]), 1):
                x = x0 + math.cos(j * step_angle) * (width - 2 * margin) / 6
                y = y0 + math.sin(j * step_angle) * (width - 2 * margin) / 6
                self.graph._positions[cycle[i][j]] = (x, y)

        return True
예제 #28
0
    def find_KaiXuanMen(cls, graph):
        ''' contaions only two variables of the same kind
            which are linked by a ceil edge
            and the two variables are in different kempe cycles
        '''
        errors = []
        for edge in graph.edges:
            if edge.is_error():
                errors.append(edge)
        if len(errors) != 2:
            err_msg = "errors not equal 2, return false"
            return (False, err_msg, None, None, None, None, None)

        left = errors[0]
        right = errors[1]
        (la, lb) = left.links
        (ra, rb) = right.links
        if la.color + lb.color != ra.color + rb.color:
            err_msg = "Two variable not same, return false"
            return (False, err_msg, None, None, None, None, None)

        ceil = None
        (la, lb) = left.get_endpoints()
        (ra, rb) = right.get_endpoints()

        if graph.get_edge_by_endpoint(la, ra) != None:
            left_top, right_top = la, ra
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(la, rb) != None:
            left_top, right_top = la, rb
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(lb, ra) != None:
            left_top, right_top = lb, ra
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(lb, rb) != None:
            left_top, right_top = lb, rb
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if ceil == None:
            err_msg = "format color failed! Two variable not adjacent, return false"
            return (False, err_msg, None, None, None, None, None)

        left_p = create_path(
            graph, left_top,
            left.link_color(left.get_another_vertex(left_top)),
            left.link_color(left_top))
        if left_p.is_closed() != True:
            err_msg = "left path not closed. Two variables are linked by kempe path, return false"
            return (False, err_msg, None, None, None, None, None)

        return (True, "", left, right, left_top, right_top, ceil)
    def standard_format(cls, graph, width=600, height=600, margin=20):
        result, err_msg, left, right, left_top, right_top, ceil = cls().find_KaiXuanMen(graph)
        if result == False:
            print err_msg
            return False

        if ceil.color != 3:
            graph.swap_colors(ceil.color,3)

        if left.link_color(left_top) != 2:
            p = create_path(graph, left_top, 2, 1)
            p.swap_colors(1, 2)
        
        if right.link_color(right_top) != 2:
            p = create_path(graph, right_top, 2, 1)
            p.swap_colors(1, 2)

        kaixuanmen = (left, right, left_top, right_top, ceil)
        cls().format_location(graph, kaixuanmen, width, height, margin)
        return True
예제 #30
0
    def standard_format(cls, graph, width=600, height=600, margin=20):
        result, err_msg, left, right, left_top, right_top, ceil = cls(
        ).find_KaiXuanMen(graph)
        if result == False:
            print err_msg
            return False

        if ceil.color != 3:
            graph.swap_colors(ceil.color, 3)

        if left.link_color(left_top) != 2:
            p = create_path(graph, left_top, 2, 1)
            p.swap_colors(1, 2)

        if right.link_color(right_top) != 2:
            p = create_path(graph, right_top, 2, 1)
            p.swap_colors(1, 2)

        kaixuanmen = (left, right, left_top, right_top, ceil)
        cls().format_location(graph, kaixuanmen, width, height, margin)
        return True
예제 #31
0
 def factor_graph(self, x, y):
     vid_list = self.graph.vid_list
     rc = list()
     while len(vid_list) > 0:
         v = random.choice(vid_list)
         temp = create_path(self.graph, v, x, y)
         for v in temp:
             if v in vid_list:
                 vid_list.remove(v)
         if temp.is_closed():
             rc.append(temp)
     return rc
 def factor_graph(self, x, y):
     vid_list = self.graph.vid_list
     rc = list()
     while len(vid_list) > 0:
         v = random.choice(vid_list)
         temp = create_path(self.graph, v, x, y)
         for v in temp:
             if v in vid_list:
                 vid_list.remove(v)
         if temp.is_closed():
             rc.append(temp)
     return rc
    def find_KaiXuanMen(cls, graph):
        ''' contaions only two variables of the same kind
            which are linked by a ceil edge
            and the two variables are in different kempe cycles
        '''
        errors = []
        for edge in graph.edges:
            if edge.is_error():
                errors.append(edge)
        if len(errors) != 2:
            err_msg = "errors not equal 2, return false"
            return (False, err_msg, None, None, None, None, None) 

        left = errors[0]
        right = errors[1]
        (la, lb) = left.links
        (ra, rb) = right.links
        if la.color + lb.color != ra.color + rb.color:
            err_msg = "Two variable not same, return false"
            return (False, err_msg, None, None, None, None, None)

        ceil = None
        (la, lb) = left.get_endpoints()
        (ra, rb) = right.get_endpoints()
        
        if graph.get_edge_by_endpoint(la, ra) != None:
            left_top, right_top = la, ra
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(la, rb) != None:
            left_top, right_top = la, rb
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(lb, ra) != None:
            left_top, right_top = lb, ra
            ceil = graph.get_edge_by_endpoint(left_top, right_top)

        if graph.get_edge_by_endpoint(lb, rb) != None:
            left_top, right_top = lb, rb
            ceil = graph.get_edge_by_endpoint(left_top, right_top)
            
        if ceil == None:
            err_msg = "format color failed! Two variable not adjacent, return false"
            return (False, err_msg, None, None, None, None, None)


        left_p = create_path(graph, left_top, left.link_color(left.get_another_vertex(left_top)), left.link_color(left_top))
        if left_p.is_closed() != True:
            err_msg = "left path not closed. Two variables are linked by kempe path, return false"
            return (False, err_msg, None, None, None, None, None)

        return (True, "", left, right, left_top, right_top, ceil)
    def count_resolve(self):
        errors = []
        for edge in self.graph.errors:
            errors.append(edge)
        if len(errors) != 2:
            print "errors not equal 2, return false"
            return

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)

        if la + lb != ra + rb:
            print "Two variable not same, return false"
            return

        left_p = create_path(self.graph, v1, lb, la)
        if left_p.is_closed() != True:
            print "Error: Two variables are connected!"
            return
        right_p = create_path(self.graph, v3, rb, ra)

        count = 0

        for i in range(0, 2 * len(left_p)):
            for j in range(0, 2 * len(right_p)):
                if self._sub_routine_for_resolve(left_p):
                    count = count + 1
                right_p.move_one_step()
            left_p.move_one_step()

        print "Total: ", 4, "*", len(left_p), "*", len(right_p),
        print " = ", 4 * len(left_p) * len(right_p)
        print "Solution #: ", count
예제 #35
0
 def factor_cycle(self, vertices, x, y):
     # vertices is the v_id list
     cycles = []
     paths = []
     while len(vertices) > 0:
         s = vertices[0]
         cycle1 = []
         path = create_path(self.graph, s, x, y)
         paths.append(path)
         assert path.is_closed(), "assert path.is_closed()"
         for v in path:
             cycle1.append(v)
             vertices.remove(v)
         cycles.append(list(cycle1))
     return paths
 def factor_cycle(self, vertices, x, y):
     # vertices is the v_id list
     cycles = []
     paths = []
     while len(vertices) > 0:
         s = vertices[0]
         cycle1 = []
         path = create_path(self.graph, s, x, y)
         paths.append(path)
         assert path.is_closed(), "assert path.is_closed()"
         for v in path:
             cycle1.append(v)
             vertices.remove(v)
         cycles.append(list(cycle1))
     return paths
 def smooth(self):
     for v in self.graph.vertices:
         if len(self.graph._neighbors[v.id]) == 2:
             eid1, eid2 = self.graph._neighbors[v.id]
             edge1 = self.graph.get_edge(eid1)
             edge2 = self.graph.get_edge(eid2)
             vid1 = edge1.get_another_vertex(v.id)
             vid2 = edge2.get_another_vertex(v.id)
             c1 = edge1.get_link(vid1).color
             c2 = edge2.get_link(vid2).color
             neweid = self.graph.smooth_vertex(v.id)
             edge = self.graph.get_edge(neweid)
             edge.get_link(vid1).color = c1
             edge.get_link(vid2).color = c2
             path = create_path(self.graph, vid1, c2, c1)
             if not path.is_closed():
                 path.invert_colors()
예제 #38
0
 def smooth(self):
     for v in self.graph.vertices:
         if len(self.graph._neighbors[v.id]) == 2:
             eid1, eid2 = self.graph._neighbors[v.id]
             edge1 = self.graph.get_edge(eid1)
             edge2 = self.graph.get_edge(eid2)
             vid1 = edge1.get_another_vertex(v.id)
             vid2 = edge2.get_another_vertex(v.id)
             c1 = edge1.get_link(vid1).color
             c2 = edge2.get_link(vid2).color
             neweid = self.graph.smooth_vertex(v.id)
             edge = self.graph.get_edge(neweid)
             edge.get_link(vid1).color = c1
             edge.get_link(vid2).color = c2
             path = create_path(self.graph, vid1, c2, c1)
             if not path.is_closed():
                 path.invert_colors()
    def easy_put_back(self):
        # check to see if there is edge removed.
        # if yes, simply put it back. And resolve the variables if it is easy.
        # return (k, Boolean)
        # k is the length of the cycle
        # Boolean is whether the variables are cleared up.
        if len(self.removed) > 0:
            e1, e2, cycle = self.removed.pop()
        else:
            print "nothing to put back"
            return

        colors = {1, 2, 3}
        k = len(cycle)
        #print "k: ", k
        a, b = tuple(cycle[:2])
        
        if k == 2:
            #          _
            # c -- a -/ \- b -- d
            #         \_/
            # e_1 = c -- b
            # e_2 = c -- d
            #
            edge = self.graph.get_edge(e2)
            x0 = edge.color
            x1, x2 = tuple(colors - {x0})
            (c, d) = edge.get_endpoints()
           
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f1 = self.graph.add_edge(a, b)
            f2 = self.graph.add_edge(a, b)
            f3 = self.graph.add_edge(a, c)
            f4 = self.graph.add_edge(b, d)
            self.graph.get_edge(f1).color = x1
            self.graph.get_edge(f2).color = x2
            self.graph.get_edge(f3).color = x0
            self.graph.get_edge(f4).color = x0
            self.state = "proper"
            return (k, True)
        
        edge_1 = self.graph.get_edge(e1)
        edge_2 = self.graph.get_edge(e2)
        
        if k == 3:
            # see p2
            x1 = edge_1.color
            x2 = edge_2.color
            x0 = 6 - x1 - x2
            v2 = cycle[2]
            v5 = edge_1.get_another_vertex(v2)
            v6 = edge_2.get_another_vertex(v2)
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f0 = self.graph.add_edge(a, b)
            f1 = self.graph.add_edge(a, v2)
            f2 = self.graph.add_edge(a, v5)
            f3 = self.graph.add_edge(b, v2)
            f4 = self.graph.add_edge(b, v6)
            self.graph.get_edge(f0).color = x0
            self.graph.get_edge(f1).color = x2
            self.graph.get_edge(f2).color = x1
            self.graph.get_edge(f3).color = x1
            self.graph.get_edge(f4).color = x2
            self.state = "proper"
            return (k, True)

        if k == 4:
            # see p3
            v2 = cycle[2]
            v1 = cycle[3]
            v5 = edge_1.get_another_vertex(v1)
            v6 = edge_2.get_another_vertex(v2)
            edge = self.graph.get_edge_by_endpoints(v1, v2)
            x0 = edge.color
            x1 = edge_1.color
            x2 = 6 - x0 - x1
            x3 = edge_2.color
            # case 0, different color, independent cycles
            if x3 != x1:
                # different color
                path = create_path(self.graph, v2, x3, x1)
                if not v1 in path: # independent cycle
                    path.swap_colors(x1, x3) # edge_1 and edge_2 should have the same color now
            x3 = edge_2.color # updated

            # put edges back
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f0 = self.graph.add_edge(a, b)
            f1 = self.graph.add_edge(a, v1)
            f2 = self.graph.add_edge(a, v5)
            f3 = self.graph.add_edge(b, v2)
            f4 = self.graph.add_edge(b, v6)

            # case 1, same color
            if x1 == x3:
                self.graph.get_edge(f0).color = x2
                self.graph.get_edge(f1).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f3).color = x0
                self.graph.get_edge(f4).color = x1
                edge.color = x1
            else: # case 2, different color, one cycle
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x2
                self.graph.get_link(f1, v1).color = x1
                self.graph.get_link(f1, a).color = x2
                self.graph.get_link(f3, v2).color = x2
                self.graph.get_link(f3, b).color = x1
                path = create_path(self.graph, v1, x2, x1)
                path.swap_colors(x1, x2)
            self.state = "proper"
            return (k, True)

        if k == 5:
            v1, v2, v3, v4, v5 = tuple(cycle)
            v8 = edge_1.get_another_vertex(v5)
            v6 = edge_2.get_another_vertex(v3)
            x1 = edge_1.color
            x3 = edge_2.color
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(v1)
            self.graph.add_vertex(v2)
            f0 = self.graph.add_edge(v1, v2)
            f1 = self.graph.add_edge(v1, v5)
            f2 = self.graph.add_edge(v1, v8)
            f3 = self.graph.add_edge(v2, v3)
            f4 = self.graph.add_edge(v2, v6)

            if x1 == x3:
                # case (a, b)|(a, b)
                x2 = self.graph.get_edge_by_endpoints(v4, v5).color
                x0 = 6 - x1 - x2
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x1
                self.graph.get_link(f1, v5).color = x1
                self.graph.get_link(f1, v1).color = x2
                self.graph.get_link(f3, v3).color = x1
                self.graph.get_link(f3, v2).color = x2
                path = create_path(self.graph, v2, x1, x2)
                if not path.is_closed(): # not blocked, two var cancelled
                    path.swap_colors(x1, x2)
                    self.state = "proper"
                    return (k, True)
            else:
                x2 = x3
                x0 = 6 - x1 - x2
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x2
                self.graph.get_link(f1, v5).color = x1
                self.graph.get_link(f1, v1).color = x2
                self.graph.get_link(f3, v3).color = x2
                self.graph.get_link(f3, v2).color = x1
                path = create_path(self.graph, v2, x2, x1)
                path.swap_colors(x1, x2)
                if not path.is_closed(): # not blocked, two var cancelled
                    self.state = "proper"
                    return (k, True)

            # if var not cancelled, it is formatted as (x1, x2) | (x1, x2) type
            v7 = filter(lambda v: not v in [v1, v4], self.graph.get_vertex(v5).neighbor_vertices)[0]
            v9 = filter(lambda v: not v in [v3, v5], self.graph.get_vertex(v4).neighbor_vertices)[0]
            v10 = filter(lambda v: not v in [v2, v4], self.graph.get_vertex(v3).neighbor_vertices)[0]
            f5 = self.graph.get_edge_by_endpoints(v5, v7).id
            f6 = self.graph.get_edge_by_endpoints(v4, v9).id
            f7 = self.graph.get_edge_by_endpoints(v3, v10).id
            f8 = self.graph.get_edge_by_endpoints(v4, v5).id
            f9 = self.graph.get_edge_by_endpoints(v3, v4).id
            
            self.vertices = (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
            self.edges = (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
            self.state = "petersen"
            return (k, False)

        return (k, False)
예제 #40
0
    def false_algorithm_1(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            print ("errors not equal 2, return false")
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            print ("Two variable not same, return false")
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            left_p.swap_colors(b, a)
            return True
        
        if self.graph.multiplicity(v1, v3) == 1:
            x, y = v1, v3
        elif self.graph.multiplicity(v1, v4) == 1:
            x, y = v1, v4
        elif self.graph.multiplicity(v2, v3) == 1:
            x, y = v2, v3
        elif self.graph.multiplicity(v2, v4) == 1:
            x, y = v2, v4
        else:
            raise Exception("weriuhgas")

        xx = v1 + v2 - x
        yy = v3 + v4 - y

        vid_x = self.graph.neighbor_vid_list(x)
        vid_y = self.graph.neighbor_vid_list(y)
        vid_x.remove(y)
        vid_y.remove(x)

        x1, x2 = vid_x
        y1, y2 = vid_y

        def list_to_set(li):
            ss = set()
            for x in li:
                ss.add(x)
            return ss

        temp1 = self.graph.neighbor_vid_list(x1)

        ###################

        right_p = create_path(self.graph, v3, b, a)
        
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        steps = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self.sub_routine_for_bicycle_algorithm(left_p, right_p):
                    count_utility.count(steps)
                    return True
                right_p.move_one_step()
                steps = steps + 1
            left_p.move_one_step()
        
        return False
    def false_algorithm_1(self):
        errors = []
        for e in self.graph.errors:
            errors.append(e)
        
        if len(errors) != 2:
            print "errors not equal 2, return false"
            return False 

        left = errors[0]
        right = errors[1]
        (v1, v2) = left.get_endpoints()
        (v3, v4) = right.get_endpoints()
        la = left.link_color(v1)
        lb = left.link_color(v2)
        ra = right.link_color(v3)
        rb = right.link_color(v4)
        
        a, b = la, lb
        if (la, lb) == (ra, rb):
            pass
        elif (la, lb) == (rb, ra):
            v3, v4 = v4, v3
        else:
            print "Two variable not same, return false"
            return False

        left_p = create_path(self.graph, v1, b, a)
        if left_p.is_closed() != True:
            left_p.swap_colors(b, a)
            return True
        
        if self.graph.multiplicity(v1, v3) == 1:
            x, y = v1, v3
        elif self.graph.multiplicity(v1, v4) == 1:
            x, y = v1, v4
        elif self.graph.multiplicity(v2, v3) == 1:
            x, y = v2, v3
        elif self.graph.multiplicity(v2, v4) == 1:
            x, y = v2, v4
        else:
            raise Exception("weriuhgas")

        xx = v1 + v2 - x
        yy = v3 + v4 - y

        vid_x = self.graph.neighbor_vid_list(x)
        vid_y = self.graph.neighbor_vid_list(y)
        vid_x.remove(y)
        vid_y.remove(x)

        x1, x2 = vid_x
        y1, y2 = vid_y

        def list_to_set(li):
            ss = set()
            for x in li:
                ss.add(x)
            return ss

        temp1 = self.graph.neighbor_vid_list(x1)

        ###################

        right_p = create_path(self.graph, v3, b, a)
        
        
        len_left = len(left_p)
        len_right = len(right_p)
        
        steps = 0

        for i in range(0, 2 * len_left):
            for j in range(0, 2 * len_right):
                if self.sub_routine_for_bicycle_algorithm(left_p, right_p):
                    count_utility.count(steps)
                    return True
                right_p.move_one_step()
                steps = steps + 1
            left_p.move_one_step()
        
        return False
 def invert_right_xy(cls, graph):
     result, err_msg, left, right, left_top, right_top, ceil = cls().find_KaiXuanMen(graph)
     right_bottom = right.get_another_vertex(right_top)
     path = create_path(graph, right_top, right.link_color(right_bottom), right.link_color(right_top))
     path.swap_colors(right.link_color(right_bottom), right.link_color(right_top))
예제 #43
0
 def create_cycle_by_variable(self, var):
     (a,b) = var.get_endpoints()
     ca = var.link_color(a)
     cb = var.link_color(b)
     path = create_path(self.graph, a, b, cb, ca)
     return path
예제 #44
0
    def format_location(cls,
                        graph,
                        kaixuanmen,
                        width=600,
                        height=600,
                        margin=20):
        left, right, left_top, right_top, ceil = kaixuanmen
        radius = width
        import math
        rad = 2 * math.asin(0.5 * float(height - 2 * margin) / radius)

        left_p = create_path(
            graph, left_top,
            left.link_color(left.get_another_vertex(left_top)),
            left.link_color(left_top))
        for index in range(0, len(left_p), 1):
            p_rad = index * rad / (len(left_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 -
                                                                p_rad) * radius
            p_x = margin + math.cos(rad / 2 - p_rad) * radius - math.cos(
                rad / 2) * radius
            graph._positions[left_p._vertices[index]] = (p_x, p_y)

        right_p = create_path(
            graph, right_top,
            right.link_color(right.get_another_vertex(right_top)),
            right.link_color(right_top))
        for index in range(0, len(right_p), 1):
            p_rad = index * rad / (len(right_p) - 1)
            p_y = margin + (height - 2 * margin) / 2 - math.sin(rad / 2 -
                                                                p_rad) * radius
            p_x = width - margin - (math.cos(rad / 2 - p_rad) * radius -
                                    math.cos(rad / 2) * radius)
            graph._positions[right_p._vertices[index]] = (p_x, p_y)

        (la, lb) = left.links
        color_a = la.color
        color_b = lb.color

        other_vertices = []
        for vertex in graph._vertices:
            if (vertex not in left_p) and (vertex not in right_p):
                other_vertices.append(int(vertex))

        cycle = []
        while len(other_vertices) > 0:
            start = other_vertices[0]
            p = create_path(graph, start, color_a, color_b)
            for x in p._vertices:
                other_vertices.remove(int(x))
            cycle.append(p._vertices)

        x0 = width / 2
        step = (height - 2 * margin) / (len(cycle) + 1)
        for i in range(0, len(cycle), 1):
            y0 = margin + (i + 1) * step
            step_angle = 2 * math.pi / len(cycle[i])
            for j in range(0, len(cycle[i]), 1):
                x = x0 + math.cos(j * step_angle) * (width - 2 * margin) / 4
                y = y0 + math.sin(j * step_angle) * (width - 2 * margin) / 4
                graph._positions[cycle[i][j]] = (x, y)
예제 #45
0
    def easy_put_back(self):
        # check to see if there is edge removed.
        # if yes, simply put it back. And resolve the variables if it is easy.
        # return (k, Boolean)
        # k is the length of the cycle
        # Boolean is whether the variables are cleared up.
        if len(self.removed) > 0:
            e1, e2, cycle = self.removed.pop()
        else:
            print ("nothing to put back")
            return

        colors = {1, 2, 3}
        k = len(cycle)
        #print "k: ", k
        a, b = tuple(cycle[:2])
        
        if k == 2:
            #          _
            # c -- a -/ \- b -- d
            #         \_/
            # e_1 = c -- b
            # e_2 = c -- d
            #
            edge = self.graph.get_edge(e2)
            x0 = edge.color
            x1, x2 = tuple(colors - {x0})
            (c, d) = edge.get_endpoints()
           
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f1 = self.graph.add_edge(a, b)
            f2 = self.graph.add_edge(a, b)
            f3 = self.graph.add_edge(a, c)
            f4 = self.graph.add_edge(b, d)
            self.graph.get_edge(f1).color = x1
            self.graph.get_edge(f2).color = x2
            self.graph.get_edge(f3).color = x0
            self.graph.get_edge(f4).color = x0
            self.state = "proper"
            return (k, True)
        
        edge_1 = self.graph.get_edge(e1)
        edge_2 = self.graph.get_edge(e2)
        
        if k == 3:
            # see p2
            x1 = edge_1.color
            x2 = edge_2.color
            x0 = 6 - x1 - x2
            v2 = cycle[2]
            v5 = edge_1.get_another_vertex(v2)
            v6 = edge_2.get_another_vertex(v2)
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f0 = self.graph.add_edge(a, b)
            f1 = self.graph.add_edge(a, v2)
            f2 = self.graph.add_edge(a, v5)
            f3 = self.graph.add_edge(b, v2)
            f4 = self.graph.add_edge(b, v6)
            self.graph.get_edge(f0).color = x0
            self.graph.get_edge(f1).color = x2
            self.graph.get_edge(f2).color = x1
            self.graph.get_edge(f3).color = x1
            self.graph.get_edge(f4).color = x2
            self.state = "proper"
            return (k, True)

        if k == 4:
            # see p3
            v2 = cycle[2]
            v1 = cycle[3]
            v5 = edge_1.get_another_vertex(v1)
            v6 = edge_2.get_another_vertex(v2)
            edge = self.graph.get_edge_by_endpoints(v1, v2)
            x0 = edge.color
            x1 = edge_1.color
            x2 = 6 - x0 - x1
            x3 = edge_2.color
            # case 0, different color, independent cycles
            if x3 != x1:
                # different color
                path = create_path(self.graph, v2, x3, x1)
                if not v1 in path: # independent cycle
                    path.swap_colors(x1, x3) # edge_1 and edge_2 should have the same color now
            x3 = edge_2.color # updated

            # put edges back
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(a)
            self.graph.add_vertex(b)
            f0 = self.graph.add_edge(a, b)
            f1 = self.graph.add_edge(a, v1)
            f2 = self.graph.add_edge(a, v5)
            f3 = self.graph.add_edge(b, v2)
            f4 = self.graph.add_edge(b, v6)

            # case 1, same color
            if x1 == x3:
                self.graph.get_edge(f0).color = x2
                self.graph.get_edge(f1).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f3).color = x0
                self.graph.get_edge(f4).color = x1
                edge.color = x1
            else: # case 2, different color, one cycle
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x2
                self.graph.get_link(f1, v1).color = x1
                self.graph.get_link(f1, a).color = x2
                self.graph.get_link(f3, v2).color = x2
                self.graph.get_link(f3, b).color = x1
                path = create_path(self.graph, v1, x2, x1)
                path.swap_colors(x1, x2)
            self.state = "proper"
            return (k, True)

        if k == 5:
            v1, v2, v3, v4, v5 = tuple(cycle)
            v8 = edge_1.get_another_vertex(v5)
            v6 = edge_2.get_another_vertex(v3)
            x1 = edge_1.color
            x3 = edge_2.color
            self.graph.remove_edge(e1)
            self.graph.remove_edge(e2)
            self.graph.add_vertex(v1)
            self.graph.add_vertex(v2)
            f0 = self.graph.add_edge(v1, v2)
            f1 = self.graph.add_edge(v1, v5)
            f2 = self.graph.add_edge(v1, v8)
            f3 = self.graph.add_edge(v2, v3)
            f4 = self.graph.add_edge(v2, v6)

            if x1 == x3:
                # case (a, b)|(a, b)
                x2 = self.graph.get_edge_by_endpoints(v4, v5).color
                x0 = 6 - x1 - x2
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x1
                self.graph.get_link(f1, v5).color = x1
                self.graph.get_link(f1, v1).color = x2
                self.graph.get_link(f3, v3).color = x1
                self.graph.get_link(f3, v2).color = x2
                path = create_path(self.graph, v2, x1, x2)
                if not path.is_closed(): # not blocked, two var cancelled
                    path.swap_colors(x1, x2)
                    self.state = "proper"
                    return (k, True)
            else:
                x2 = x3
                x0 = 6 - x1 - x2
                self.graph.get_edge(f0).color = x0
                self.graph.get_edge(f2).color = x1
                self.graph.get_edge(f4).color = x2
                self.graph.get_link(f1, v5).color = x1
                self.graph.get_link(f1, v1).color = x2
                self.graph.get_link(f3, v3).color = x2
                self.graph.get_link(f3, v2).color = x1
                path = create_path(self.graph, v2, x2, x1)
                path.swap_colors(x1, x2)
                if not path.is_closed(): # not blocked, two var cancelled
                    self.state = "proper"
                    return (k, True)

            # if var not cancelled, it is formatted as (x1, x2) | (x1, x2) type
            v7 = filter(lambda v: not v in [v1, v4], self.graph.get_vertex(v5).neighbor_vertices)[0]
            v9 = filter(lambda v: not v in [v3, v5], self.graph.get_vertex(v4).neighbor_vertices)[0]
            v10 = filter(lambda v: not v in [v2, v4], self.graph.get_vertex(v3).neighbor_vertices)[0]
            f5 = self.graph.get_edge_by_endpoints(v5, v7).id
            f6 = self.graph.get_edge_by_endpoints(v4, v9).id
            f7 = self.graph.get_edge_by_endpoints(v3, v10).id
            f8 = self.graph.get_edge_by_endpoints(v4, v5).id
            f9 = self.graph.get_edge_by_endpoints(v3, v4).id
            
            self.vertices = (v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
            self.edges = (f0, f1, f2, f3, f4, f5, f6, f7, f8, f9)
            self.state = "petersen"
            return (k, False)

        return (k, False)
 def create_cycle_by_variable(self, var):
     (a,b) = var.get_endpoints()
     ca = var.link_color(a)
     cb = var.link_color(b)
     path = create_path(self.graph, a, b, cb, ca)
     return path