Beispiel #1
0
    def __init__(self, degree, n_nodes):
        # initialize kr
        generator = kr_util()
        self.kr = generator.build_kr(n_nodes, degree)

        g_p = graph_util().generate_random_regular_bipartite(n_nodes, degree)
        arbitrary_p = graph_util().generate_random_regular_bipartite(
            n_nodes, 1)

        # create the C versions of the graphs
        self.g_c_structure = graph.create_graph_structure_test(n_nodes)
        self.g_c = graph.create_graph_edges_test(n_nodes)
        self.g_c_copy = graph.create_graph_edges_test(n_nodes)
        for edge in g_p.edges_iter():
            graph.add_edge(self.g_c_structure, self.g_c, edge[0], edge[1])
        graph.copy_edges(self.g_c, self.g_c_copy, n_nodes)

        self.arbitrary_c = graph.create_graph_edges_test(n_nodes)
        for edge in arbitrary_p.edges_iter():
            graph.add_edge(self.g_c_structure, self.g_c, edge[0], edge[1])
            graph.set_edge(self.g_c_structure, self.g_c_copy, self.arbitrary_c,
                           edge[0], edge[1])

        # allocate solution
        self.solution = kapoorrizzi.create_matching_set()
 def test_approx_coloring(self):
     
     KR = kapoor_rizzi()
     
     degree = 40
     partition_n_nodes = 15
     
     # generate random graph
     g = graph_util().generate_random_regular_bipartite(partition_n_nodes, degree)
     
     # generate arbitrary partitions for approximation algo
     arbitrary = [graph_util().generate_random_regular_bipartite(partition_n_nodes, 1) for i in xrange((degree % 2) + 1)]
     
     # algorithm is destructive so save these for later comparisons
     original_nodes = g.nodes()
     arbitrary_edges = reduce(lambda x,y: x+y, (m.edges() for m in arbitrary))
     original_edges = g.edges() + arbitrary_edges
     
     solution = KR.solve(degree, g, arbitrary)
     
     # check the amount of matchings
     self.assertEqual(len(solution), degree + len(arbitrary), "Didn't get enough matchings")
     # check each matching:
     for matching in solution:
         # matching preserves nodes
         self.assertEquals(matching.nodes(), original_nodes)
         # every node has degree 1
         self.assertEquals(nx.degree_histogram(matching), [0, 2*partition_n_nodes])
     # matchings preserve edges
     matching_edges = reduce(lambda x,y: x+y, (m.edges() for m in solution))
     self.assertEquals(sorted(matching_edges), sorted(original_edges))#, "Mismatch between input and output edges")
    def test(self):
        degree = 40
        n_nodes = 15

        # initialize kr
        generator = kr_util()
        kr = generator.build_kr(n_nodes, degree, print_debug=True)
        
        # generate graph and arbitrary matching
        g_p = graph_util().generate_random_regular_bipartite(n_nodes, degree)
        arbitrary_p = graph_util().generate_random_regular_bipartite(n_nodes, 1)

        # create the C versions of the graphs, and copies
        g_c_structure = graph.create_graph_structure_test(n_nodes)
        g_c = graph.create_graph_edges_test(n_nodes)
        g_c_copy = graph.create_graph_edges_test(n_nodes)
        for edge in g_p.edges_iter():
            graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
        graph.copy_edges(g_c, g_c_copy, n_nodes)
        self.assertEqual(graph.get_max_degree(g_c, n_nodes), degree)
        self.assertEqual(graph.get_max_degree(g_c_copy, n_nodes), degree)

        arbitrary_c = graph.create_graph_edges_test(n_nodes)
        for edge in arbitrary_p.edges_iter():
            graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
            graph.set_edge(g_c_structure, g_c_copy, arbitrary_c, edge[0], edge[1])
        self.assertEqual(graph.get_max_degree(arbitrary_c, n_nodes), 1)

        # solve
        solution = kapoorrizzi.create_matching_set()
        kapoorrizzi.solve(kr, g_c_structure, g_c_copy, arbitrary_c, solution)

        # check solution

        # check that we have the correct number of matchings
        num_matchings = kapoorrizzi.get_num_matchings(solution)
        self.assertEqual(num_matchings, degree + 1)

        # check that each matching is a perfect matching
        for i in range(num_matchings):
            matching = kapoorrizzi.get_matching(solution, i)
            self.assertTrue(graph.is_perfect_matching(matching, n_nodes))

        # check sum of matchings equals the original graph
        matchings_graph_c = graph.create_graph_edges_test(n_nodes)
        for i in range(num_matchings):
            matching = kapoorrizzi.get_matching(solution, i)
            graph.add_edges(matchings_graph_c, matching, n_nodes)
        self.assertTrue(graph.are_equal(matchings_graph_c, g_c, n_nodes))

        # clean up
        kapoorrizzi.destroy_kr(kr)
        kapoorrizzi.destroy_matching_set(solution)
        graph.destroy_graph_structure_test(g_c_structure)
        graph.destroy_graph_edges_test(g_c)
        graph.destroy_graph_edges_test(g_c_copy)
        graph.destroy_graph_edges_test(arbitrary_c)

        pass
