Ticket #9911: trac_9911.patch

File trac_9911.patch, 5.3 KB (added by ncohen, 10 years ago)
  • sage/graphs/digraph.py

    # HG changeset patch
    # User Nathann Cohen <nathann.cohen@gmail.com>
    # Date 1284497993 -7200
    # Node ID 731510ba72734f597f8f1c190814e904d3b82839
    # Parent  8c722bce2f917caab751122ef48b6057821142de
    trac 9911 - Changing the LP formulation of feedback vertex/arc set to improve the speed
    
    diff -r 8c722bce2f91 -r 731510ba7273 sage/graphs/digraph.py
    a b  
    12261226
    12271227            \mbox{Minimize : }&\sum_{(u,v)\in G} b_{(u,v)}\\
    12281228            \mbox{Such that : }&\\
    1229             &\forall v\in G, \sum_{i\in [0,\dots,n-1]}x_{v,i}=1\\
    1230             &\forall i\in [0,\dots,n-1], \sum_{v\in G}x_{v,i}=1\\
    1231             &\forall v\in G,\sum_{i\in [0,\dots,n-1]} ix_{v,i}=d_v\\
    12321229            &\forall (u,v)\in G, d_u-d_v+nb_{(u,v)}\geq 0\\
     1230            &\forall u\in G, 0\leq d_u\leq |G|\\
    12331231                       
    12341232        An explanation:
    12351233
     
    12391237        that if `(u,v)\in G`, then `u<v`.
    12401238
    12411239        Thus, this linear program is built in order to assign to each vertex
    1242         `v` a unique number `d_v\in [0,\dots,n-1]` such that if there exists
     1240        `v` a number `d_v\in [0,\dots,n-1]` such that if there exists
    12431241        an edge `(u,v)\in G` such that `d_v<d_u`, then the edge `(u,v)` is
    1244         removed (`\Rightarrow x_{(u,v)}=1`).
     1242        removed.
    12451243
    12461244        The number of edges removed is then minimized, which is
    12471245        the objective.
     
    12751273       
    12761274        p=MixedIntegerLinearProgram(maximization=False, solver=solver)
    12771275       
    1278         b=p.new_variable()
    1279         x=p.new_variable(dim=2)
    1280         d=p.new_variable()
     1276        b=p.new_variable(binary = True)
     1277        d=p.new_variable(integer = True)
     1278
    12811279        n=self.order()
    1282         N=range(n)
    12831280
    1284         # First and second constraints
    1285         [p.add_constraint(Sum([x[v][i] for i in N]),min=1,max=1) for v in self]
    1286         [p.add_constraint(Sum([x[v][i] for v in self]),min=1,max=1) for i in N]
    1287        
    1288         # Definition of d_v
    1289         [p.add_constraint(Sum([i*x[v][i] for i in N])-d[v],max=0,min=0) for v in self]
     1281        for (u,v) in self.edges(labels=None):
     1282            p.add_constraint(d[u]-d[v]+n*(b[(u,v)]),min=1)
    12901283
    1291         # The removed vertices cover all the back arcs ( third condition )
    1292         [p.add_constraint(d[u]-d[v]+n*(b[(u,v)]),min=0) for (u,v) in self.edges(labels=None)]
     1284        for v in self:
     1285            p.add_constraint(d[v],min=n)
    12931286
    1294         p.set_binary(b)
    1295         p.set_binary(x)
    12961287
    12971288        p.set_objective(Sum([b[(u,v)] for (u,v) in self.edges(labels=None)]))
    12981289
     
    13491340
    13501341            \mbox{Minimize : }&\sum_{v\in G} b_v\\
    13511342            \mbox{Such that : }&\\
    1352             &\forall v\in G, \sum_{i\in [0,\dots,n-1]}x_{v,i}=1\\
    1353             &\forall i\in [0,\dots,n-1], \sum_{v\in G}x_{v,i}=1\\
    1354             &\forall v\in G,\sum_{i\in [0,\dots,n-1]} ix_{v,i}=d_v\\
    13551343            &\forall (u,v)\in G, d_u-d_v+nb_u+nb_v\geq 0\\
     1344            &\forall u\in G, 0\leq d_u\leq |G|\\
    13561345                       
    13571346        A brief explanation:
    13581347
    13591348        An acyclic digraph can be seen as a poset, and every poset has
    1360         a linear extension. This means that in any acyclic digraph
    1361         the vertices can be ordered with a total order `<` in such a way
    1362         that if `(u,v)\in G`, then `u<v`.
    1363         Thus, this linear program is built in order to assign to each vertex
    1364         `v` an unique number `d_v\in [0,\dots,n-1]` such that if there exists
    1365         an edge `(u,v)\in G` such that `d_v<d_u`, then either `u` is removed
    1366         (`\Rightarrow b_u=1`) or `v` is removed (`\Rightarrow b_v=1`).
    1367         The number of vertices removed is then minimized, which is
    1368         the objective.
     1349        a linear extension. This means that in any acyclic digraph the
     1350        vertices can be ordered with a total order `<` in such a way
     1351        that if `(u,v)\in G`, then `u<v`.  Thus, this linear program
     1352        is built in order to assign to each vertex `v` a number
     1353        `d_v\in [0,\dots,n-1]` such that if there exists an edge
     1354        `(u,v)\in G` then either `d_v<d_u` or one of `u` or `v` is
     1355        removed.  The number of vertices removed is then minimized,
     1356        which is the objective.
    13691357
    13701358        EXAMPLES:
    13711359
     
    13971385       
    13981386        p=MixedIntegerLinearProgram(maximization=False, solver=solver)
    13991387       
    1400         b=p.new_variable()
    1401         x=p.new_variable(dim=2)
    1402         d=p.new_variable()
     1388        b=p.new_variable(binary = True)
     1389        d=p.new_variable(integer = True)
    14031390        n=self.order()
    1404         N=range(n)
    1405 
    1406         # First and second constraints
    1407         [p.add_constraint(Sum([x[v][i] for i in N]),min=1,max=1) for v in self]
    1408         [p.add_constraint(Sum([x[v][i] for v in self]),min=1,max=1) for i in N]
    1409        
    1410         # Definition of d_v
    1411         [p.add_constraint(Sum([i*x[v][i] for i in N])-d[v],max=0,min=0) for v in self]
    14121391
    14131392        # The removed vertices cover all the back arcs ( third condition )
    1414         [p.add_constraint(d[u]-d[v]+n*(b[u]+b[v]),min=0) for (u,v) in self.edges(labels=None)]
    1415 
    1416         p.set_binary(b)
    1417         p.set_binary(x)
     1393        [p.add_constraint(d[u]-d[v]+n*(b[u]+b[v]),min=1) for (u,v) in self.edges(labels=None)]
     1394        [p.add_constraint(d[u],max=n) for u in self]
    14181395
    14191396        p.set_objective(Sum([b[v] for v in self]))
    14201397