| 10588 | def ISR(self,family): |
| 10589 | r""" |
| 10590 | Returns an independent set of representatives. |
| 10591 | |
| 10592 | Given a graph `G` and and a family `F=\{F_i:i\in [1,...,k]\}` of subsets |
| 10593 | of ``g.vertices()``, an ISR ( Independent Set of Reprersentatives ) is an |
| 10594 | assignation of a vertex `v_i\in F_i` to each set `F_i` such that |
| 10595 | `v_i != v_j` if `i<j` ( they are represdentatives ) and the set |
| 10596 | `\cup_{i}v_i` is an independent set in `G`. |
| 10597 | |
| 10598 | It generalizes, for example, graph coloring and graph list coloring. |
| 10599 | |
| 10600 | ( See [AhaBerZiv07]_ for more informations ) |
| 10601 | |
| 10602 | INPUT : |
| 10603 | |
| 10604 | * ``family`` : A list of lists defining the family `F` |
| 10605 | ( actually, a Family of subsets of ``G.vertices()`` ) |
| 10606 | |
| 10607 | OUTPUT : |
| 10608 | |
| 10609 | A list whose `i^{\mbox{th}}` element is the representativeof the `i^{\mbox{th}}` |
| 10610 | element of the ``family`` list. If there is no ISR, ``None`` is returned |
| 10611 | |
| 10612 | EXAMPLE :: |
| 10613 | |
| 10614 | sage: g=graphs.CompleteBipartiteGraph(3,3) |
| 10615 | sage: g.delete_edge(1,4) |
| 10616 | sage: g.ISR([[0,1,2],[3,4,5]]) |
| 10617 | [1, 4] |
| 10618 | |
| 10619 | |
| 10620 | REFERENCE: |
| 10621 | |
| 10622 | .. [AhaBerZiv07] R. Aharoni and E. Berger and R. Ziv |
| 10623 | Independent systems of representatives in weighted graphs |
| 10624 | Combinatorica vol 27, num 3, p253--267 |
| 10625 | 2007 |
| 10626 | |
| 10627 | """ |
| 10628 | |
| 10629 | from sage.numerical.mip import MIP |
| 10630 | p=MIP() |
| 10631 | |
| 10632 | # Boolean variable indicating whether the vertex |
| 10633 | # is the representative of some set |
| 10634 | vertex_taken=p.newvar() |
| 10635 | |
| 10636 | # Boolean variable in two dimension whose first |
| 10637 | # element is a vertex and whose second element |
| 10638 | # is one of the sets given as arguments. |
| 10639 | # When true, indicated that the vertex is the representent |
| 10640 | # of the corresponding set |
| 10641 | |
| 10642 | classss=p.newvar(dim=2) |
| 10643 | |
| 10644 | # Associates to the vertices the classsses |
| 10645 | # to which they belong |
| 10646 | |
| 10647 | lists={} |
| 10648 | for v in self.vertices(): |
| 10649 | lists[v]=[] |
| 10650 | |
| 10651 | for i in range(len(family)): |
| 10652 | for v in family[i]: |
| 10653 | assert v in self, "All the vertices must belong to the graph !" |
| 10654 | |
| 10655 | [lists[v].append(i) for v in family[i]] |
| 10656 | |
| 10657 | # a classss has exactly one representant |
| 10658 | p.addconstraint(sum([classss[v][i] for v in family[i]]),max=1,min=1) |
| 10659 | |
| 10660 | # A vertex represents at most one classss (vertex_taken is binary), and |
| 10661 | # vertex_taken[v]==1 if v is the representative of some classss |
| 10662 | |
| 10663 | [p.addconstraint(sum([classss[v][i] for i in lists[v]])-vertex_taken[v],max=0) for v in self.vertices()] |
| 10664 | |
| 10665 | # Two adjacent vertices can not both be representants of a set |
| 10666 | |
| 10667 | for (u,v) in self.edges(labels=None): |
| 10668 | p.addconstraint(vertex_taken[u]+vertex_taken[v],max=1) |
| 10669 | |
| 10670 | p.setobj(sum([vertex_taken[v] for v in self.vertices()])) |
| 10671 | |
| 10672 | p.setbinary(vertex_taken) |
| 10673 | p.setbinary(classss) |
| 10674 | |
| 10675 | try: |
| 10676 | p.solve() |
| 10677 | except: |
| 10678 | return None |
| 10679 | |
| 10680 | classss=p.get_values(classss) |
| 10681 | |
| 10682 | repr=[] |
| 10683 | for i in range(len(family)): |
| 10684 | for v in family[i]: |
| 10685 | if classss[v][i]==1: |
| 10686 | repr.append(v) |
| 10687 | break |
| 10688 | |
| 10689 | return repr |
| 10690 | |