Beispiel #4
0
 def __init__(self, degree, n_nodes):
     self.degree = degree
     self.KR = kapoor_rizzi()
 
     # generate random graph
     self.g = graph_util().generate_random_regular_bipartite(n_nodes, degree)
     
     # generate arbitrary partitions for approximation algo
     self.arbitrary = [graph_util().generate_random_regular_bipartite(n_nodes, 1) for i in xrange((degree % 2) + 1)]
Beispiel #5
0
    def __init__(self, degree, n_nodes):
        self.degree = degree
        self.KR = kapoor_rizzi()

        # generate random graph
        self.g = graph_util().generate_random_regular_bipartite(
            n_nodes, degree)

        # generate arbitrary partitions for approximation algo
        self.arbitrary = [
            graph_util().generate_random_regular_bipartite(n_nodes, 1)
            for i in xrange((degree % 2) + 1)
        ]
Beispiel #6
0
    def test_graph_creation(self):
        generator = graph_util()
        
        for deg in xrange(2, 11, 2):
            for n_side in xrange(2*deg+4,33,7):
                g_p = generator.generate_random_regular_bipartite(n_side, deg)

                g_c_structure = graph.create_graph_structure_test(n_side)
                g_c = graph.create_graph_edges_test(n_side)
                
                # Create the graph in C
                # first n vertices are on left, second n are on right
                for edge in g_p.edges_iter():
                    graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
                    
                # Check that graph in C matches the graph in Python
                for node in xrange(2 * n_side):
                    self.assertEqual(g_p.degree(node), graph.get_degree(g_c, node))
                
                for node in xrange(2 * n_side):
                    if (g_p.degree(node) > 0):
                        self.assertTrue(graph.has_neighbor(g_c, node))

                graph.destroy_graph_structure_test(g_c_structure)
                graph.destroy_graph_edges_test(g_c)
        pass
