Étonnamment, nous n'avons pas encore eu de défis sur la coloration des graphiques!
Étant donné un graphe non orienté, nous pouvons donner à chaque sommet une couleur telle que deux sommets adjacents ne partagent pas la même couleur. Le plus petit nombre χ de couleurs distinctes nécessaires pour y parvenir est appelé numéro chromatique du graphique.
Par exemple, ce qui suit montre une coloration valide utilisant le nombre minimum de couleurs:
(Trouvé sur Wikipedia)
Le nombre chromatique de ce graphique est donc χ = 3 .
Écrivez un programme ou une fonction qui, étant donné un nombre de sommets N <16 (qui sont numérotés de 1 à N ) et une liste d'arêtes, détermine le nombre chromatique d'un graphique.
Vous pouvez recevoir l'entrée et produire la sortie dans n'importe quel format approprié, tant que l'entrée n'est pas prétraitée. Autrement dit, vous pouvez utiliser une chaîne ou un tableau, ajouter des délimiteurs pratiques à la chaîne ou utiliser un tableau imbriqué, mais quoi que vous fassiez, la structure aplatie doit contenir les mêmes numéros que les exemples ci-dessous (dans le même ordre).
Vous ne pouvez pas utiliser les fonctions intégrées liées à la théorie des graphes (comme celles de Mathematica ChromaticNumber
).
Vous pouvez supposer que le graphique n'a pas de boucle (un bord reliant un sommet à lui-même) car cela rendrait le graphique incolore.
Il s'agit du code golf, la réponse la plus courte (en octets) l'emporte.
Exemples
Votre programme doit au moins résoudre tous ces problèmes dans un délai raisonnable. (Il doit résoudre correctement toutes les entrées, mais cela peut prendre plus de temps pour les entrées plus grandes.)
Pour raccourcir le message, dans les exemples suivants, je présente les bords dans une seule liste séparée par des virgules. Si vous préférez, vous pouvez utiliser des sauts de ligne ou attendre l'entrée dans un format de tableau pratique.
Triangle (χ = 3)
3
1 2, 2 3, 1 3
"Anneau" de 6 sommets (χ = 2)
6
1 2, 2 3, 3 4, 4 5, 5 6, 6 1
"Anneau" de 5 sommets (χ = 3)
5
1 2, 2 3, 3 4, 4 5, 5 1
Exemple d'image ci-dessus (χ = 3)
6
1 2, 2 3, 3 4, 4 5, 5 6, 6 1, 1 3, 2 4, 3 5, 4 6, 5 1, 6 2
Généralisation de ce qui précède pour 7 sommets (χ = 4)
7
1 2, 2 3, 3 4, 4 5, 5 6, 6 7, 7 1, 1 3, 2 4, 3 5, 4 6, 5 7, 6 1, 7 2
Graphique de Petersen (χ = 3)
10
1 2, 2 3, 3 4, 4 5, 5 1, 1 6, 2 7, 3 8, 4 9, 5 10, 6 8, 7 9, 8 10, 9 6, 10 7
Graphique complet de 5 sommets, plus un sommet déconnecté (χ = 5)
6
1 2, 1 3, 1 4, 1 5, 2 3, 2 4, 2 5, 3 4, 3 5, 4 5
Graphique complet de 8 sommets (χ = 8)
8
1 2, 1 3, 1 4, 1 5, 1 6, 1 7, 1 8, 2 3, 2 4, 2 5, 2 6, 2 7, 2 8, 3 4, 3 5, 3 6, 3 7, 3 8, 4 5, 4 6, 4 7, 4 8, 5 6, 5 7, 5 8, 6 7, 6 8, 7 8
Réseau triangulaire à 15 sommets (χ = 3)
15
1 2, 1 3, 2 3, 2 4, 2 5, 3 5, 3 6, 4 5, 5 6, 4 7, 4 8, 5 8, 5 9, 6 9, 6 10, 7 8, 8 9, 9 10, 7 11, 7 12, 8 12, 8 13, 9 13, 9 14, 10 14, 10 15, 11 12, 12 13, 13 14, 14 15
la source
Réponses:
Python 2.7 -
122109111 111109108103Usage:
Force brute en augmentant le nombre chromatique (m) et vérifiez toutes les colorations possibles. Une coloration peut être décrite comme un nombre en base m. Les colorations possibles sont donc 0, 1, ..., m ^ n-1.
edit: Le graphe complet de 8 sommets prend assez de temps. Mais mon ordinateur portable le résout en environ 10 minutes. Les autres cas de test ne prennent que quelques secondes.
edit 2: Lire que le prétraitement est autorisé, je laisse donc l'index des sommets commencer par 0: raccourcit t * m // m ** x% m en t // m ** a% m (-2). Dissoudre lambda et mettre m dans les paramètres de fonction (-11)
edit 3: le prétraitement n'est pas autorisé -> retour à t * m (+4), simplifié // à / (-2).
modifier 4: supprimer les crochets dans n'importe quel (-2), merci xnor.
edit 5: au lieu de prendre deux fois modulo m, il suffit de les soustraire et ensuite d'utiliser modulo (-1). Il s'agit également d'une amélioration des performances. Tous les tests prennent ensemble environ 25 secondes sur mon ordinateur portable.
edit 6: appel récursif au lieu de while 1: et m + = 1 (-5). Merci encore, xnor.
la source
all([...])
si vous encassez les parenthèsesa,b
(ce qui ne coûte aucun caractère ici en raison de l'espacement) afin deall
ne pas les confondre avec des arguments supplémentaires. En outre, je soupçonne que vous pouvez enregistrer des caractères si vous recursez avec un appel de fonction au niveaum
supérieur suivant plutôt que d'utiliser une boucle while.any
et l'and/or
astuce, puis il enregistre quelques caractères:f=lambda n,e,m=1:any(all(t*m//m**a%m!=t*m//m**b%m for(a,b)in e)for t in range(m**n))and m or f(n,e,m+1)
.Java -
241218La façon la plus évidente de le faire étant donné les contraintes est la force brute. Parcourez chaque numéro chromatique
k
et attribuez chaque couleur à chaque sommet. Si aucun voisin n'est de la même couleur, vous avez votre numéro. Sinon, continuez.Cela prend le plus de temps pour le cas de test
χ = 8
(les graphiques complets sont nulles ici), mais c'est toujours sous 15 secondes (ok, environ 100s avec la dernière modification).L'entrée est le nombre de sommets
n
et un tableau de sommets d'arêtese[]
donnés dans le même ordre que les valeurs séparées par des virgules OP.Avec des sauts de ligne:
Oh, et cela suppose que l'entrée est une sorte de graphique colorable. Si une arête passe de v1 à v1, ou s'il n'y a pas de sommets, elle ne peut pas être colorée et affichera 0. Cela fonctionnera toujours pour les graphiques sans arêtes
χ=1
, etc.la source
Python 3 - 162
Utilise la même approche par force brute, mais utilise la bibliothèque itertools pour, espérons-le, une génération de combinaisons plus rapide. Résout le graphique complet de 8 en <1 min sur ma machine assez ordinaire.
Exemple d'utilisation pour le cas complet à 8 graphiques:
la source
Haskell, 163 octets
L'utilisation serait comme ceci:
Approche de base de la force brute. Vérifiez toutes les combinaisons de couleurs possibles si elles sont valides. Pas grand-chose d'autre à dire ici, sauf que je suis heureux d'entendre des conseils pour raccourcir cela encore plus;)
la source
all id
est identique àand
,any id
est identique àor
etany id$map f list
est identique à justeany f list
. vous pouvez également faire quelques choses avecg
: vous pouvez le redéfinir en tant queg a=(and.).zipWith(\x y->a!!x/=a!!y)
, le rendre infixé, changer l'ordre d'entrée pour le remplacer(\x->g x b c)
parg b c
ou même le rendre complètement sans points et l'intégrer. certains d'entre eux ne fonctionnent pas ensemble, alors essayez-les tous et choisissez le meilleur :)