Risposte:
Il modo migliore (in termini di pigrizia) è usare lo strumento Sage liberamente disponibile che ha il miglior supporto per la teoria dei grafi.
Esempio
sage: G = graphs.PetersenGraph()
sage: G.has_homomorphism_to(graphs.CycleGraph(5))
False
sage: G.has_homomorphism_to(graphs.CompleteGraph(5))
{0: 0, 1: 1, 2: 0, 3: 1, 4: 2, 5: 1, 6: 0, 7: 2, 8: 2, 9: 1}
Un approccio sarebbe quello di utilizzare un solutore SAT.
Introdurre una variabile booleana per ogni vertice da e ciascun vertice da . L'intuizione è che sarà vero se l'omomorfismo mappa . (Naturalmente, se si dispone di un insieme candidato minore di vertici che potrebbe mappare - forse limitato giù con considerazioni di laurea o di altri criteri locali - allora si può ridurre il numero di variabili booleane di conseguenza Questo tipo di pre-elaborazione potrebbe migliorare la. efficienza di questo approccio in modo significativo.)
Successivamente, aggiungi due tipi di clausole / vincoli:
Aggiungi alcune clausole per richiedere che questa mappatura formi un omomorfismo grafico. In particolare, per ciascun bordo , aggiungere il vincolo
(Puoi convertirlo in 3CNF usando la trasformazione standard di Tseitin.)
Aggiungere alcune clausole per richiedere che ogni vertice da associa a esattamente un vertice da . Esistono numerosi metodi standard per codificare questo vincolo. Un modo semplice è, per ogni vertice , aggiungere la clausola
e la clausola
Quindi, è possibile utilizzare qualsiasi solutore SAT standard. Non so quanto funzionerà in pratica, ma potresti provarlo e vedere come funziona.
Nella letteratura di ricerca, il problema dell'omomorfismo grafico è stato ampiamente studiato per grafici con proprietà speciali (ad esempio, dove è una cricca, dove ha limitato la larghezza degli alberi e così via). Se conosci qualcosa di speciale sulla struttura dei tuoi grafici, potrebbe essere possibile trovare algoritmi migliori per il tuo problema. Per i grafici generali, questo problema è noto per essere NP-difficile.