Beispiel #7
0
    def test_irregular_graphs(self):
        ES = euler_split()
        generator = graph_util()

        for max_deg in xrange(2, 11, 2):
            for n_side in xrange(2 * max_deg + 4, 33, 7):
                for e in xrange(4, n_side * max_deg - 4, 10):

                    g = generator.generate_random_even_degree_bipartite(
                        n_side, max_deg, e)
                    g1, g2 = ES.split(g.copy())

                    # Add nodes, since they might have degree 0
                    for x in g.nodes():
                        g1.add_node(x)
                        g2.add_node(x)

                    self.assertEqual(g1.number_of_nodes(), g.number_of_nodes())
                    self.assertEqual(g2.number_of_nodes(), g.number_of_nodes())
                    self.assertEqual(len(g.edges()), 2 * len(g1.edges()))
                    self.assertEqual(len(g.edges()), 2 * len(g2.edges()))
                    self.assertEquals(sorted(g.edges()),
                                      sorted(g1.edges() + g2.edges()))
                    self.assertEquals(
                        [g1.degree(x) + g2.degree(x) for x in g.nodes()],
                        [g.degree(x) for x in g.nodes()])

        pass
    def test_irregular_graphs(self):
        ES = euler_split()
        generator = graph_util()

        for max_deg in xrange(2, 11, 2):
            for n_side in xrange(2 * max_deg + 4, 33, 7):
                for e in xrange(4, n_side * max_deg - 4, 10):

                    g = generator.generate_random_even_degree_bipartite(n_side, max_deg, e)
                    g1, g2 = ES.split(g.copy())

                    # Add nodes, since they might have degree 0
                    for x in g.nodes():
                        g1.add_node(x)
                        g2.add_node(x)

                    self.assertEqual(g1.number_of_nodes(), g.number_of_nodes())
                    self.assertEqual(g2.number_of_nodes(), g.number_of_nodes())
                    self.assertEqual(len(g.edges()), 2 * len(g1.edges()))
                    self.assertEqual(len(g.edges()), 2 * len(g2.edges()))
                    self.assertEquals(sorted(g.edges()), sorted(g1.edges() + g2.edges()))
                    self.assertEquals(
                        [g1.degree(x) + g2.degree(x) for x in g.nodes()], [g.degree(x) for x in g.nodes()]
                    )

        pass
Beispiel #9
0
    def test_approx_coloring(self):

        KR = kapoor_rizzi()

        degree = 40
        partition_n_nodes = 15

        # generate random graph
        g = graph_util().generate_random_regular_bipartite(
            partition_n_nodes, degree)

        # generate arbitrary partitions for approximation algo
        arbitrary = [
            graph_util().generate_random_regular_bipartite(
                partition_n_nodes, 1) for i in xrange((degree % 2) + 1)
        ]

        # algorithm is destructive so save these for later comparisons
        original_nodes = g.nodes()
        arbitrary_edges = reduce(lambda x, y: x + y,
                                 (m.edges() for m in arbitrary))
        original_edges = g.edges() + arbitrary_edges

        solution = KR.solve(degree, g, arbitrary)

        # check the amount of matchings
        self.assertEqual(len(solution), degree + len(arbitrary),
                         "Didn't get enough matchings")
        # check each matching:
        for matching in solution:
            # matching preserves nodes
            self.assertEquals(matching.nodes(), original_nodes)
            # every node has degree 1
            self.assertEquals(nx.degree_histogram(matching),
                              [0, 2 * partition_n_nodes])
        # matchings preserve edges
        matching_edges = reduce(lambda x, y: x + y,
                                (m.edges() for m in solution))
        self.assertEquals(sorted(matching_edges), sorted(
            original_edges))  #, "Mismatch between input and output edges")
Beispiel #10
0
    def test_irregular_graph(self):
        """Tests graphs that are not necessarily regular - some number of sources
        and destinations have no edges."""

        generator = graph_util()
        num_experiments = 100
        n_nodes = 256  # network with 8 racks of 32 nodes each
        n_racks = n_nodes / structures.MAX_NODES_PER_RACK

        for i in range(num_experiments):
            # generate admitted traffic
            g_p = generator.generate_random_regular_bipartite(n_nodes, 1)

            # choose a number of edges to remove
            num_edges_to_remove = random.randint(1, 256)
            # remove edges
            for j in range(num_edges_to_remove):
                while (True):
                    # choose an edge index at random
                    index = random.randint(0, n_nodes - 1)
                    edge = g_p.edges(index)
                    if edge != []:
                        edge_tuple = edge[0]
                        g_p.remove_edge(edge_tuple[0], edge_tuple[1])
                        break

            admitted = structures.create_admitted_traffic()
            admitted_copy = structures.create_admitted_traffic()
            for edge in g_p.edges_iter():
                structures.insert_admitted_edge(admitted, edge[0],
                                                edge[1] - n_nodes)
                structures.insert_admitted_edge(admitted_copy, edge[0],
                                                edge[1] - n_nodes)

            # select paths
            pathselection.select_paths(admitted, n_racks)

            # check that path assignments are valid
            self.assertTrue(pathselection.paths_are_valid(admitted, n_racks))

            # check that src addrs and lower bits of destination addrs are unchanged
            for e in range(admitted.size):
                edge = structures.get_admitted_edge(admitted, e)
                edge_copy = structures.get_admitted_edge(admitted_copy, e)
                self.assertEqual(edge.src, edge_copy.src)
                self.assertEqual(edge.dst & pathselection.PATH_MASK,
                                 edge_copy.dst & pathselection.PATH_MASK)

            # clean up
            structures.destroy_admitted_traffic(admitted)

        pass
