Graphes d'espace négatif


13

Tâche

Vous recevrez un entier positif et vous devrez produire un " graphique auto-complémentaire " avec autant de nœuds. Si vous ne savez pas ce qu'est un graphique auto-complémentaire, l'article de wikipedia ne vous aidera pas beaucoup, voici deux explications, une technique et une non technique.

Non technique

Un graphique est un ensemble de nœuds connectés par des lignes. Chaque paire de points peut être connectée par une ligne ou aucune. Le "complément" d'un graphe est le résultat de la prise d'un graphe et de la connexion de tous les nœuds qui ne sont pas connectés et de la déconnexion de tous les nœuds qui le sont.

Un graphe auto-complémentaire est un graphe dont le complément peut être réorganisé sous la forme de l'original. Vous trouverez ci-dessous un exemple de graphique auto-complémentaire et une démonstration de comment.

Voici un graphique à 5 nœuds:

Graphique à 5 nœuds

Nous mettrons en évidence tous les endroits où les connexions pourraient aller avec des lignes pointillées rouges:

Graphique en surbrillance

Nous allons maintenant trouver le complément du graphique en échangeant les bords rouge et noir:

Complément

Cela ne ressemble pas au graphique d'origine, mais si nous déplaçons les nœuds comme cela (chaque étape permute deux nœuds):

Isomorphisme

Nous obtenons le graphique d'origine! Le graphique et son complément sont le même graphique

Technique

Un graphe auto-complémentaire est un graphe isomorphe à son complément.

Caractéristiques

Vous recevrez un entier positif via la méthode qui vous convient le mieux. Et vous produirez un graphique dans la méthode que vous jugerez appropriée, cela inclut, mais sans s'y limiter , le formulaire de matrice d'adjacence , le formulaire de liste d'adjacence et bien sûr des images! Le graphique en sortie doit être son propre complément et avoir autant de nœuds que l'entrée entière. Si aucun graphique de ce type n'existe, vous devez générer une valeur falsifiée.

C'est du et vous devez viser à minimiser votre nombre d'octets.

Cas de test

Vous trouverez ci-dessous des images des sorties possibles pour plusieurs n

4

5

9


Un graphe auto-complémentaire ne peut exister que lorsque le graphe complet a un nombre pair d'arêtes. Sommes-nous garantis?
xnor

@xnor J'ai oublié de l'inclure. Fixé maintenant.
Post Rock Garf Hunter

Faut-il gérer les entrées négatives?
xnor

@xnor Non. Je vais corriger la question pour qu'elle soit cohérente
Post Rock Garf Hunter

3
Avant que quiconque ait l'idée de baser une réponse GraphData@{"SelfComplementary",{#,1}}&, je pense que cela charge simplement quelques exemples de bas nde la base de données de Wolfram, donc cela ne fonctionnera pas pour des entrées arbitrairement grandes.
Martin Ender

Réponses:


9

Haskell , 77 octets

f n=[(a,b)|b<-[1..n],a<-[1..b-1],mod n 4<2,mod(a+(last$b:[a|odd n,n==b]))4<2]

Essayez-le en ligne!

Il utilise un critère explicite facile à calculer pour décider si une arête (a,b)appartient au graphique. Instancie cet algorithme , avec le cycle de permutation parmi les valeurs modulo 4

4*m -> 4*m+1 -> 4*m+2 -> 4*m+3 -> 4*m

Nous incluons les arêtes dont les deux sommets d'extrémité ajoutent à 0 ou 1 modulo 4. Notez que les sommets cycliques selon cette permutation ajoutent 2 modulo 4 à la somme des sommets sur chacun, et permutent ainsi les arêtes et les non-arêtes. Cela donne une permutation des sommets qui complète les bords.

Si le graphique a un nœud supplémentaire au-delà d'un multiple de 4, il est placé dans un cycle seul. Nous incluons des arêtes avec lui lorsque l'autre sommet est pair. Permuter les sommets inverse la parité et le graphe reste donc auto-complémentaire.

