| 5514 | def distance_graph(self, dist): |
| 5515 | r""" |
| 5516 | Returns the graph on the same vertex set as |
| 5517 | the original graph but vertices are adjacent |
| 5518 | in the returned graph if and only if they are |
| 5519 | at a specified distance in the original graph. |
| 5520 | |
| 5521 | INPUT: |
| 5522 | |
| 5523 | - ``dist`` is a nonnegative integer or |
| 5524 | ``Infinity``. The latter describes |
| 5525 | vertex pairs in separate components. |
| 5526 | |
| 5527 | OUTPUT: |
| 5528 | |
| 5529 | The returned value is an undirected graph. Loops |
| 5530 | will only be present in the distance 0 graph. If |
| 5531 | the original graph has a position dictionary specifying |
| 5532 | locations of vertices for plotting, then this information |
| 5533 | is copied over to the distance graph. In some instances |
| 5534 | this layout may not be the best, and might even be confusing |
| 5535 | when edges run on top of each other. |
| 5536 | |
| 5537 | EXAMPLES:: |
| 5538 | |
| 5539 | sage: G = graphs.CompleteGraph(3) |
| 5540 | sage: H = G.cartesian_product(graphs.CompleteGraph(2)) |
| 5541 | sage: K = H.distance_graph(2) |
| 5542 | sage: K.am() |
| 5543 | [0 0 0 1 0 1] |
| 5544 | [0 0 1 0 1 0] |
| 5545 | [0 1 0 0 0 1] |
| 5546 | [1 0 0 0 1 0] |
| 5547 | [0 1 0 1 0 0] |
| 5548 | [1 0 1 0 0 0] |
| 5549 | |
| 5550 | A complete collection of distance graphs will have |
| 5551 | adjacency matrices that sum to the matrix of all ones. :: |
| 5552 | |
| 5553 | sage: P = graphs.PathGraph(20) |
| 5554 | sage: all_ones = sum([P.distance_graph(i).am() for i in range(20)]) |
| 5555 | sage: all_ones == matrix(ZZ, 20, 20, [1]*400) |
| 5556 | True |
| 5557 | |
| 5558 | Four-bit strings differing in one bit is the same as |
| 5559 | four-bit strings differing in three bits. :: |
| 5560 | |
| 5561 | sage: G = graphs.CubeGraph(4) |
| 5562 | sage: H = G.distance_graph(3) |
| 5563 | sage: G.is_isomorphic(H) |
| 5564 | True |
| 5565 | |
| 5566 | An example of using ``Infinity`` as the distance in |
| 5567 | a graph that is not connected. :: |
| 5568 | |
| 5569 | sage: G = graphs.CompleteGraph(3) |
| 5570 | sage: H = G.disjoint_union(graphs.CompleteGraph(2)) |
| 5571 | sage: L = H.distance_graph(Infinity) |
| 5572 | sage: L.am() |
| 5573 | [0 0 0 1 1] |
| 5574 | [0 0 0 1 1] |
| 5575 | [0 0 0 1 1] |
| 5576 | [1 1 1 0 0] |
| 5577 | [1 1 1 0 0] |
| 5578 | |
| 5579 | TESTS: |
| 5580 | |
| 5581 | It is an error to provide a distance that is not an integer type. :: |
| 5582 | |
| 5583 | sage: G = graphs.CompleteGraph(5) |
| 5584 | sage: G.distance_graph('junk') |
| 5585 | Traceback (most recent call last): |
| 5586 | ... |
| 5587 | TypeError: unable to convert x (=junk) to an integer |
| 5588 | |
| 5589 | It is an error to provide a negative distance. :: |
| 5590 | |
| 5591 | sage: G = graphs.CompleteGraph(5) |
| 5592 | sage: G.distance_graph(-3) |
| 5593 | Traceback (most recent call last): |
| 5594 | ... |
| 5595 | ValueError: Distance graph for a negative distance (d=-3) is not defined |
| 5596 | |
| 5597 | AUTHOR: |
| 5598 | |
| 5599 | Rob Beezer, 2009-11-25 |
| 5600 | """ |
| 5601 | from sage.rings.infinity import Infinity |
| 5602 | from copy import copy |
| 5603 | d = dist |
| 5604 | if not(dist == Infinity): |
| 5605 | d = Integer(dist) |
| 5606 | if d < 0: |
| 5607 | raise ValueError('Distance graph for a negative distance (d=%d) is not defined' % d) |
| 5608 | vertices = {} |
| 5609 | for v in self.vertex_iterator(): |
| 5610 | vertices[v] = {} |
| 5611 | positions = copy(self.get_pos()) |
| 5612 | D = Graph(vertices, pos=positions, multiedges=False, loops=True) |
| 5613 | D.name("Distance %s graph of " % str(d) + self.name()) |
| 5614 | for u in self.vertex_iterator(): |
| 5615 | for v in self.vertex_iterator(): |
| 5616 | if self.distance(u,v) == d: |
| 5617 | D.add_edge(u,v) |
| 5618 | return D |
| 5619 | |