Beispiel #11
0
    def __init__(self, degree, n_nodes):
        # initialize kr
        generator = kr_util()
        self.kr = generator.build_kr(n_nodes, degree)

        g_p = graph_util().generate_random_regular_bipartite(n_nodes, degree)
        arbitrary_p = graph_util().generate_random_regular_bipartite(n_nodes, 1)
        
        # create the C versions of the graphs
        self.g_c_structure = graph.create_graph_structure_test(n_nodes)
        self.g_c = graph.create_graph_edges_test(n_nodes)
        self.g_c_copy = graph.create_graph_edges_test(n_nodes)
        for edge in g_p.edges_iter():
            graph.add_edge(self.g_c_structure, self.g_c, edge[0], edge[1])
        graph.copy_edges(self.g_c, self.g_c_copy, n_nodes)
 
        self.arbitrary_c = graph.create_graph_edges_test(n_nodes)
        for edge in arbitrary_p.edges_iter():
            graph.add_edge(self.g_c_structure, self.g_c, edge[0], edge[1])
            graph.set_edge(self.g_c_structure, self.g_c_copy, self.arbitrary_c, edge[0], edge[1])

        # allocate solution
        self.solution = kapoorrizzi.create_matching_set()
    def test_irregular_graph(self):
        """Tests graphs that are not necessarily regular - some number of sources
        and destinations have no edges."""

        generator = graph_util()
        num_experiments = 100
        n_nodes = 256 # network with 8 racks of 32 nodes each
        n_racks = n_nodes / structures.MAX_NODES_PER_RACK

        for i in range(num_experiments):
            # generate admitted traffic
            g_p = generator.generate_random_regular_bipartite(n_nodes, 1)

            # choose a number of edges to remove
            num_edges_to_remove = random.randint(1, 256)
            # remove edges
            for j in range(num_edges_to_remove):
                while (True):
                    # choose an edge index at random
                    index = random.randint(0, n_nodes - 1)
                    edge = g_p.edges(index)
                    if edge != []:
                        edge_tuple = edge[0]
                        g_p.remove_edge(edge_tuple[0], edge_tuple[1])
                        break

            admitted = structures.create_admitted_traffic()
            admitted_copy = structures.create_admitted_traffic()
            for edge in g_p.edges_iter():
                structures.insert_admitted_edge(admitted, edge[0], edge[1] - n_nodes)
                structures.insert_admitted_edge(admitted_copy, edge[0], edge[1] - n_nodes)

            # select paths
            pathselection.select_paths(admitted, n_racks)

            # check that path assignments are valid
            self.assertTrue(pathselection.paths_are_valid(admitted, n_racks))

            # check that src addrs and lower bits of destination addrs are unchanged
            for e in range(admitted.size):
                edge = structures.get_admitted_edge(admitted, e)
                edge_copy = structures.get_admitted_edge(admitted_copy, e)
                self.assertEqual(edge.src, edge_copy.src)
                self.assertEqual(edge.dst & pathselection.PATH_MASK,
                                 edge_copy.dst & pathselection.PATH_MASK)

            # clean up
            structures.destroy_admitted_traffic(admitted)

        pass
    def test_keeps_edge_set(self):
        generator = graph_util()
        for deg in xrange(2, 11, 2):
            for n_side in xrange(2*deg+4,33,7):
                g_p = generator.generate_random_regular_bipartite(n_side, deg)
                
                # Create the graph in C
                g_c_structure = graph.create_graph_structure_test(n_side);
                g_c = graph.create_graph_edges_test(n_side);
                g_c_copy = graph.create_graph_edges_test(n_side)
                for edge in g_p.edges_iter():
                    graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
                graph.copy_edges(g_c, g_c_copy, n_side)
                self.assertEqual(graph.get_max_degree(g_c, n_side), deg)
                self.assertEqual(graph.get_max_degree(g_c_copy, n_side), deg)
 
                # Create the output graphs
                g1_c = graph.create_graph_edges_test(n_side)
                g2_c = graph.create_graph_edges_test(n_side)

                eulersplit.split(g_c_structure, g_c_copy, g1_c, g2_c)

                # Check that the input graph is now empty
                self.assertEqual(graph.get_max_degree(g_c_copy, n_side), 0)
                for node in xrange(2 * n_side):
                    self.assertEqual(graph.get_degree(g_c_copy, node), 0)

                # Check that graphs have the correct degree
                self.assertEqual(graph.get_max_degree(g1_c, n_side), deg / 2)
                self.assertEqual(graph.get_max_degree(g2_c, n_side), deg / 2)

                # Check that vertices have the correct degree
                for node in xrange(2 * n_side):
                    self.assertEqual(graph.get_degree(g1_c, node), deg / 2)
                    self.assertEqual(graph.get_degree(g2_c, node), deg / 2)

                # Check that the combination of the two graphs equals the original graph
                graph.add_edges(g1_c, g2_c, n_side)
                self.assertTrue(graph.are_equal(g_c, g1_c, n_side))
                   
                graph.destroy_graph_structure_test(g_c_structure)
                graph.destroy_graph_edges_test(g_c)
                graph.destroy_graph_edges_test(g_c_copy)
                graph.destroy_graph_edges_test(g1_c)
                graph.destroy_graph_edges_test(g2_c)

        pass