Si le nombre de sommets n'est pas 0 ou 1 modulo 4, aucun graphe auto-complémentaire n'est possible car il y a un nombre impair d'arêtes dans le graphe complet

Globalement, voici les conditions:

  • Si l'entrée n n'est pas 0 ou 1 modulo 4, sortez une liste vide
  • Sinon, si n est pair, inclure toutes les arêtes (a,b)avec a<beta+b égal à 0 ou 1 modulo 4.
  • Sinon, si n est impair, faites de même, mais incluez plutôt les bords du formulaire (a,n)lorsque a est pair.

Le code combine les deuxième et troisième cas en remplaçant la condition mod(a+b)4<2par les mod(a+a)4<2deux odd net b==n.


5

Brachylog 2 , 24 octets

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧

Essayez-le en ligne!

Il s'agit d'une fonction qui renvoie une paire composée de deux listes d'adjacence: une pour le graphique, une pour le graphique complémentaire. (Dans l'interpréteur Brachylog sur TIO, vous pouvez lui demander d'évaluer une fonction, plutôt qu'un programme complet, en donnant Zcomme argument de ligne de commande.) Par exemple, la sortie d'entrée 5est:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

Voici à quoi ressemble une image (montrant les deux graphiques):

un graphe et son complément identique sur 5 éléments

