Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions src/doc/en/reference/graphs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Libraries of algorithms
sage/graphs/pq_trees
sage/graphs/matching
sage/graphs/matchpoly
sage/graphs/morphisms
sage/graphs/genus
sage/graphs/lovasz_theta
sage/graphs/schnyder
Expand Down Expand Up @@ -126,5 +127,3 @@ Libraries of algorithms
sage/graphs/cycle_enumeration

.. include:: ../footer.txt


8 changes: 8 additions & 0 deletions src/sage/graphs/generic_graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@
:meth:`~GenericGraph.is_isomorphic` | Test for isomorphism between ``self`` and ``other``.
:meth:`~GenericGraph.canonical_label` | Return the canonical graph.
:meth:`~GenericGraph.is_cayley` | Check whether the graph is a Cayley graph.
:meth:`~GenericGraph.is_homeomorphic` | Check whether ``G`` and ``H`` are homeomorphic.
:meth:`~GenericGraph.reduced_homeomorphic_graph` | Return the smallest graph homeomorphic to `G`.
:meth:`~GenericGraph.has_homomorphism_to` | Check whether there is a homomorphism between two graphs.

**Graph properties:**

Expand Down Expand Up @@ -26016,6 +26019,11 @@ def is_self_complementary(self):
)
from sage.graphs.line_graph import line_graph
rooted_product = LazyImport('sage.graphs.graph_decompositions.graph_products', 'rooted_product')
from sage.graphs.morphisms import (
has_homomorphism_to,
is_homeomorphic,
reduced_homeomorphic_graph,
)
from sage.graphs.path_enumeration import (
_all_paths_iterator,
all_paths,
Expand Down
113 changes: 0 additions & 113 deletions src/sage/graphs/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -3966,119 +3966,6 @@
ret += prod(fact[i] for i in pa.to_exp()) * m[pa] * (1+t)**mono(pi)
return ret

@doc_index("Algorithmically hard stuff")
def has_homomorphism_to(self, H, core=False, solver=None, verbose=0,
*, integrality_tolerance=1e-3):
r"""
Check whether there is a homomorphism between two graphs.

A homomorphism from a graph `G` to a graph `H` is a function
`\phi:V(G)\mapsto V(H)` such that for any edge `uv \in E(G)` the pair
`\phi(u)\phi(v)` is an edge of `H`.

Saying that a graph can be `k`-colored is equivalent to saying that it
has a homomorphism to `K_k`, the complete graph on `k` elements.

For more information, see the :wikipedia:`Graph_homomorphism`.

INPUT:

- ``H`` -- the graph to which ``self`` should be sent

- ``core`` -- boolean (default: ``False``; whether to minimize the size
of the mapping's image (see note below). This is set to ``False`` by
default.

- ``solver`` -- string (default: ``None``); specifies a Mixed Integer
Linear Programming (MILP) solver to be used. If set to ``None``, the
default one is used. For more information on MILP solvers and which
default solver is used, see the method :meth:`solve
<sage.numerical.mip.MixedIntegerLinearProgram.solve>` of the class
:class:`MixedIntegerLinearProgram
<sage.numerical.mip.MixedIntegerLinearProgram>`.

- ``verbose`` -- integer (default: 0); sets the level of
verbosity. Set to 0 by default, which means quiet.

- ``integrality_tolerance`` -- float; parameter for use with MILP
solvers over an inexact base ring; see
:meth:`MixedIntegerLinearProgram.get_values`.

.. NOTE::

One can compute the core of a graph (with respect to homomorphism)
with this method ::

sage: g = graphs.CycleGraph(10)
sage: mapping = g.has_homomorphism_to(g, core=True) # needs sage.numerical.mip
sage: print("The size of the core is {}".format(len(set(mapping.values())))) # needs sage.numerical.mip
The size of the core is 2

OUTPUT:

This method returns ``False`` when the homomorphism does not exist, and
returns the homomorphism otherwise as a dictionary associating a vertex
of `H` to a vertex of `G`.

EXAMPLES:

Is Petersen's graph 3-colorable::

sage: P = graphs.PetersenGraph()
sage: P.has_homomorphism_to(graphs.CompleteGraph(3)) is not False # needs sage.numerical.mip
True

An odd cycle admits a homomorphism to a smaller odd cycle, but not to an
even cycle::

sage: g = graphs.CycleGraph(9)
sage: g.has_homomorphism_to(graphs.CycleGraph(5)) is not False # needs sage.numerical.mip
True
sage: g.has_homomorphism_to(graphs.CycleGraph(7)) is not False # needs sage.numerical.mip
True
sage: g.has_homomorphism_to(graphs.CycleGraph(4)) is not False # needs sage.numerical.mip
False
"""
self._scream_if_not_simple()
from sage.numerical.mip import MixedIntegerLinearProgram, MIPSolverException
p = MixedIntegerLinearProgram(solver=solver, maximization=False)
b = p.new_variable(binary=True)

# Each vertex has an image
for ug in self:
p.add_constraint(p.sum(b[ug, uh] for uh in H) == 1)

nonedges = H.complement().edges(sort=False, labels=False)
for ug, vg in self.edges(sort=False, labels=False):
# Two adjacent vertices cannot be mapped to the same element
for uh in H:
p.add_constraint(b[ug, uh] + b[vg, uh] <= 1)

# Two adjacent vertices cannot be mapped to no adjacent vertices
for uh, vh in nonedges:
p.add_constraint(b[ug, uh] + b[vg, vh] <= 1)
p.add_constraint(b[ug, vh] + b[vg, uh] <= 1)

# Minimize the mapping's size
if core:

# the value of m is one if the corresponding vertex of h is used.
m = p.new_variable(nonnegative=True)
for uh in H:
for ug in self:
p.add_constraint(b[ug, uh] <= m[uh])

p.set_objective(p.sum(m[vh] for vh in H))

try:
p.solve(log=verbose)
except MIPSolverException:
return False

b = p.get_values(b, convert=bool, tolerance=integrality_tolerance)
mapping = dict(x[0] for x in b.items() if x[1])
return mapping

@doc_index("Clique-related methods")
def fractional_clique_number(self, solver='PPL', verbose=0,
check_components=True, check_bipartite=True):
Expand Down Expand Up @@ -9568,7 +9455,7 @@
The Peterson graph is a known projective planar graph::

sage: P = graphs.PetersenGraph()
sage: P.is_projective_planar() # long time

Check warning on line 9458 in src/sage/graphs/graph.py

View workflow job for this annotation

GitHub Actions / Conda (ubuntu, Python 3.12, new)

Warning: slow doctest:

slow doctest:: Test ran for 246.66s cpu, 246.86s wall Check ran for 0.00s cpu, 0.00s wall

Check warning on line 9458 in src/sage/graphs/graph.py

View workflow job for this annotation

GitHub Actions / test-long (src/sage/[g-o]*)

Warning: slow doctest:

slow doctest:: Test ran for 358.02s cpu, 361.23s wall Check ran for 0.00s cpu, 0.00s wall
True

`K_{4,4}` has a projective plane crossing number of 2. One of the
Expand Down
1 change: 1 addition & 0 deletions src/sage/graphs/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ py.install_sources(
'matchpoly.pyx',
'mcqd.pxd',
'mcqd.pyx',
'morphisms.py',
'orientations.py',
'partial_cube.py',
'path_enumeration.pyx',
Expand Down
Loading
Loading