Beispiel #14
0
    def test_keeps_edge_set(self):
        generator = graph_util()
        for deg in xrange(2, 11, 2):
            for n_side in xrange(2 * deg + 4, 33, 7):
                g_p = generator.generate_random_regular_bipartite(n_side, deg)

                # Create the graph in C
                g_c_structure = graph.create_graph_structure_test(n_side)
                g_c = graph.create_graph_edges_test(n_side)
                g_c_copy = graph.create_graph_edges_test(n_side)
                for edge in g_p.edges_iter():
                    graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
                graph.copy_edges(g_c, g_c_copy, n_side)
                self.assertEqual(graph.get_max_degree(g_c, n_side), deg)
                self.assertEqual(graph.get_max_degree(g_c_copy, n_side), deg)

                # Create the output graphs
                g1_c = graph.create_graph_edges_test(n_side)
                g2_c = graph.create_graph_edges_test(n_side)

                eulersplit.split(g_c_structure, g_c_copy, g1_c, g2_c)

                # Check that the input graph is now empty
                self.assertEqual(graph.get_max_degree(g_c_copy, n_side), 0)
                for node in xrange(2 * n_side):
                    self.assertEqual(graph.get_degree(g_c_copy, node), 0)

                # Check that graphs have the correct degree
                self.assertEqual(graph.get_max_degree(g1_c, n_side), deg / 2)
                self.assertEqual(graph.get_max_degree(g2_c, n_side), deg / 2)

                # Check that vertices have the correct degree
                for node in xrange(2 * n_side):
                    self.assertEqual(graph.get_degree(g1_c, node), deg / 2)
                    self.assertEqual(graph.get_degree(g2_c, node), deg / 2)

                # Check that the combination of the two graphs equals the original graph
                graph.add_edges(g1_c, g2_c, n_side)
                self.assertTrue(graph.are_equal(g_c, g1_c, n_side))

                graph.destroy_graph_structure_test(g_c_structure)
                graph.destroy_graph_edges_test(g_c)
                graph.destroy_graph_edges_test(g_c_copy)
                graph.destroy_graph_edges_test(g1_c)
                graph.destroy_graph_edges_test(g2_c)

        pass
    def test_keeps_edge_set(self):
        ES = euler_split()
        generator = graph_util()
        for deg in xrange(2, 11, 2):
            for n_side in xrange(2 * deg + 4, 33, 7):
                g = generator.generate_random_regular_bipartite(n_side, deg)
                g1, g2 = ES.split(g.copy())

                self.assertEquals(g1.nodes(), g.nodes())
                self.assertEquals(g2.nodes(), g.nodes())
                self.assertEqual(len(g.edges()), 2 * len(g1.edges()))
                self.assertEqual(len(g.edges()), 2 * len(g2.edges()))
                self.assertEquals(sorted(g.edges()), sorted(g1.edges() + g2.edges()))
                self.assertEquals([g1.degree(x) for x in g1.nodes()], [deg / 2] * 2 * n_side)
                self.assertEquals([g2.degree(x) for x in g2.nodes()], [deg / 2] * 2 * n_side)

        pass
