# HG changeset patch
# User Robert L. Miller <rlm@rlmiller.org>
# Date 1276901396 25200
# Node ID 49971fc086c87861b671d58ebfe396a5f9bc865d
# Parent 556bb66e4c6dbb92a4ee37c1750d82a5c6298eeb
#9269: Better use of #optional in sage/graphs
diff -r 556bb66e4c6d -r 49971fc086c8 sage/graphs/digraph.py
|
a
|
b
|
|
| 1164 | 1164 | sage: dcycle=DiGraph(cycle) |
| 1165 | 1165 | sage: cycle.size() |
| 1166 | 1166 | 5 |
| 1167 | | sage: dcycle.feedback_edge_set(value_only=True) # optional - requires GLPK or CBC |
| | 1167 | sage: dcycle.feedback_edge_set(value_only=True) # optional - GLPK, CBC |
| 1168 | 1168 | 5.0 |
| 1169 | 1169 | |
| 1170 | 1170 | And in this situation, for any edge `uv` of the first graph, `uv` of `vu` |
| … |
… |
|
| 1172 | 1172 | |
| 1173 | 1173 | sage: g = graphs.RandomGNP(5,.3) |
| 1174 | 1174 | sage: dg = DiGraph(g) |
| 1175 | | sage: feedback = dg.feedback_edge_set() # optional - requires GLPK or CBC |
| | 1175 | sage: feedback = dg.feedback_edge_set() # optional - GLPK, CBC |
| 1176 | 1176 | sage: (u,v,l) = g.edge_iterator().next() |
| 1177 | | sage: (u,v) in feedback or (v,u) in feedback # optional - requires GLPK or CBC |
| | 1177 | sage: (u,v) in feedback or (v,u) in feedback # optional - GLPK, CBC |
| 1178 | 1178 | True |
| 1179 | 1179 | """ |
| 1180 | 1180 | |
| … |
… |
|
| 1284 | 1284 | |
| 1285 | 1285 | sage: cycle=graphs.CycleGraph(5) |
| 1286 | 1286 | sage: dcycle=DiGraph(cycle) |
| 1287 | | sage: cycle.vertex_cover(value_only=True) # optional - requires GLPK or CBC |
| | 1287 | sage: cycle.vertex_cover(value_only=True) # optional - GLPK, CBC |
| 1288 | 1288 | 3 |
| 1289 | | sage: feedback = dcycle.feedback_vertex_set() # optional - requires GLPK or CBC |
| 1290 | | sage: feedback.cardinality() # optional - requires GLPK or CBC |
| | 1289 | sage: feedback = dcycle.feedback_vertex_set() # optional - GLPK, CBC |
| | 1290 | sage: feedback.cardinality() # optional - GLPK, CBC |
| 1291 | 1291 | 3 |
| 1292 | 1292 | sage: (u,v,l) = cycle.edge_iterator().next() |
| 1293 | | sage: u in feedback or v in feedback # optional - requires GLPK or CBC |
| | 1293 | sage: u in feedback or v in feedback # optional - GLPK, CBC |
| 1294 | 1294 | True |
| 1295 | 1295 | |
| 1296 | 1296 | For a circuit, the minimum feedback arc set is clearly `1`:: |
| 1297 | 1297 | |
| 1298 | 1298 | sage: circuit = digraphs.Circuit(5) |
| 1299 | | sage: circuit.feedback_vertex_set(value_only=True) == 1 # optional - requires GLPK or CBC |
| | 1299 | sage: circuit.feedback_vertex_set(value_only=True) == 1 # optional - GLPK, CBC |
| 1300 | 1300 | True |
| 1301 | 1301 | """ |
| 1302 | 1302 | |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/graphs/generic_graph.py
|
a
|
b
|
|
| 2066 | 2066 | Given a complete bipartite graph `K_{n,m}`, the maximum out-degree |
| 2067 | 2067 | of an optimal orientation is `\left\lceil \frac {nm} {n+m}\right\rceil`:: |
| 2068 | 2068 | |
| 2069 | | sage: g = graphs.CompleteBipartiteGraph(3,4) |
| 2070 | | sage: o = g.minimum_outdegree_orientation() # optional - requires GLPK or CBC |
| 2071 | | sage: max(o.out_degree()) == ceil((4*3)/(3+4)) # optional - requires GLPK or CBC |
| | 2069 | sage: g = graphs.CompleteBipartiteGraph(3,4) # optional - GLPK, CBC |
| | 2070 | sage: o = g.minimum_outdegree_orientation() # optional - GLPK, CBC |
| | 2071 | sage: max(o.out_degree()) == ceil((4*3)/(3+4)) # optional - GLPK, CBC |
| 2072 | 2072 | True |
| 2073 | 2073 | |
| 2074 | 2074 | REFERENCES: |
| … |
… |
|
| 3139 | 3139 | A basic application in the Pappus graph:: |
| 3140 | 3140 | |
| 3141 | 3141 | sage: g = graphs.PappusGraph() |
| 3142 | | sage: g.edge_cut(1, 2, value_only=True) # optional - requires GLPK or COIN-OR/CBC |
| | 3142 | sage: g.edge_cut(1, 2, value_only=True) # optional - GLPK, CBC |
| 3143 | 3143 | 3.0 |
| 3144 | 3144 | |
| 3145 | 3145 | If the graph is a path with randomly weighted edges:: |
| … |
… |
|
| 3151 | 3151 | The edge cut between the two ends is the edge of minimum weight:: |
| 3152 | 3152 | |
| 3153 | 3153 | sage: minimum = min([l for u,v,l in g.edge_iterator()]) |
| 3154 | | sage: abs(minimum - g.edge_cut(0, 14, use_edge_labels=True)) < 10**(-5) # optional - requires GLPK or COIN-OR/CBC or CPLEX |
| 3155 | | True |
| 3156 | | sage: [value,[[u,v]]] = g.edge_cut(0, 14, use_edge_labels=True, value_only=False) # optional - requires GLPK or COIN-OR/CBC |
| 3157 | | sage: g.edge_label(u, v) == minimum # optional - requires GLPK or COIN-OR/CBC |
| | 3154 | sage: abs(minimum - g.edge_cut(0, 14, use_edge_labels=True)) < 10**(-5) # optional - GLPK, CBC |
| | 3155 | True |
| | 3156 | sage: [value,[[u,v]]] = g.edge_cut(0, 14, use_edge_labels=True, value_only=False) # optional - GLPK, CBC |
| | 3157 | sage: g.edge_label(u, v) == minimum # optional - GLPK, CBC |
| 3158 | 3158 | True |
| 3159 | 3159 | |
| 3160 | 3160 | The two sides of the edge cut are obviously shorter paths:: |
| 3161 | 3161 | |
| 3162 | | sage: value,edges,[set1,set2] = g.edge_cut(0, 14, use_edge_labels=True, vertices=True) # optional - requires GLPK or COIN-OR/CBC |
| 3163 | | sage: g.subgraph(set1).is_isomorphic(graphs.PathGraph(len(set1))) # optional - requires GLPK or COIN-OR/CBC |
| 3164 | | True |
| 3165 | | sage: g.subgraph(set2).is_isomorphic(graphs.PathGraph(len(set2))) # optional - requires GLPK or COIN-OR/CBC |
| 3166 | | True |
| 3167 | | sage: len(set1) + len(set2) == g.order() # optional - requires GLPK or COIN-OR/CBC |
| | 3162 | sage: value,edges,[set1,set2] = g.edge_cut(0, 14, use_edge_labels=True, vertices=True) # optional - GLPK, CBC |
| | 3163 | sage: g.subgraph(set1).is_isomorphic(graphs.PathGraph(len(set1))) # optional - GLPK, CBC |
| | 3164 | True |
| | 3165 | sage: g.subgraph(set2).is_isomorphic(graphs.PathGraph(len(set2))) # optional - GLPK, CBC |
| | 3166 | True |
| | 3167 | sage: len(set1) + len(set2) == g.order() # optional - GLPK, CBC |
| 3168 | 3168 | True |
| 3169 | 3169 | """ |
| 3170 | 3170 | from sage.numerical.mip import MixedIntegerLinearProgram |
| … |
… |
|
| 3272 | 3272 | A basic application in the Pappus graph:: |
| 3273 | 3273 | |
| 3274 | 3274 | sage: g = graphs.PappusGraph() |
| 3275 | | sage: g.vertex_cut(1, 16, value_only=True) # optional - requires GLPK or COIN-OR/CBC |
| | 3275 | sage: g.vertex_cut(1, 16, value_only=True) # optional - GLPK, CBC |
| 3276 | 3276 | 3.0 |
| 3277 | 3277 | |
| 3278 | 3278 | In the bipartite complete graph `K_{2,8}`, a cut between the two |
| 3279 | 3279 | vertices in the size `2` part consists of the other `8` vertices:: |
| 3280 | 3280 | |
| 3281 | 3281 | sage: g = graphs.CompleteBipartiteGraph(2, 8) |
| 3282 | | sage: [value, vertices] = g.vertex_cut(0, 1, value_only=False) # optional - requires GLPK or COIN-OR/CBC |
| 3283 | | sage: print value # optional - requires GLPK or COIN-OR/CBC |
| | 3282 | sage: [value, vertices] = g.vertex_cut(0, 1, value_only=False) # optional - GLPK, CBC |
| | 3283 | sage: print value # optional - GLPK, CBC |
| 3284 | 3284 | 8.0 |
| 3285 | | sage: vertices == range(2,10) # optional - requires GLPK or COIN-OR/CBC |
| | 3285 | sage: vertices == range(2,10) # optional - GLPK, CBC |
| 3286 | 3286 | True |
| 3287 | 3287 | |
| 3288 | 3288 | Clearly, in this case the two sides of the cut are singletons :: |
| 3289 | 3289 | |
| 3290 | | sage: [value, vertices, [set1, set2]] = g.vertex_cut(0,1, vertices=True) # optional - requires GLPK or COIN-OR/CBC |
| 3291 | | sage: len(set1) == 1 # optional - requires GLPK or COIN-OR/CBC |
| 3292 | | True |
| 3293 | | sage: len(set2) == 1 # optional - requires GLPK or COIN-OR/CBC |
| | 3290 | sage: [value, vertices, [set1, set2]] = g.vertex_cut(0,1, vertices=True) # optional - GLPK, CBC |
| | 3291 | sage: len(set1) == 1 # optional - GLPK, CBC |
| | 3292 | True |
| | 3293 | sage: len(set2) == 1 # optional - GLPK, CBC |
| 3294 | 3294 | True |
| 3295 | 3295 | """ |
| 3296 | 3296 | from sage.numerical.mip import MixedIntegerLinearProgram |
| … |
… |
|
| 3420 | 3420 | The two algorithms should return the same result:: |
| 3421 | 3421 | |
| 3422 | 3422 | sage: g = graphs.RandomGNP(10,.5) |
| 3423 | | sage: vc1 = g.vertex_cover(algorithm="MILP") # optional requires GLPK or CBC |
| 3424 | | sage: vc2 = g.vertex_cover(algorithm="Cliquer") # optional requires GLPK or CBC |
| 3425 | | sage: len(vc1) == len(vc2) # optional requires GLPK or CBC |
| | 3423 | sage: vc1 = g.vertex_cover(algorithm="MILP") # optional - GLPK, CBC |
| | 3424 | sage: vc2 = g.vertex_cover(algorithm="Cliquer") # optional - GLPK, CBC |
| | 3425 | sage: len(vc1) == len(vc2) # optional - GLPK, CBC |
| 3426 | 3426 | True |
| 3427 | 3427 | """ |
| 3428 | 3428 | if algorithm == "Cliquer": |
| … |
… |
|
| 3650 | 3650 | The Heawood graph is known to be hamiltonian:: |
| 3651 | 3651 | |
| 3652 | 3652 | sage: g = graphs.HeawoodGraph() |
| 3653 | | sage: tsp = g.traveling_salesman_problem() # optional - requires GLPK, CBC, or CPLEX |
| 3654 | | sage: tsp # optional - requires GLPK, CBC, or CPLEX |
| | 3653 | sage: tsp = g.traveling_salesman_problem() # optional - GLPK, CBC |
| | 3654 | sage: tsp # optional - GLPK, CBC |
| 3655 | 3655 | TSP from Heawood graph: Graph on 14 vertices |
| 3656 | 3656 | |
| 3657 | 3657 | The solution to the TSP has to be connected :: |
| 3658 | 3658 | |
| 3659 | | sage: tsp.is_connected() # optional - requires GLPK, CBC, or CPLEX |
| | 3659 | sage: tsp.is_connected() # optional - GLPK, CBC |
| 3660 | 3660 | True |
| 3661 | 3661 | |
| 3662 | 3662 | It must also be a `2`-regular graph:: |
| 3663 | 3663 | |
| 3664 | | sage: tsp.is_regular(k=2) # optional - requires GLPK, CBC, or CPLEX |
| | 3664 | sage: tsp.is_regular(k=2) # optional - GLPK, CBC |
| 3665 | 3665 | True |
| 3666 | 3666 | |
| 3667 | 3667 | And obviously it is a subgraph of the Heawood graph:: |
| 3668 | 3668 | |
| 3669 | | sage: all([ e in g.edges() for e in tsp.edges()]) # optional - requires GLPK, CBC, or CPLEX |
| | 3669 | sage: all([ e in g.edges() for e in tsp.edges()]) # optional - GLPK, CBC |
| 3670 | 3670 | True |
| 3671 | 3671 | |
| 3672 | 3672 | On the other hand, the Petersen Graph is known not to |
| 3673 | 3673 | be hamiltonian:: |
| 3674 | 3674 | |
| 3675 | | sage: g = graphs.PetersenGraph() # optional - requires GLPK, CBC, or CPLEX |
| 3676 | | sage: tsp = g.traveling_salesman_problem() # optional - requires GLPK, CBC, or CPLEX |
| | 3675 | sage: g = graphs.PetersenGraph() # optional - GLPK, CBC |
| | 3676 | sage: tsp = g.traveling_salesman_problem() # optional - GLPK, CBC |
| 3677 | 3677 | Traceback (most recent call last): |
| 3678 | 3678 | ... |
| 3679 | 3679 | ValueError: The given graph is not hamiltonian |
| … |
… |
|
| 3695 | 3695 | ... g.add_edge(u,v) |
| 3696 | 3696 | ... g.set_edge_label(u,v,2) |
| 3697 | 3697 | |
| 3698 | | sage: tsp = g.traveling_salesman_problem(weighted = True) # optional - requires GLPK, CBC, or CPLEX |
| 3699 | | sage: sum( tsp.edge_labels() ) < 2*10 # optional - requires GLPK, CBC, or CPLEX |
| | 3698 | sage: tsp = g.traveling_salesman_problem(weighted = True) # optional - GLPK, CBC |
| | 3699 | sage: sum( tsp.edge_labels() ) < 2*10 # optional - GLPK, CBC |
| 3700 | 3700 | True |
| 3701 | 3701 | |
| 3702 | 3702 | If we pick `1/2` instead of `2` as a cost for these new edges, |
| … |
… |
|
| 3705 | 3705 | sage: for u,v in cycle.edges(labels = None): |
| 3706 | 3706 | ... g.set_edge_label(u,v,1/2) |
| 3707 | 3707 | |
| 3708 | | sage: tsp = g.traveling_salesman_problem(weighted = True) # optional - requires GLPK, CBC, or CPLEX |
| 3709 | | sage: sum( tsp.edge_labels() ) == (1/2)*10 # optional - requires GLPK, CBC, or CPLEX |
| | 3708 | sage: tsp = g.traveling_salesman_problem(weighted = True) # optional - GLPK, CBC |
| | 3709 | sage: sum( tsp.edge_labels() ) == (1/2)*10 # optional - GLPK, CBC |
| 3710 | 3710 | True |
| 3711 | 3711 | |
| 3712 | 3712 | """ |
| … |
… |
|
| 3865 | 3865 | The Heawood Graph is known to be hamiltonian :: |
| 3866 | 3866 | |
| 3867 | 3867 | sage: g = graphs.HeawoodGraph() |
| 3868 | | sage: g.hamiltonian_cycle() # optional - requires GLPK, CBC, or CPLEX |
| | 3868 | sage: g.hamiltonian_cycle() # optional - GLPK, CBC |
| 3869 | 3869 | TSP from Heawood graph: Graph on 14 vertices |
| 3870 | 3870 | |
| 3871 | 3871 | The Petergraph, though, is not :: |
| 3872 | 3872 | |
| 3873 | 3873 | sage: g = graphs.PetersenGraph() |
| 3874 | | sage: g.hamiltonian_cycle() # optional - requires GLPK, CBC, or CPLEX |
| | 3874 | sage: g.hamiltonian_cycle() # optional - GLPK, CBC |
| 3875 | 3875 | Traceback (most recent call last): |
| 3876 | 3876 | ... |
| 3877 | 3877 | ValueError: The given graph is not hamiltonian |
| … |
… |
|
| 3967 | 3967 | sage: g.add_edges([('s',i) for i in range(4)]) |
| 3968 | 3968 | sage: g.add_edges([(i,4+j) for i in range(4) for j in range(4)]) |
| 3969 | 3969 | sage: g.add_edges([(4+i,'t') for i in range(4)]) |
| 3970 | | sage: [cardinal, flow_graph] = g.flow('s','t',integer=True,value_only=False) # optional - requires GLPK or CBC |
| 3971 | | sage: flow_graph.delete_vertices(['s','t']) # optional - requires GLPK or CBC |
| 3972 | | sage: len(flow_graph.edges(labels=None)) # optional - requires GLPK or CBC |
| | 3970 | sage: [cardinal, flow_graph] = g.flow('s','t',integer=True,value_only=False) # optional - GLPK, CBC |
| | 3971 | sage: flow_graph.delete_vertices(['s','t']) # optional - GLPK, CBC |
| | 3972 | sage: len(flow_graph.edges(labels=None)) # optional - GLPK, CBC |
| 3973 | 3973 | 4 |
| 3974 | 3974 | |
| 3975 | 3975 | """ |
| … |
… |
|
| 4097 | 4097 | In a complete bipartite graph :: |
| 4098 | 4098 | |
| 4099 | 4099 | sage: g = graphs.CompleteBipartiteGraph(2,3) |
| 4100 | | sage: g.edge_disjoint_paths(0,1) # optional - requires GLPK or CBC |
| | 4100 | sage: g.edge_disjoint_paths(0,1) # optional - GLPK, CBC |
| 4101 | 4101 | [[0, 2, 1], [0, 3, 1], [0, 4, 1]] |
| 4102 | 4102 | """ |
| 4103 | 4103 | |
| … |
… |
|
| 4137 | 4137 | In a complete bipartite graph :: |
| 4138 | 4138 | |
| 4139 | 4139 | sage: g = graphs.CompleteBipartiteGraph(2,3) |
| 4140 | | sage: g.vertex_disjoint_paths(0,1) # optional - requires GLPK or CBC |
| | 4140 | sage: g.vertex_disjoint_paths(0,1) # optional - GLPK, CBC |
| 4141 | 4141 | [[0, 2, 1], [0, 3, 1], [0, 4, 1]] |
| 4142 | 4142 | """ |
| 4143 | 4143 | |
| … |
… |
|
| 4223 | 4223 | Same test with the Linear Program formulation:: |
| 4224 | 4224 | |
| 4225 | 4225 | sage: g = graphs.PappusGraph() |
| 4226 | | sage: g.matching(algorithm="LP", value_only=True) #optional - requires GLPK CBC or CPLEX |
| | 4226 | sage: g.matching(algorithm="LP", value_only=True) # optional - GLPK, CBC |
| 4227 | 4227 | 9.0 |
| 4228 | 4228 | |
| 4229 | 4229 | TESTS: |
| … |
… |
|
| 6270 | 6270 | degree:: |
| 6271 | 6271 | |
| 6272 | 6272 | sage: g = graphs.RandomGNP(20,.3) |
| 6273 | | sage: mad_g = g.maximum_average_degree() # optional - requires GLPK or CBC |
| 6274 | | sage: g.average_degree() <= mad_g # optional - requires GLPK or CBC |
| | 6273 | sage: mad_g = g.maximum_average_degree() # optional - GLPK, CBC |
| | 6274 | sage: g.average_degree() <= mad_g # optional - GLPK, CBC |
| 6275 | 6275 | True |
| 6276 | 6276 | |
| 6277 | 6277 | Unlike the average degree, the `Mad` of the disjoint |
| … |
… |
|
| 6279 | 6279 | graphs:: |
| 6280 | 6280 | |
| 6281 | 6281 | sage: h = graphs.RandomGNP(20,.3) |
| 6282 | | sage: mad_h = h.maximum_average_degree() # optional - requires GLPK or CBC |
| 6283 | | sage: (g+h).maximum_average_degree() == max(mad_g, mad_h) # optional - requires GLPK or CBC |
| | 6282 | sage: mad_h = h.maximum_average_degree() # optional - GLPK, CBC |
| | 6283 | sage: (g+h).maximum_average_degree() == max(mad_g, mad_h) # optional - GLPK, CBC |
| 6284 | 6284 | True |
| 6285 | 6285 | |
| 6286 | 6286 | The subgraph of a regular graph realizing the maximum |
| 6287 | 6287 | average degree is always the whole graph :: |
| 6288 | 6288 | |
| 6289 | 6289 | sage: g = graphs.CompleteGraph(5) |
| 6290 | | sage: mad_g = g.maximum_average_degree(value_only=False) # optional - requires GLPK or CBC |
| 6291 | | sage: g.is_isomorphic(mad_g) # optional - requires GLPK or CBC |
| | 6290 | sage: mad_g = g.maximum_average_degree(value_only=False) # optional - GLPK, CBC |
| | 6291 | sage: g.is_isomorphic(mad_g) # optional - GLPK, CBC |
| 6292 | 6292 | True |
| 6293 | 6293 | |
| 6294 | 6294 | This also works for complete bipartite graphs :: |
| 6295 | 6295 | |
| 6296 | | sage: g = graphs.CompleteBipartiteGraph(3,4) # optional - requires GLPK or CBC |
| 6297 | | sage: mad_g = g.maximum_average_degree(value_only=False) # optional - requires GLPK or CBC |
| 6298 | | sage: g.is_isomorphic(mad_g) # optional - requires GLPK or CBC |
| | 6296 | sage: g = graphs.CompleteBipartiteGraph(3,4) # optional - GLPK, CBC |
| | 6297 | sage: mad_g = g.maximum_average_degree(value_only=False) # optional - GLPK, CBC |
| | 6298 | sage: g.is_isomorphic(mad_g) # optional - GLPK, CBC |
| 6299 | 6299 | True |
| 6300 | 6300 | """ |
| 6301 | 6301 | |
| … |
… |
|
| 11965 | 11965 | The Heawood Graph is known to be hamiltonian :: |
| 11966 | 11966 | |
| 11967 | 11967 | sage: g = graphs.HeawoodGraph() |
| 11968 | | sage: g.is_hamiltonian() # optional - requires GLPK, CBC, or CPLEX |
| | 11968 | sage: g.is_hamiltonian() # optional - GLPK, CBC |
| 11969 | 11969 | True |
| 11970 | 11970 | |
| 11971 | 11971 | The Petergraph, though, is not :: |
| 11972 | 11972 | |
| 11973 | 11973 | sage: g = graphs.PetersenGraph() |
| 11974 | | sage: g.is_hamiltonian() # optional - requires GLPK, CBC, or CPLEX |
| | 11974 | sage: g.is_hamiltonian() # optional - GLPK, CBC |
| 11975 | 11975 | False |
| 11976 | 11976 | |
| 11977 | 11977 | """ |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/graphs/graph.py
|
a
|
b
|
|
| 1445 | 1445 | |
| 1446 | 1446 | sage: g = graphs.CycleGraph(6) |
| 1447 | 1447 | sage: bounds = lambda x: [1,1] |
| 1448 | | sage: m = g.degree_constrained_subgraph(bounds=bounds) # optional - requires GLPK or CBC or CPLEX |
| 1449 | | sage: m.size() # optional - requires GLPK or CBC or CPLEX |
| | 1448 | sage: m = g.degree_constrained_subgraph(bounds=bounds) # optional - GLPK, CBC |
| | 1449 | sage: m.size() # optional - GLPK, CBC |
| 1450 | 1450 | 3 |
| 1451 | 1451 | """ |
| 1452 | 1452 | |
| … |
… |
|
| 1724 | 1724 | sage: G = Graph({0: [1, 2, 3], 1: [2]}) |
| 1725 | 1725 | sage: G.chromatic_number(algorithm="DLX") |
| 1726 | 1726 | 3 |
| 1727 | | sage: G.chromatic_number(algorithm="MILP") # optional - requires GLPK or CBC |
| | 1727 | sage: G.chromatic_number(algorithm="MILP") # optional - GLPK, CBC |
| 1728 | 1728 | 3 |
| 1729 | 1729 | sage: G.chromatic_number(algorithm="CP") |
| 1730 | 1730 | 3 |
| … |
… |
|
| 1783 | 1783 | EXAMPLES:: |
| 1784 | 1784 | |
| 1785 | 1785 | sage: G = Graph("Fooba") |
| 1786 | | sage: P = G.coloring(algorithm="MILP"); P # optional - requires GLPK or CBC |
| | 1786 | sage: P = G.coloring(algorithm="MILP"); P # optional - GLPK, CBC |
| 1787 | 1787 | [[2, 1, 3], [0, 6, 5], [4]] |
| 1788 | 1788 | sage: P = G.coloring(algorithm="DLX"); P |
| 1789 | 1789 | [[1, 2, 3], [0, 5, 6], [4]] |
| 1790 | 1790 | sage: G.plot(partition=P) |
| 1791 | | sage: H = G.coloring(hex_colors=True, algorithm="MILP") # optional - requires GLPK or CBC |
| 1792 | | sage: for c in sorted(H.keys()): # optional - requires GLPK or CBC |
| 1793 | | ... print c, H[c] # optional - requires GLPK or CBC |
| | 1791 | sage: H = G.coloring(hex_colors=True, algorithm="MILP") # optional - GLPK, CBC |
| | 1792 | sage: for c in sorted(H.keys()): # optional - GLPK, CBC |
| | 1793 | ... print c, H[c] # optional - GLPK, CBC |
| 1794 | 1794 | #0000ff [4] |
| 1795 | 1795 | #00ff00 [0, 6, 5] |
| 1796 | 1796 | #ff0000 [2, 1, 3] |
| … |
… |
|
| 1860 | 1860 | |
| 1861 | 1861 | sage: g = graphs.CompleteBipartiteGraph(3,3) |
| 1862 | 1862 | sage: g.delete_edge(1,4) |
| 1863 | | sage: g.independent_set_of_representatives([[0,1,2],[3,4,5]]) # optional - requires GLPK or CBC |
| | 1863 | sage: g.independent_set_of_representatives([[0,1,2],[3,4,5]]) # optional - GLPK, CBC |
| 1864 | 1864 | [1, 4] |
| 1865 | 1865 | |
| 1866 | 1866 | The Petersen Graph is 3-colorable, which can be expressed as an |
| … |
… |
|
| 1873 | 1873 | sage: g = 3 * graphs.PetersenGraph() |
| 1874 | 1874 | sage: n = g.order()/3 |
| 1875 | 1875 | sage: f = [[i,i+n,i+2*n] for i in xrange(n)] |
| 1876 | | sage: isr = g.independent_set_of_representatives(f) # optional - requires GLPK or CBC |
| 1877 | | sage: c = [floor(i/n) for i in isr] # optional - requires GLPK or CBC |
| 1878 | | sage: color_classes = [[],[],[]] # optional - requires GLPK or CBC |
| 1879 | | sage: for v,i in enumerate(c): # optional - requires GLPK or CBC |
| 1880 | | ... color_classes[i].append(v) # optional - requires GLPK or CBC |
| 1881 | | sage: for classs in color_classes: # optional - requires GLPK or CBC |
| 1882 | | ... g.subgraph(classs).size() == 0 # optional - requires GLPK or CBC |
| | 1876 | sage: isr = g.independent_set_of_representatives(f) # optional - GLPK, CBC |
| | 1877 | sage: c = [floor(i/n) for i in isr] # optional - GLPK, CBC |
| | 1878 | sage: color_classes = [[],[],[]] # optional - GLPK, CBC |
| | 1879 | sage: for v,i in enumerate(c): # optional - GLPK, CBC |
| | 1880 | ... color_classes[i].append(v) # optional - GLPK, CBC |
| | 1881 | sage: for classs in color_classes: # optional - GLPK, CBC |
| | 1882 | ... g.subgraph(classs).size() == 0 # optional - GLPK, CBC |
| 1883 | 1883 | True |
| 1884 | 1884 | True |
| 1885 | 1885 | True |
| … |
… |
|
| 2004 | 2004 | |
| 2005 | 2005 | sage: g = graphs.GridGraph([4,4]) |
| 2006 | 2006 | sage: h = graphs.CompleteGraph(4) |
| 2007 | | sage: L = g.minor(h) # optional - requires GLPK, CPLEX or CBC |
| 2008 | | sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) # optional - requires GLPK, CPLEX or CBC |
| 2009 | | sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] # optional - requires GLPK, CPLEX or CBC |
| 2010 | | sage: gg.is_isomorphic(h) # optional - requires GLPK, CPLEX or CBC |
| | 2007 | sage: L = g.minor(h) # optional - GLPK, CBC |
| | 2008 | sage: gg = g.subgraph(flatten(L.values(), max_level = 1)) # optional - GLPK, CBC |
| | 2009 | sage: _ = [gg.merge_vertices(l) for l in L.values() if len(l)>1] # optional - GLPK, CBC |
| | 2010 | sage: gg.is_isomorphic(h) # optional - GLPK, CBC |
| 2011 | 2011 | True |
| 2012 | 2012 | |
| 2013 | 2013 | We can also try to prove this way that the Petersen graph |
| 2014 | 2014 | is not planar, as it has a `K_5` minor:: |
| 2015 | 2015 | |
| 2016 | 2016 | sage: g = graphs.PetersenGraph() |
| 2017 | | sage: K5_minor = g.minor(graphs.CompleteGraph(5)) # optional long - requires GLPK, CPLEX or CBC |
| | 2017 | sage: K5_minor = g.minor(graphs.CompleteGraph(5)) # long, optional - GLPK, CBC |
| 2018 | 2018 | |
| 2019 | 2019 | And even a `K_{3,3}` minor:: |
| 2020 | 2020 | |
| 2021 | | sage: K33_minor = g.minor(graphs.CompleteBipartiteGraph(3,3)) # optional long - requires GLPK, CPLEX or CBC |
| | 2021 | sage: K33_minor = g.minor(graphs.CompleteBipartiteGraph(3,3)) # long, optional - GLPK, CBC |
| 2022 | 2022 | |
| 2023 | 2023 | (It is much faster to use the linear-time test of |
| 2024 | 2024 | planarity in this situation, though.) |
| … |
… |
|
| 2030 | 2030 | sage: g = g.subgraph(edges = g.min_spanning_tree()) |
| 2031 | 2031 | sage: g.is_tree() |
| 2032 | 2032 | True |
| 2033 | | sage: L = g.minor(graphs.CompleteGraph(3)) # optional - requires GLPK, CPLEX or CBC |
| | 2033 | sage: L = g.minor(graphs.CompleteGraph(3)) # optional - GLPK, CBC |
| 2034 | 2034 | Traceback (most recent call last): |
| 2035 | 2035 | ... |
| 2036 | 2036 | ValueError: This graph has no minor isomorphic to H ! |
| … |
… |
|
| 2942 | 2942 | example is only present to have a doctest coverage of 100%. |
| 2943 | 2943 | |
| 2944 | 2944 | sage: g = graphs.PetersenGraph() |
| 2945 | | sage: t = g._gomory_hu_tree() # optional - requires GLPK or CBC |
| | 2945 | sage: t = g._gomory_hu_tree() # optional - GLPK, CBC |
| 2946 | 2946 | """ |
| 2947 | 2947 | from sage.sets.set import Set |
| 2948 | 2948 | |
| … |
… |
|
| 3061 | 3061 | Taking the Petersen graph:: |
| 3062 | 3062 | |
| 3063 | 3063 | sage: g = graphs.PetersenGraph() |
| 3064 | | sage: t = g.gomory_hu_tree() # optional - requires GLPK or CBC |
| | 3064 | sage: t = g.gomory_hu_tree() # optional - GLPK, CBC |
| 3065 | 3065 | |
| 3066 | 3066 | Obviously, this graph is a tree:: |
| 3067 | 3067 | |
| 3068 | | sage: t.is_tree() # optional - requires GLPK or CBC |
| | 3068 | sage: t.is_tree() # optional - GLPK, CBC |
| 3069 | 3069 | True |
| 3070 | 3070 | |
| 3071 | 3071 | Note that if the original graph is not connected, then the |
| 3072 | 3072 | Gomory-Hu tree is in fact a forest:: |
| 3073 | 3073 | |
| 3074 | | sage: (2*g).gomory_hu_tree().is_forest() # optional - requires GLPK or CBC |
| | 3074 | sage: (2*g).gomory_hu_tree().is_forest() # optional - GLPK, CBC |
| 3075 | 3075 | True |
| 3076 | | sage: (2*g).gomory_hu_tree().is_connected() # optional - requires GLPK or CBC |
| | 3076 | sage: (2*g).gomory_hu_tree().is_connected() # optional - GLPK, CBC |
| 3077 | 3077 | False |
| 3078 | 3078 | |
| 3079 | 3079 | On the other hand, such a tree has lost nothing of the initial |
| 3080 | 3080 | graph connectedness:: |
| 3081 | 3081 | |
| 3082 | | sage: all([ t.flow(u,v) == g.flow(u,v) for u,v in Subsets( g.vertices(), 2 ) ]) # optional - requires GLPK or CBC |
| | 3082 | sage: all([ t.flow(u,v) == g.flow(u,v) for u,v in Subsets( g.vertices(), 2 ) ]) # optional - GLPK, CBC |
| 3083 | 3083 | True |
| 3084 | 3084 | |
| 3085 | 3085 | Just to make sure, we can check that the same is true for two vertices |
| 3086 | 3086 | in a random graph:: |
| 3087 | 3087 | |
| 3088 | 3088 | sage: g = graphs.RandomGNP(20,.3) |
| 3089 | | sage: t = g.gomory_hu_tree() # optional - requires GLPK or CBC |
| 3090 | | sage: g.flow(0,1) == t.flow(0,1) # optional - requires GLPK or CBC |
| | 3089 | sage: t = g.gomory_hu_tree() # optional - GLPK, CBC |
| | 3090 | sage: g.flow(0,1) == t.flow(0,1) # optional - GLPK, CBC |
| 3091 | 3091 | True |
| 3092 | 3092 | |
| 3093 | 3093 | And also the min cut:: |
| 3094 | 3094 | |
| 3095 | | sage: g.edge_connectivity() == min(t.edge_labels()) # optional - requires GLPK or CBC |
| | 3095 | sage: g.edge_connectivity() == min(t.edge_labels()) # optional - GLPK, CBC |
| 3096 | 3096 | True |
| 3097 | 3097 | """ |
| 3098 | 3098 | return self._gomory_hu_tree() |
| … |
… |
|
| 3123 | 3123 | be edge-partitionned into `2`-regular graphs:: |
| 3124 | 3124 | |
| 3125 | 3125 | sage: g = graphs.CompleteGraph(7) |
| 3126 | | sage: classes = g.two_factor_petersen() # optional - requires GLPK or CBC |
| 3127 | | sage: for c in classes: # optional - requires GLPK or CBC |
| 3128 | | ... gg = Graph() # optional - requires GLPK or CBC |
| 3129 | | ... gg.add_edges(c) # optional - requires GLPK or CBC |
| 3130 | | ... print max(gg.degree())<=2 # optional - requires GLPK or CBC |
| | 3126 | sage: classes = g.two_factor_petersen() # optional - GLPK, CBC |
| | 3127 | sage: for c in classes: # optional - GLPK, CBC |
| | 3128 | ... gg = Graph() # optional - GLPK, CBC |
| | 3129 | ... gg.add_edges(c) # optional - GLPK, CBC |
| | 3130 | ... print max(gg.degree())<=2 # optional - GLPK, CBC |
| 3131 | 3131 | True |
| 3132 | 3132 | True |
| 3133 | 3133 | True |
| 3134 | | sage: Set(set(classes[0]) | set(classes[1]) | set(classes[2])).cardinality() == g.size() # optional - requires GLPK or CBC |
| | 3134 | sage: Set(set(classes[0]) | set(classes[1]) | set(classes[2])).cardinality() == g.size() # optional - GLPK, CBC |
| 3135 | 3135 | True |
| 3136 | 3136 | |
| 3137 | 3137 | :: |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/graphs/graph_coloring.py
|
a
|
b
|
|
| 299 | 299 | |
| 300 | 300 | sage: from sage.graphs.graph_coloring import vertex_coloring |
| 301 | 301 | sage: g = graphs.PetersenGraph() |
| 302 | | sage: vertex_coloring(g, value_only=True) # optional - requires GLPK or CBC |
| | 302 | sage: vertex_coloring(g, value_only=True) # optional - GLPK, CBC |
| 303 | 303 | 3 |
| 304 | 304 | """ |
| 305 | 305 | from sage.numerical.mip import MixedIntegerLinearProgram |
| … |
… |
|
| 510 | 510 | |
| 511 | 511 | sage: from sage.graphs.graph_coloring import edge_coloring |
| 512 | 512 | sage: g = graphs.PetersenGraph() |
| 513 | | sage: edge_coloring(g, value_only=True) # optional - requires GLPK or CBC |
| | 513 | sage: edge_coloring(g, value_only=True) # optional - GLPK, CBC |
| 514 | 514 | 4 |
| 515 | 515 | |
| 516 | 516 | Complete graphs are colored using the linear-time round-robin coloring:: |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/numerical/mip.pyx
|
a
|
b
|
|
| 41 | 41 | sage: for (u,v) in g.edges(labels=None): |
| 42 | 42 | ... p.add_constraint(b[u] + b[v], max=1) |
| 43 | 43 | sage: p.set_binary(b) |
| 44 | | sage: p.solve(objective_only=True) # optional - requires Glpk or COIN-OR/CBC |
| | 44 | sage: p.solve(objective_only=True) # optional - GLPK, CBC |
| 45 | 45 | 4.0 |
| 46 | 46 | """ |
| 47 | 47 | |
| … |
… |
|
| 486 | 486 | sage: x = p.new_variable() |
| 487 | 487 | sage: p.set_objective(x[1] + x[2]) |
| 488 | 488 | sage: p.add_constraint(-3*x[1] + 2*x[2], max=2,name="OneConstraint") |
| 489 | | sage: p.write_mps(SAGE_TMP+"/lp_problem.mps") # optional - requires GLPK |
| | 489 | sage: p.write_mps(SAGE_TMP+"/lp_problem.mps") # optional - GLPK |
| 490 | 490 | |
| 491 | 491 | For information about the MPS file format : |
| 492 | 492 | http://en.wikipedia.org/wiki/MPS_%28format%29 |
| … |
… |
|
| 518 | 518 | sage: x = p.new_variable() |
| 519 | 519 | sage: p.set_objective(x[1] + x[2]) |
| 520 | 520 | sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) |
| 521 | | sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - requires GLPK |
| | 521 | sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - GLPK |
| 522 | 522 | |
| 523 | 523 | For more information about the LP file format : |
| 524 | 524 | http://lpsolve.sourceforge.net/5.5/lp-format.htm |
| … |
… |
|
| 556 | 556 | sage: y = p.new_variable(dim=2) |
| 557 | 557 | sage: p.set_objective(x[3] + 3*y[2][9] + x[5]) |
| 558 | 558 | sage: p.add_constraint(x[3] + y[2][9] + 2*x[5], max=2) |
| 559 | | sage: p.solve() # optional - requires Glpk or COIN-OR/CBC |
| | 559 | sage: p.solve() # optional - GLPK, CBC |
| 560 | 560 | 6.0 |
| 561 | 561 | |
| 562 | 562 | To return the optimal value of ``y[2][9]``:: |
| 563 | 563 | |
| 564 | | sage: p.get_values(y[2][9]) # optional - requires Glpk or COIN-OR/CBC |
| | 564 | sage: p.get_values(y[2][9]) # optional - GLPK, CBC |
| 565 | 565 | 2.0 |
| 566 | 566 | |
| 567 | 567 | To get a dictionary identical to ``x`` containing optimal |
| … |
… |
|
| 640 | 640 | sage: p.set_objective(x[1] + 5*x[2]) |
| 641 | 641 | sage: p.add_constraint(x[1] + 2/10*x[2], max=4) |
| 642 | 642 | sage: p.add_constraint(1.5*x[1]+3*x[2], max=4) |
| 643 | | sage: round(p.solve(),5) # optional - requires Glpk or COIN-OR/CBC |
| | 643 | sage: round(p.solve(),5) # optional - GLPK, CBC |
| 644 | 644 | 6.66667 |
| 645 | 645 | sage: p.set_objective(None) |
| 646 | | sage: p.solve() #optional - requires Glpk or COIN-OR/CBC |
| | 646 | sage: p.solve() #optional - GLPK, CBC |
| 647 | 647 | 0.0 |
| 648 | 648 | """ |
| 649 | 649 | |
| … |
… |
|
| 705 | 705 | sage: p.set_objective(x[1] + 5*x[2]) |
| 706 | 706 | sage: p.add_constraint(x[1] + 0.2*x[2], max=4) |
| 707 | 707 | sage: p.add_constraint(1.5*x[1] + 3*x[2], max=4) |
| 708 | | sage: round(p.solve(),6) # optional - requires Glpk or COIN-OR/CBC |
| | 708 | sage: round(p.solve(),6) # optional - GLPK, CBC |
| 709 | 709 | 6.666667 |
| 710 | 710 | |
| 711 | 711 | There are two different ways to add the constraint |
| … |
… |
|
| 735 | 735 | sage: p.set_objective(x[1] + 5*x[2]) |
| 736 | 736 | sage: p.add_constraint(x[1] + 0.2*x[2] <= 4) |
| 737 | 737 | sage: p.add_constraint(1.5*x[1] + 3*x[2] <= 4) |
| 738 | | sage: p.solve() # optional - requires Glpk or COIN-OR/CBC |
| | 738 | sage: p.solve() # optional - GLPK, CBC |
| 739 | 739 | 6.6666666666666661 |
| 740 | 740 | |
| 741 | 741 | |
| … |
… |
|
| 1048 | 1048 | sage: p.set_objective(x[1] + 5*x[2]) |
| 1049 | 1049 | sage: p.add_constraint(x[1] + 0.2*x[2], max=4) |
| 1050 | 1050 | sage: p.add_constraint(1.5*x[1] + 3*x[2], max=4) |
| 1051 | | sage: round(p.solve(),6) # optional - requires Glpk or COIN-OR/CBC |
| | 1051 | sage: round(p.solve(),6) # optional - GLPK, CBC |
| 1052 | 1052 | 6.666667 |
| 1053 | | sage: p.get_values(x) # optional random - requires Glpk or COIN-OR/CBC |
| | 1053 | sage: p.get_values(x) # optional random - GLPK, CBC |
| 1054 | 1054 | {0: 0.0, 1: 1.3333333333333333} |
| 1055 | 1055 | |
| 1056 | 1056 | Computation of a maximum stable set in Petersen's graph:: |
| … |
… |
|
| 1062 | 1062 | sage: for (u,v) in g.edges(labels=None): |
| 1063 | 1063 | ... p.add_constraint(b[u] + b[v], max=1) |
| 1064 | 1064 | sage: p.set_binary(b) |
| 1065 | | sage: p.solve(objective_only=True) # optional - requires Glpk or COIN-OR/CBC |
| | 1065 | sage: p.solve(objective_only=True) # optional - GLPK, CBC |
| 1066 | 1066 | 4.0 |
| 1067 | 1067 | """ |
| 1068 | 1068 | |
| … |
… |
|
| 1259 | 1259 | |
| 1260 | 1260 | Tests of GLPK's Exceptions:: |
| 1261 | 1261 | |
| 1262 | | sage: p.solve(solver="GLPK") # optional - requires GLPK |
| | 1262 | sage: p.solve(solver="GLPK") # optional - GLPK |
| 1263 | 1263 | Traceback (most recent call last): |
| 1264 | 1264 | ... |
| 1265 | 1265 | MIPSolverException: 'GLPK : Solution is undefined' |
| … |
… |
|
| 1275 | 1275 | |
| 1276 | 1276 | Tests of GLPK's Exceptions:: |
| 1277 | 1277 | |
| 1278 | | sage: p.solve(solver="GLPK") # optional - requires GLPK |
| | 1278 | sage: p.solve(solver="GLPK") # optional - GLPK |
| 1279 | 1279 | Traceback (most recent call last): |
| 1280 | 1280 | ... |
| 1281 | 1281 | MIPSolverException: 'GLPK : Solution is undefined' |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/numerical/mip_coin.pyx
|
a
|
b
|
|
| 36 | 36 | Solving a simple Linear Program using Coin as a solver |
| 37 | 37 | (Computation of a maximum stable set in Petersen's graph):: |
| 38 | 38 | |
| 39 | | sage: from sage.numerical.mip_coin import solve_coin # optional - requires Cbc |
| | 39 | sage: from sage.numerical.mip_coin import solve_coin # optional - CBC |
| 40 | 40 | sage: g = graphs.PetersenGraph() |
| 41 | 41 | sage: p = MixedIntegerLinearProgram(maximization=True) |
| 42 | 42 | sage: b = p.new_variable() |
| … |
… |
|
| 44 | 44 | sage: for (u,v) in g.edges(labels=None): |
| 45 | 45 | ... p.add_constraint(b[u] + b[v], max=1) |
| 46 | 46 | sage: p.set_binary(b) |
| 47 | | sage: solve_coin(p,objective_only=True) # optional - requires Cbc |
| | 47 | sage: solve_coin(p,objective_only=True) # optional - CBC |
| 48 | 48 | 4.0 |
| 49 | 49 | """ |
| 50 | 50 | # Creates the solver interfaces |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/numerical/mip_cplex.pyx
|
a
|
b
|
|
| 33 | 33 | Solving a simple Linear Program using CPLEX as a solver |
| 34 | 34 | (Computation of a maximum stable set in Petersen's graph):: |
| 35 | 35 | |
| 36 | | sage: from sage.numerical.mip_cplex import solve_cplex # optional - requires Cplex |
| | 36 | sage: from sage.numerical.mip_cplex import solve_cplex # optional - CPLEX |
| 37 | 37 | sage: g = graphs.PetersenGraph() |
| 38 | 38 | sage: p = MixedIntegerLinearProgram(maximization=True) |
| 39 | 39 | sage: b = p.new_variable() |
| … |
… |
|
| 41 | 41 | sage: for (u,v) in g.edges(labels=None): |
| 42 | 42 | ... p.add_constraint(b[u] + b[v], max=1) |
| 43 | 43 | sage: p.set_binary(b) |
| 44 | | sage: solve_cplex(p,objective_only=True) # optional - requires Cplex |
| | 44 | sage: solve_cplex(p,objective_only=True) # optional - CPLEX |
| 45 | 45 | 4.0 |
| 46 | 46 | """ |
| 47 | 47 | |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/numerical/mip_glpk.pyx
|
a
|
b
|
|
| 38 | 38 | Solving a simple Linear Program using Coin as a solver |
| 39 | 39 | ( Computation of a maximum stable set in Petersen's graph ):: |
| 40 | 40 | |
| 41 | | sage: from sage.numerical.mip_glpk import solve_glpk # optional - requires Glpk |
| | 41 | sage: from sage.numerical.mip_glpk import solve_glpk # optional - GLPK |
| 42 | 42 | sage: g = graphs.PetersenGraph() |
| 43 | 43 | sage: p = MixedIntegerLinearProgram(maximization=True) |
| 44 | 44 | sage: b = p.new_variable() |
| … |
… |
|
| 46 | 46 | sage: for (u,v) in g.edges(labels=None): |
| 47 | 47 | ... p.add_constraint(b[u] + b[v], max=1) |
| 48 | 48 | sage: p.set_binary(b) |
| 49 | | sage: solve_glpk(p, objective_only=True) # optional - requires Glpk |
| | 49 | sage: solve_glpk(p, objective_only=True) # optional - GLPK |
| 50 | 50 | 4.0 |
| 51 | 51 | """ |
| 52 | 52 | |
| … |
… |
|
| 120 | 120 | sage: x = p.new_variable() |
| 121 | 121 | sage: p.set_objective(x[1] + x[2]) |
| 122 | 122 | sage: p.add_constraint(-3*x[1] + 2*x[2], max=2,name="OneConstraint") |
| 123 | | sage: p.write_mps(SAGE_TMP+"/lp_problem.mps") # optional - requires GLPK |
| | 123 | sage: p.write_mps(SAGE_TMP+"/lp_problem.mps") # optional - GLPK |
| 124 | 124 | |
| 125 | 125 | |
| 126 | 126 | For information about the MPS file format : |
| … |
… |
|
| 161 | 161 | sage: x = p.new_variable() |
| 162 | 162 | sage: p.set_objective(x[1] + x[2]) |
| 163 | 163 | sage: p.add_constraint(-3*x[1] + 2*x[2], max=2) |
| 164 | | sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - requires GLPK |
| | 164 | sage: p.write_lp(SAGE_TMP+"/lp_problem.lp") # optional - GLPK |
| 165 | 165 | |
| 166 | 166 | For more information about the LP file format : |
| 167 | 167 | http://lpsolve.sourceforge.net/5.5/lp-format.htm |
diff -r 556bb66e4c6d -r 49971fc086c8 sage/numerical/optimize.py
|
a
|
b
|
|
| 697 | 697 | `1/5, 1/4, 2/3, 3/4, 5/7`:: |
| 698 | 698 | |
| 699 | 699 | sage: from sage.numerical.optimize import binpacking |
| 700 | | sage: print sorted(binpacking([1/5,1/3,2/3,3/4, 5/7])) # optional - requires GLPK CPLEX or CBC |
| | 700 | sage: print sorted(binpacking([1/5,1/3,2/3,3/4, 5/7])) # optional - GLPK, CBC |
| 701 | 701 | [[1/5, 3/4], [1/3, 2/3], [5/7]] |
| 702 | 702 | |
| 703 | 703 | One way to use only three boxes (which is best possible) is to put |
| … |
… |
|
| 707 | 707 | Of course, we can also check that there is no solution using only two boxes :: |
| 708 | 708 | |
| 709 | 709 | sage: from sage.numerical.optimize import binpacking |
| 710 | | sage: binpacking([0.2,0.3,0.8,0.9], k=2) # optional - requires GLPK CPLEX or CBC |
| | 710 | sage: binpacking([0.2,0.3,0.8,0.9], k=2) # optional - GLPK, CBC |
| 711 | 711 | Traceback (most recent call last): |
| 712 | 712 | ... |
| 713 | 713 | ValueError: This problem has no solution ! |