Zaintrygował mnie projekt tej grafiki z „New York Timesa”, w którym każdy stan USA jest reprezentowany przez kwadrat w siatce. Zastanawiałem się, czy umieścili kwadraty ręcznie, czy rzeczywiście znaleźli optymalne rozmieszczenie kwadratów (pod pewną definicją), aby przedstawić pozycje sąsiednich stanów.
Twój kod podejmie niewielką część zadania polegającego na optymalnym umieszczeniu kwadratów do reprezentowania stanów (lub innych dowolnych dwuwymiarowych kształtów). W szczególności zakłada, że mamy już wszystkie geograficzne centra lub centroidy kształtów w wygodny format i że optymalna reprezentacja danych na takim schemacie to ta, w której całkowita odległość od centrów kształtów do środków kwadratów, które je reprezentują, jest minimalna, z co najwyżej jednym kwadratem na każdym możliwa pozycja.
Twój kod pobierze listę unikalnych par współrzędnych zmiennoprzecinkowych X i Y od 0,0 do 100,0 (włącznie) w dowolnym dogodnym formacie i wyświetli nieujemne liczby całkowite współrzędnych kwadratowych w siatce optymalnie umieszczonej do reprezentacji danych , zachowując porządek. W przypadkach, w których wielokrotne ułożenie kwadratów jest optymalne, możesz wyprowadzić dowolne z optymalnych ułożenia. Podanych zostanie od 1 do 100 par współrzędnych.
To jest kod golfowy, wygrywa najkrótszy kod.
Przykłady:
Wejście: [(0.0, 0.0), (1.0, 1.0), (0.0, 1.0), (1.0, 0.0)]
To jest proste. Środki kwadratów w naszej siatce wynoszą 0,0, 1,0, 2,0 itd., Więc te kształty są już idealnie umieszczone w środkach kwadratów w tym wzorze:
21
03
Zatem dane wyjściowe powinny mieć dokładnie te współrzędne, ale jako liczby całkowite, w wybranym formacie:
[(0, 0), (1, 1), (0, 1), (1, 0)]
Wejście: [(2.0, 2.1), (2.0, 2.2), (2.1, 2.0), (2.0, 1.9), (1.9, 2.0)]
W tym przypadku wszystkie kształty znajdują się blisko środka kwadratu w (2, 2), ale musimy je odepchnąć, ponieważ dwa kwadraty nie mogą znajdować się w tej samej pozycji. Minimalizacja odległości od środka ciężkości kształtu do reprezentującego go kwadratu daje nam następujący wzór:
1
402
3
Tak powinien wyglądać twój wynik [(2, 2), (2, 3), (3, 2), (2, 1), (1, 2)]
.
Przypadki testowe:
[(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)]
Całkowita odległość od środkowych kształtów do środków kwadratów, które je reprezentują w każdym przypadku (daj mi znać, jeśli zauważysz jakieś błędy!):
0.0
3.6
4.087011
13.243299
2.724791
1.144123
Dla żartu:
Oto reprezentacja centrów geograficznych przyległych Stanów Zjednoczonych w naszym formacie wejściowym, w przybliżeniu w skali stosowanej przez 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)]
Aby je uzyskać, wziąłem współrzędne z drugiej listy na tej stronie i użyłem 0.4 * (125.0 - longitude)
dla naszej współrzędnej X i 0.4 * (latitude - 25.0)
naszej współrzędnej Y. Oto, jak to wygląda na wykresie:
Pierwsza osoba, która użyje danych wyjściowych ze swojego kodu z powyższymi współrzędnymi jako danych wejściowych do stworzenia diagramu z rzeczywistymi kwadratami, zostanie poklepana po plecach!
(1, 2)
, nie(1, 1)
.Odpowiedzi:
Mathematica, 473 bajty
Przed golfem:
Objaśnienie :
Ten problem optymalizacji nie jest trudny do opisania w Mathematica. Biorąc pod uwagę listę punktów
p
długościn
,x[i]
iy[i]
:v=Array[{x[#],y[#]}&,n]
,f=Total[Norm/@(p-v)]
,c=Flatten[v]∈Integers&&And@@(Or@@Thread[#1!=#2]&@@@Subsets[v,{2}])
.I
NMinimize[{f,cons},v,MaxIterations->Infinity]
da wynik. Niestety taki prosty schemat wydaje się zbyt skomplikowany, aby można go było zjednoczyć.Aby obejść problem złożoności, przyjmuje się dwie techniki:
If[#1==#2,1*^4,0]&
służy do uniknięcia kolizji między punktami.Zaczynamy od wstępnego odgadnięcia, zaokrąglając punkty. Gdy optymalizacje są wykonywane jeden po drugim, oczekuje się, że kolizje zostaną rozwiązane, a zoptymalizowane ustawienie zostanie ustanowione.
Ostateczne rozwiązanie jest co najmniej dobre, jeśli nie optymalne. (Wierzę
:P
)Wynik :
Wynik Just for fun pokazano poniżej. Ciemnozielone punkty to dane wejściowe, szare kwadraty to dane wyjściowe, a czarne linie pokazują przemieszczenia.
Suma przesunięć wynosi 19,4595 . I rozwiązaniem jest
źródło
Python 3, 877 bajtów
To nie jest poprawna implementacja. Nie udaje się to w drugim z „dalszych przypadków testowych”, tworząc rozwiązanie o całkowitej odległości 13,5325, gdzie dostarczone rozwiązanie potrzebuje tylko 13,2433. Dalszą komplikacją jest fakt, że moja implementacja gry w golfa nie pasuje do tego, który napisałem pierwszy ...
Jednak nikt inny nie odpowiedział, a jest to zbyt interesujące wyzwanie, aby przejść obok niego. Mam też zdjęcie wygenerowane na podstawie danych z USA, więc o to chodzi.
Algorytm jest mniej więcej taki:
Nie mam absolutnie żadnego dowodu optymalności dla jakiejkolwiek części tego algorytmu, tylko silne podejrzenie, że zapewni on „całkiem dobre” wyniki. Myślę, że to właśnie nazywaliśmy „algorytmem heurystycznym” w moich czasach uniwersyteckich ...!
I wynik uruchomienia go na danych USA (dzięki funkcji narzędzia, która zamienia wyniki w SVG):
Jest to nieco gorsze niż ten, który stworzył nieoznakowany kod; jedyną widoczną różnicą jest to, że kwadrat w prawym górnym rogu znajduje się jeden dalej w lewo w lepszym.
źródło
MATLAB,
316 343326 bajtówTen jest w toku - nie jest szybki, ale jest krótki. Wydaje się, że zdaje większość testów. Obecnie działa mapa dla zabawy, ale nadal działa po 10 minutach, więc ...
I w nieco bardziej czytelnym formacie:
Format wejściowy ma być tablicą MATLAB, taką jak:
Który jest dość zbliżony do formatu w pytaniu, co pozwala na pewną swobodę.
Dane wyjściowe są w tym samym formacie co dane wejściowe, tablica, w której dowolny dany indeks odpowiada temu samemu punktowi zarówno na wejściu, jak i na wyjściu.
Hmm, 8 godzin i nadal działa na mapie jedna ... to rozwiązanie gwarantuje znalezienie najbardziej optymalnej, ale robi to z użyciem brutalnej siły, więc zajmuje to bardzo dużo czasu.
Wymyśliłem inne rozwiązanie, które jest znacznie szybsze, ale podobnie jak druga odpowiedź nie znajduje najbardziej optymalnego w jednym z przypadków testowych. Co ciekawe mapa, którą otrzymuję dla mojego innego rozwiązania (niepublikowana), jest pokazana poniżej. Osiąga łączny dystans 20,72.
źródło