Beispiel #16
0
    def test_keeps_edge_set(self):
        ES = euler_split()
        generator = graph_util()
        for deg in xrange(2, 11, 2):
            for n_side in xrange(2 * deg + 4, 33, 7):
                g = generator.generate_random_regular_bipartite(n_side, deg)
                g1, g2 = ES.split(g.copy())

                self.assertEquals(g1.nodes(), g.nodes())
                self.assertEquals(g2.nodes(), g.nodes())
                self.assertEqual(len(g.edges()), 2 * len(g1.edges()))
                self.assertEqual(len(g.edges()), 2 * len(g2.edges()))
                self.assertEquals(sorted(g.edges()),
                                  sorted(g1.edges() + g2.edges()))
                self.assertEquals([g1.degree(x) for x in g1.nodes()],
                                  [deg / 2] * 2 * n_side)
                self.assertEquals([g2.degree(x) for x in g2.nodes()],
                                  [deg / 2] * 2 * n_side)

        pass
Beispiel #17
0
    def test_regular_graph(self):
        """Basic test involving graphs that are already regular."""

        generator = graph_util()
        num_experiments = 10
        n_nodes = 256  # network with 8 racks of 32 nodes each
        n_racks = n_nodes / structures.MAX_NODES_PER_RACK

        for i in range(num_experiments):
            # generate admitted traffic
            g_p = generator.generate_random_regular_bipartite(n_nodes, 1)

            admitted = structures.create_admitted_traffic()
            admitted_copy = structures.create_admitted_traffic()
            for edge in g_p.edges_iter():
                structures.insert_admitted_edge(admitted, edge[0],
                                                edge[1] - n_nodes)
                structures.insert_admitted_edge(admitted_copy, edge[0],
                                                edge[1] - n_nodes)

            # select paths
            pathselection.select_paths(admitted, n_racks)

            # check that path assignments are valid
            self.assertTrue(pathselection.paths_are_valid(admitted, n_racks))

            # check that src addrs and lower bits of destination addrs are unchanged
            for e in range(admitted.size):
                edge = structures.get_admitted_edge(admitted, e)
                edge_copy = structures.get_admitted_edge(admitted_copy, e)
                self.assertEqual(edge.src, edge_copy.src)
                self.assertEqual(edge.dst & pathselection.PATH_MASK,
                                 edge_copy.dst & pathselection.PATH_MASK)

            # clean up
            structures.destroy_admitted_traffic(admitted)

        pass
    def test_regular_graph(self):
        """Basic test involving graphs that are already regular."""

        generator = graph_util()
        num_experiments = 10
        n_nodes = 256 # network with 8 racks of 32 nodes each
        n_racks = n_nodes / structures.MAX_NODES_PER_RACK

        for i in range(num_experiments):
            # generate admitted traffic
            g_p = generator.generate_random_regular_bipartite(n_nodes, 1)

            admitted = structures.create_admitted_traffic()
            admitted_copy = structures.create_admitted_traffic()
            for edge in g_p.edges_iter():
                structures.insert_admitted_edge(admitted, edge[0], edge[1] - n_nodes)
                structures.insert_admitted_edge(admitted_copy, edge[0], edge[1] - n_nodes)

            # select paths
            pathselection.select_paths(admitted, n_racks)

            # check that path assignments are valid
            self.assertTrue(pathselection.paths_are_valid(admitted, n_racks))

            # check that src addrs and lower bits of destination addrs are unchanged
            for e in range(admitted.size):
                edge = structures.get_admitted_edge(admitted, e)
                edge_copy = structures.get_admitted_edge(admitted_copy, e)
                self.assertEqual(edge.src, edge_copy.src)
                self.assertEqual(edge.dst & pathselection.PATH_MASK,
                                 edge_copy.dst & pathselection.PATH_MASK)

            # clean up
            structures.destroy_admitted_traffic(admitted)

        pass