Comme cela est courant dans les langages basés sur Prolog, la fonction prend en charge plusieurs modèles d'appel. Notamment, si vous essayez de l'utiliser en tant que générateur, il produira tous les graphiques auto-complémentaires possibles avec le nombre de sommets donné (bien que je n'aie fait aucun effort pour rendre ce cas utilisable, et notamment il produira chacun de les graphiques plusieurs fois chacun).

Explication

Il s'agit essentiellement d'une description du problème, laissant l'implémentation de Prolog pour trouver la meilleure méthode pour le résoudre. (Cependant, je doute qu'il utilisera un algorithme mieux que la force brute dans ce cas particulier, donc il est probablement assez inefficace, et les tests semblent le confirmer, montrant que les performances empirent d'autant plus que le graphique est grand.)

{⟦₁⊇Ċ}ᶠpḍ.(\\ᵐcdl?∨?<2)∧
 ⟦₁                       The range [1, 2, …, ?], where ? is the input
   ⊇                      A subset of that range…
    Ċ                     …which has exactly two elements
{    }ᶠ                   A list of everything that fits the above description
{⟦₁⊇Ċ}ᶠ                   All edges that could exist in a ?-element graph
       p                  Find a permutation of these…
        ḍ                 …so that splitting it into two equal parts…
          (       ∨   )   …either:
               dl?          produces ? distinct elements
           \                after transposing it
            \ᵐ              and transposing its elements
              c             and flattening one level;
                          or:
                   ?<2      ? was less than 2
         .             ∧  Once you've found it, . specifies what to output

Soit dit en passant, j'ai fini par devoir dépenser un total de 6 octets (¼ du programme, les caractères (∨?<2) ) pour traiter les cas spéciaux de 0 et 1. Frustrant, mais c'est la nature des cas spéciaux.

La \\ᵐcdl?section est un peu difficile à comprendre, alors voici un exemple concret. Son but est de vérifier si quelque chose est un graphe et son complément, les bords correspondants du graphe et du complément étant dans le même ordre dans les listes. La paire graphique / complément devient la sortie éventuelle du programme. Voici un exemple de cas:

[[[1,2],[1,3],[1,5],[3,5],[4,5]],[[2,5],[2,3],[2,4],[3,4],[1,4]]]

La transposition nous donne une liste de paires d'arêtes correspondantes entre le graphe et le complément:

[[[1,2],[2,5]],[[1,3],[2,3]],[[1,5],[2,4]],[[3,5],[3,4]],[[4,5],[1,4]]

Ensuite, nous transposons à l'intérieur des éléments de la liste et aplatissons un niveau; qui nous donne une liste de paires d'éléments correspondants entre le graphe et le complément:

[[1,2],[2,5],[1,2],[3,3],[1,2],[5,4],[3,3],[5,4],[4,1],[5,4]]

Clairement, ce que nous voulons ici, c'est qu'il n'y ait pas plus d'une paire à partir de chaque élément (prouvant ainsi que les éléments du graphe et du complément sont en correspondance 1 à 1). Nous pouvons presque vérifier cela simplement en déclarant que la liste a exactement ?des éléments distincts (c'est-à-dire un nombre d'éléments distincts égal au nombre de sommets). Dans ce cas, le test réussit; les éléments distincts sont:

[[1,2],[2,5],[3,3],[5,4],[4,1]]

Cependant, cela laisse place à un problème potentiel; si un sommet est entièrement déconnecté dans le graphique d'origine, sa correspondance ne sera pas mentionnée, laissant la place à une correspondance en double à partir d'un autre sommet. Si tel est le cas, le graphique du complément doit avoir une arête entre ce sommet (sans perte de généralité, disons que c'est 1), et tous les autres sommets, et ainsi la liste des correspondances contiendra [1,2], [1,3]..., [1, ?]. Quand ?est grand, cela entraînera plus de correspondances que nous n'en aurions autrement, donc il n'y a pas de problème. Le seul problème se produit quand ?est 3 ou moins, auquel cas nous finissons seulement par ajouter une correspondance supplémentaire (tout en supprimant une de1 n'apparaît pas dans l'entrée); cependant, ce n'est pas un problème dans la pratique, car il y a 3 bords possibles sur un graphique à 3 éléments, ce qui est un nombre impair (de même, 1 bord possible sur un graphique à 2 éléments est également un nombre impair), et donc le test échouera au\ étape (vous ne pouvez pas transposer une liste irrégulière, c'est-à-dire celles dont les éléments ont des longueurs différentes).


La différence entre zet \est que zest cyclique zip, ce qui signifie que [[1,2,3],["a"]]finira par être [[1,"a"],[2,"a"],[3,"a"]]avec z, alors qu'il échouera pour \. \en ce moment ne fonctionne que sur des matrices carrées; la mise en œuvre future le fera fonctionner comme z, sauf de façon cyclique.
Fatalize

J'avais en fait compris la différence moi-même, mais seulement après avoir écrit l'explication. Cette solution particulière dépend de `` travailler uniquement sur des rectangles (même si cela ne prend que 2 octets de plus si vous ne pouvez pas profiter de cette étape).

2

BBC BASIC, 161 octets

Taille de fichier Tokenized 140 octets

Téléchargez l'interprète sur http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

I.m:IF2ANDm ORm<4P.0:END
r=400n=-2A.m:t=2*PI/n:F.i=1TOn*n:a=i DIVn:b=i MODn:c=b:IFa+b A.2a*=t:b*=t:L.r+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1A.m A.c DRAWr*3,0
N.

Code non golfé

  INPUTm                           :REM get input
  IF2ANDm ORm<4PRINT0:END          :REM if m=4x+2 or 4x+3 or less than 4, print 0 and exit
  r=400                            :REM radius of diagram
  n=-2ANDm                         :REM n = m truncated to an even number
  t=2*PI/n                         :REM t = 1/n turns
  FORi=1TOn*n                      :REM for each combination of vertices
    a=i DIVn                       :REM extract a and b
    b=i MODn                       :REM make a copy of c
    c=b                            :REM if a+b MOD 4 = 2 or 3, convert a and b to angles and draw edge.
    IFa+b AND2 a*=t:b*=t:LINEr+r*SINa,r+r*COSa,r+r*SINb,r+r*COSb:IF 1ANDm ANDc DRAWr*3,0
  NEXT                             :REM if m is odd and c is odd, draw a line to the additional vertex for m=4x+1 input.

Explication

Cela utilise le même algorithme que Xnor, mais produit une sortie schématique.

nest la forme 4x+2ou 4x+3il n'y a pas de solution car le nombre d'arêtes est impair.

nest de la forme 4x, nous organisons tous les sommets dans un cercle et dessinons ces bords où (a+b) mod 4est 2 ou 3 (pas 0 ou 1 comme dans le cas de Xnor, pour des raisons de golf. C'est donc le complément de la solution donnée par Xnor.)

Pour voir cela dans un sens plus pictural, nous prenons un sommet sur deux et dessinons les bords aux sommets 1 et 2 endroits dans le sens inverse des aiguilles d'une montre. Cela définit ndes directions parallèles, la moitié du total. Ensuite, nous ajoutons tous les autres bords parallèles à ceux-ci.

Le complément peut être trouvé en ajoutant 1 à la fois à a et à b dans chaque spécification de bord, ou de manière imagée en faisant tourner le diagramme par un 1/n tour.

nest de la forme 4x + 1, nous ajoutons un autre sommet, qui est lié à chaque deuxième sommet du graphique 4x. S'il était placé au centre, la symétrie du diagramme serait préservée, mais j'ai choisi de le placer en dehors du cercle principal de points pour plus de clarté.

Production

Voici les premiers cas pour 4x + 1. les cas 4x peuvent être vus en supprimant le sommet en bas à droite et ses bords associés.

entrez la description de l'image ici


1

JavaScript (ES6), 191 octets

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a

Cette fonction renvoie une liste d'adjacence. Il utilise deux algorithmes et différencie les graphiques complémentaires vides et les non-sorties en retournant 0au lieu de []quand aucun n'existe. Le premier algorithme est basé sur des graphiques Rado construits à l'aide du prédicat BIT et crée des graphiques complémentaires valides d'ordre 0, 1, 4 et 5. L'autre algorithme, trouvé par nos amis en mathématiques , construit un graphe complémentaire V + 4 sommet valide en appliquant une addition à 4 voies à un graphe complémentaire V sommet valide.

Il commence par valider l'entrée pour confirmer l'existence d'un graphe complémentaire valide (à l'aide n*~-n/4%1), et si cela échoue, retourne 0. Il vérifie ensuite si n>5et revient au n-4cas pour construire une solution d'ordre inférieur valide, puis applique l'addition 4 à la liste d'adjacence retournée sur le chemin de la chaîne de récursivité. Enfin, si ce n>5n'est pas vrai, il itère de 0à n-1pour xet y, et vérifie si le (y>>x)&1est vrai. Si oui, alors ces nœuds sont appariés.

Voici un format plus lisible de la fonction, avec des opérateurs ternaires étendus aux instructions if-else et eval()s en ligne:

// precalculate amount of required vertices in v
f = (n, a = [], v = n*~-n / 4) => {
  // if amount is non-integer
  if (v % 1) {
    // no valid complementary graph
    return 0;
  } else {
    if (n > 5) {
      // generate valid (n-4)-order complementary graph
      f(n -= 4, a);
      // apply 4-path addition
      for (i = 0; i < n;)
        a.push([i, n+1],[i++, n+2]);
      a.push([n, ++n], [n, ++n], [n, ++n]);
    } else {
      // construct Rado graph using BIT predicate
      for(l = x = 0; x < n; x++)
        for(y = x; y < n; y++)
          // if amount of pairs is less than required and xth bit of y is high
          if (l < v && (y>>x & 1))
            // vertices x and y should be paired
            a.push([x,y]);
    }
    return a;
  }
};

Démo

f=(n,a=[],v=n*~-n/4)=>v%1?0:eval(n>5?f(n-=4,a)&&'for(i=0;i<n;)a.push([i,n+1],[i++,n+2]);a.push([n,++n],[n,++n],[n,++n])-v':'for(l=x=0;x<n;x++)for(y=x;y<n;y++)l<v&y>>x&1?l=a.push([x,y]):a')||a
<input type="number" onchange="o.textContent=JSON.stringify(f(this.value))"><pre id="o"></pre>

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.