J'ai été intrigué par la conception de ce graphique du New York Times, dans lequel chaque État américain est représenté par un carré dans une grille. Je me suis demandé s'ils avaient placé les carrés à la main ou s'ils avaient effectivement trouvé un placement optimal des carrés (sous une certaine définition) pour représenter les positions des états contigus.
Votre code va relever une petite partie du défi de placer de manière optimale des carrés pour représenter des états (ou d'autres formes bidimensionnelles arbitraires). Plus précisément, il va supposer que nous avons déjà tous les centres géographiques ou centroïdes des formes dans un format pratique, et que la représentation optimale des données dans un diagramme comme celui-ci est celle dans laquelle la distance totale entre les centroïdes des formes et les centres des carrés qui les représentent est minimale, avec au plus un carré dans chaque position possible.
Votre code prendra une liste de paires uniques de coordonnées X et Y à virgule flottante de 0,0 à 100,0 (inclus) dans n'importe quel format pratique, et affichera les coordonnées entières non négatives des carrés d'unité dans une grille placée de manière optimale pour représenter les données , en préservant l'ordre. Dans les cas où plusieurs arrangements de carrés sont optimaux, vous pouvez sortir n'importe lequel des arrangements optimaux. Entre 1 et 100 paires de coordonnées seront données.
C'est le golf de code, le code le plus court gagne.
Exemples:
Contribution: [(0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (1.0, 0.0)]
C'est facile. Les centres des carrés de notre grille sont à 0,0, 1,0, 2,0, etc. donc ces formes sont déjà parfaitement placées au centre des carrés dans ce modèle:
21
03
Donc, votre sortie doit être exactement ces coordonnées, mais sous forme d'entiers, dans un format de votre choix:
[(0, 0), (1, 1), (0, 1), (1, 0)]
Contribution: [(2.0, 2.1), (2.0, 2.2), (2.1, 2.0), (2.0, 1.9), (1.9, 2.0)]
Dans ce cas, toutes les formes sont proches du centre du carré en (2, 2), mais nous devons les repousser car deux carrés ne peuvent pas être dans la même position. Minimiser la distance entre le centre de gravité d'une forme et le centre du carré qui la représente nous donne ce modèle:
1
402
3
Votre sortie devrait donc l'être [(2, 2), (2, 3), (3, 2), (2, 1), (1, 2)]
.
Cas de test:
[(0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (1.0, 0.0)] -> [(0, 0), (1, 1), (0, 1), (1, 0)]
[(2.0, 2.1), (2.0, 2.2), (2.1, 2.0), (2.0, 1.9), (1.9, 2.0)] -> [(2, 2), (2, 3), (3, 2), (2, 1), (1, 2)]
[(94.838, 63.634), (97.533, 1.047), (71.954, 18.17), (74.493, 30.886), (19.453, 20.396), (54.752, 56.791), (79.753, 68.383), (15.794, 25.801), (81.689, 95.885), (27.528, 71.253)] -> [(95, 64), (98, 1), (72, 18), (74, 31), (19, 20), (55, 57), (80, 68), (16, 26), (82, 96), (28, 71)]
[(0.0, 0.0), (0.1, 0.0), (0.2, 0.0), (0.0, 0.1), (0.1, 0.1), (0.2, 0.1), (0.0, 0.2), (0.1, 0.2), (0.2, 0.2)] -> [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)]
[(1.0, 0.0), (1.0, 0.1), (1.0, 0.2), (1.0, 0.3)] -> [(1, 0), (0, 0), (2, 0), (1, 1)] or [(1, 0), (2, 0), (0, 0), (1, 1)]
[(3.75, 3.75), (4.25, 4.25)] -> [(3, 4), (4, 4)] or [(4, 3), (4, 4)] or [(4, 4), (4, 5)] or [(4, 4), (5, 4)]
Distance totale entre les centroïdes des formes et les centres des carrés qui les représentent dans chaque cas (veuillez me prévenir si vous repérez des erreurs!):
0.0
3.6
4.087011
13.243299
2.724791
1.144123
Juste pour le fun:
Voici une représentation des centres géographiques des États-Unis contigus dans notre format d'entrée, à peu près à l'échelle utilisée par le Times:
[(15.2284, 3.1114), (5.3367, 3.7096), (13.0228, 3.9575), (2.2198, 4.8797), (7.7802, 5.5992), (20.9091, 6.6488), (19.798, 5.5958), (19.1941, 5.564), (17.023, 1.4513), (16.6233, 3.0576), (4.1566, 7.7415), (14.3214, 6.0164), (15.4873, 5.9575), (12.6016, 6.8301), (10.648, 5.398), (15.8792, 5.0144), (13.2019, 2.4276), (22.3025, 8.1481), (19.2836, 5.622), (21.2767, 6.9038), (15.8354, 7.7384), (12.2782, 8.5124), (14.1328, 3.094), (13.0172, 5.3427), (6.142, 8.8211), (10.0813, 6.6157), (3.3493, 5.7322), (21.3673, 7.4722), (20.1307, 6.0763), (7.5549, 3.7626), (19.7895, 7.1817), (18.2458, 4.2232), (9.813, 8.98), (16.8825, 6.1145), (11.0023, 4.2364), (1.7753, 7.5734), (18.8806, 6.3514), (21.3775, 6.6705), (17.6417, 3.5668), (9.9087, 7.7778), (15.4598, 4.3442), (10.2685, 2.5916), (5.3326, 5.7223), (20.9335, 7.6275), (18.4588, 5.0092), (1.8198, 8.9529), (17.7508, 5.4564), (14.0024, 7.8497), (6.9789, 7.1984)]
Pour les obtenir, j'ai pris les coordonnées de la deuxième liste sur cette page et utilisé 0.4 * (125.0 - longitude)
pour notre coordonnée X et 0.4 * (latitude - 25.0)
pour notre coordonnée Y. Voici à quoi cela ressemble:
La première personne à utiliser la sortie de son code avec les coordonnées ci-dessus comme entrée pour créer un diagramme avec des carrés réels obtient une tape dans le dos!
(1, 2)
, non(1, 1)
.Réponses:
Mathematica, 473 octets
Avant de jouer au golf:
Explication :
Ce problème d'optimisation n'est pas difficile à décrire dans Mathematica. Étant donné une liste de points
p
de longueurn
,x[i]
ety[i]
:v=Array[{x[#],y[#]}&,n]
,f=Total[Norm/@(p-v)]
,c=Flatten[v]∈Integers&&And@@(Or@@Thread[#1!=#2]&@@@Subsets[v,{2}])
.Et,
NMinimize[{f,cons},v,MaxIterations->Infinity]
donnera le résultat. Mais malheureusement, un tel schéma simple semble trop compliqué pour converger.Pour contourner le problème de la complexité, deux techniques sont adoptées:
If[#1==#2,1*^4,0]&
est utilisée pour éviter la collision entre les points.Nous partons d'une supposition initiale en arrondissant les points. Lorsque les optimisations sont effectuées une par une, les collisions devraient être résolues et un arrangement optimisé est établi.
La solution finale est au moins bonne, sinon optimale. (Je crois
:P
)Résultat :
Le résultat de Just for fun est illustré ci-dessous. Les points vert foncé sont les entrées, les carrés gris les sorties et les lignes noires indiquent les déplacements.
La somme des déplacements est de 19,4595 . Et la solution est
la source
Python 3, 877 octets
Ce n'est pas une implémentation correcte. Il échoue sur le deuxième des "autres cas de test", produisant une solution avec une distance totale de 13,5325, où la solution fournie n'a besoin que de 13,2433. Ce qui complique encore les choses, c'est le fait que mon implémentation au golf ne correspond pas à celle que j'ai écrite en premier ...
Cependant, personne d'autre n'a répondu, et c'est un défi trop intéressant à laisser passer. De plus, j'ai une image générée à partir des données des États-Unis, alors voilà.
L'algorithme est quelque chose comme ceci:
Je n'ai absolument aucune preuve d'optimalité pour aucune partie de cet algorithme, juste une forte suspicion qu'il fournira de "très bons" résultats. Je pense que c'est ce que nous appelions un "algorithme heuristique" à l'époque de mon uni ...!
Et le résultat de l'exécuter sur les données des États-Unis (grâce à une fonction utilitaire qui transforme les résultats en SVG):
C'est légèrement pire que celui que le code non golfé a produit; la seule différence visible est que le carré en haut à droite est un plus à gauche dans le meilleur.
la source
MATLAB,
316 343326 octetsCelui-ci est un travail en cours - il n'est pas rapide, mais il est court. Il semble passer la plupart des cas de test. Actuellement, la carte juste pour le plaisir est en cours d'exécution, mais elle continue après 10 minutes, alors ...
Et dans un format un peu plus lisible:
Le format d'entrée devrait être un tableau MATLAB, tel que:
Ce qui est assez proche du format de la question, ce qui laisse une certaine latitude.
La sortie est au même format que l'entrée, un tableau où tout index donné correspond au même point à la fois en entrée et en sortie.
Hmm, 8 heures et toujours en cours d'exécution sur la carte ... cette solution est garantie de trouver la plus optimale, mais elle le fait via la force brute, donc prend très longtemps.
J'ai trouvé une autre solution qui est beaucoup plus rapide, mais comme l'autre réponse ne parvient pas à trouver la plus optimale dans l'un des cas de test. Fait intéressant, la carte que j'obtiens pour mon autre solution (non publiée) est présentée ci-dessous. Il atteint une distance totale de 20,72.
la source