Beispiel #19
0
    def test(self):
        degree = 40
        n_nodes = 15

        # initialize kr
        generator = kr_util()
        kr = generator.build_kr(n_nodes, degree, print_debug=True)

        # generate graph and arbitrary matching
        g_p = graph_util().generate_random_regular_bipartite(n_nodes, degree)
        arbitrary_p = graph_util().generate_random_regular_bipartite(
            n_nodes, 1)

        # create the C versions of the graphs, and copies
        g_c_structure = graph.create_graph_structure_test(n_nodes)
        g_c = graph.create_graph_edges_test(n_nodes)
        g_c_copy = graph.create_graph_edges_test(n_nodes)
        for edge in g_p.edges_iter():
            graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
        graph.copy_edges(g_c, g_c_copy, n_nodes)
        self.assertEqual(graph.get_max_degree(g_c, n_nodes), degree)
        self.assertEqual(graph.get_max_degree(g_c_copy, n_nodes), degree)

        arbitrary_c = graph.create_graph_edges_test(n_nodes)
        for edge in arbitrary_p.edges_iter():
            graph.add_edge(g_c_structure, g_c, edge[0], edge[1])
            graph.set_edge(g_c_structure, g_c_copy, arbitrary_c, edge[0],
                           edge[1])
        self.assertEqual(graph.get_max_degree(arbitrary_c, n_nodes), 1)

        # solve
        solution = kapoorrizzi.create_matching_set()
        kapoorrizzi.solve(kr, g_c_structure, g_c_copy, arbitrary_c, solution)

        # check solution

        # check that we have the correct number of matchings
        num_matchings = kapoorrizzi.get_num_matchings(solution)
        self.assertEqual(num_matchings, degree + 1)

        # check that each matching is a perfect matching
        for i in range(num_matchings):
            matching = kapoorrizzi.get_matching(solution, i)
            self.assertTrue(graph.is_perfect_matching(matching, n_nodes))

        # check sum of matchings equals the original graph
        matchings_graph_c = graph.create_graph_edges_test(n_nodes)
        for i in range(num_matchings):
            matching = kapoorrizzi.get_matching(solution, i)
            graph.add_edges(matchings_graph_c, matching, n_nodes)
        self.assertTrue(graph.are_equal(matchings_graph_c, g_c, n_nodes))

        # clean up
        kapoorrizzi.destroy_kr(kr)
        kapoorrizzi.destroy_matching_set(solution)
        graph.destroy_graph_structure_test(g_c_structure)
        graph.destroy_graph_edges_test(g_c)
        graph.destroy_graph_edges_test(g_c_copy)
        graph.destroy_graph_edges_test(arbitrary_c)

        pass