Biorąc pod uwagę listę punktów, znajdź najkrótszą ścieżkę, która odwiedza wszystkie punkty i wraca do punktu początkowego.
Problem komiwojażera jest dobrze znane w dziedzinie informatyki, jak wiele sposobów, aby obliczyć / przybliżają go. Zostało to rozwiązane dla bardzo dużych grup punktów, ale niektóre z największych wymagają wielu lat procesora.
Nie daj się spalić ziemniakowi.
Hot Potato to gra, w której ponad 2 graczy przesyła „ziemniaka” w kółko podczas odtwarzania muzyki. Celem jest szybkie przekazanie go następnemu graczowi. Jeśli trzymasz ziemniaka, gdy muzyka przestaje grać, jesteś poza domem.
Przedmiotem sprzedaży Hot Potato jest:
Biorąc pod uwagę zestaw 100 unikalnych punktów , zwróć te punkty w lepszej kolejności ( krótszy całkowity dystans zdefiniowany w dalszej części ). Spowoduje to „przekazanie” problemu do następnego gracza. Muszą go ulepszyć i przekazać do następnego itd. Jeśli gracz nie może go ulepszyć, nie ma go i gra trwa do momentu, aż opuści jednego gracza.
Aby nie był to konkurs „brutalna siła-mnie-a-ścieżka”, istnieją następujące warunki:
Przekazanie ziemniaka nie może zająć więcej niż minutę . Jeśli do końca minuty nie znalazłeś i nie przeszedłeś krótszego rozwiązania, jesteś poza domem.
Nie możesz zmienić pozycji o więcej niż 25 punktów. Aby być dokładnym,
>= 75
punkty muszą znajdować się w tej samej pozycji, w jakiej je otrzymałeś. Nie ma znaczenia, które z nich zdecydujesz się zmienić, wystarczy zmiana kwoty .
Gdy zostaje tylko jeden gracz, jest on zwycięzcą tej gry i otrzymuje jeden punkt. Turniej składa się z 5*n
gier, w których n
jest liczba graczy. W każdej grze gracz rozpoczynający zostanie obrócony , a kolejność pozostałych graczy zostanie potasowana . Gracz z największą liczbą punktów na końcu jest zwycięzcą turnieju. Jeśli turniej zakończy się remisem na pierwsze miejsce, nowy turniej zostanie rozegrany tylko z tymi uczestnikami. Będzie to trwało, dopóki nie będzie remisu.
Gracz rozpoczynający dla każdej gry otrzyma zestaw pseudolosowo wybranych punktów w dowolnej kolejności.
Punkty są zdefiniowane jako para x,y
współrzędnych całkowitych na siatce kartezjańskiej. Odległość jest mierzona za pomocą odległość Manhattan , |x1-x2| + |y1-y2|
. Wszystkie współrzędne będą w [0..199]
zakresie.
Wkład
Dane wejściowe są podawane z argumentem o pojedynczym ciągu. Będzie się składał z 201 liczb całkowitych oddzielonych przecinkami reprezentujących liczbę obecnych graczy ( m
) i 100 punktów:
m,x0,y0,x1,y1,x2,y2,...,x99,y99
Kolejność tych punktów jest bieżącą ścieżką. Całkowitą odległość uzyskuje się przez dodanie odległości od każdego punktu do następnego ( dist(0,1) + dist(1,2) + ... + dist(99,0)
). Nie zapomnij powrócić, aby rozpocząć obliczanie całkowitego dystansu!
Pamiętaj, że niem
jest to liczba graczy, którzy rozpoczęli grę, to liczba, która wciąż jest w grze.
Wydajność
Dane wyjściowe są podawane w taki sam sposób jak dane wejściowe, minus m
; pojedynczy ciąg zawierający liczby całkowite oddzielone przecinkami reprezentujące punkty w ich nowej kolejności.
x0,y0,x1,y1,x2,y2,...,x99,y99
Program sterujący będzie czekał na wyjście tylko przez jedną minutę. Po otrzymaniu danych wyjściowych sprawdzi, czy:
- wynik jest dobrze uformowany
- wyjście składa się tylko ze wszystkich 100 punktów obecnych na wejściu
>=75
punkty znajdują się w swoich pierwotnych pozycjach- długość ścieżki jest mniejsza niż poprzednia ścieżka
Jeśli którykolwiek z tych testów zakończy się niepowodzeniem (lub nie ma danych wyjściowych), gra się kończy, a gra przejdzie do następnego gracza.
Program kontroli
Program sterujący można znaleźć pod tym linkiem . Sam program sterujący jest deterministyczny i jest wysyłany z nasieniem fikcyjnym 1
. Ziarno użyte podczas oceniania będzie inne, więc nie zawracaj sobie głowy analizowaniem wyrzucanych przez ciebie kolejności / punktów zwrotów.
Główną klasą jest Tourney
. Uruchomienie tego spowoduje pełny turniej z uczestnikami podanymi jako argumenty. Wyrzuca zwycięzcę każdej gry i podsumowanie na końcu. Przykładowy turniej z dwoma SwapBotami wygląda następująco:
Starting tournament with seed 1
(0) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 1
(1) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 3
(0) SwapBot wins a game! Current score: 2
(1) SwapBot wins a game! Current score: 4
(1) SwapBot wins a game! Current score: 5
(1) SwapBot wins a game! Current score: 6
(1) SwapBot wins a game! Current score: 7
(1) SwapBot wins a game! Current score: 8
Final Results:
Wins Contestant
2 (0) SwapBot
8 (1) SwapBot
Jeśli chcesz przetestować tylko jedną grę na raz, możesz Game
zamiast tego uruchomić klasę. To uruchomi jedną grę z graczami w kolejności podanej jako argument. Domyślnie wydrukuje również play-by-play pokazujący aktualny odtwarzacz i długość ścieżki.
Również kilka testów gracze: SwapBot
, BlockPermuter
, i TwoSwapBot
. Pierwsze dwa nie zostaną uwzględnione w biegach punktacji, więc możesz ich używać i nadużywać podczas testowania. TwoSwapBot
zostanie uwzględniony w ocenie, a on nie jest garbaty, więc weź swoją grę A.
Zbieranina
Nie możesz zapisać informacji o stanie, a każda kolej to osobne uruchomienie programu. Jedyną informacją, którą otrzymasz w każdej turze, jest zestaw punktów.
Nie możesz korzystać z zasobów zewnętrznych. Obejmuje to połączenia sieciowe i dostęp do plików.
Nie można używać funkcji bibliotecznych zaprojektowanych do rozwiązania / pomocy w przypadku problemu TSP lub jego wariantów.
Nie możesz w żaden sposób manipulować lub ingerować w innych graczy.
Nie można w żaden sposób manipulować ani ingerować w program sterujący ani zawarte w nim klasy lub pliki.
Wielowątkowość jest dozwolona.
Jedno zgłoszenie na użytkownika. Jeśli prześlesz więcej niż jeden wpis, wprowadzę tylko pierwszy przesłany. Jeśli chcesz zmienić swoje zgłoszenie, edytuj / usuń oryginał.
Turniej odbędzie się na Ubuntu 13.04, na komputerze z procesorem i7-3770K i 16 GB pamięci RAM. Nie będzie działać na maszynie wirtualnej. Wszystko, co uznam za szkodliwe, natychmiast zdyskwalifikuje bieżące i wszelkie przyszłe wpisy, które prześlesz.
Wszystkie wpisy muszą być uruchamiane z wiersza poleceń za pomocą bezpłatnego ( jak w przypadku piwa ) oprogramowania. Jeśli mam problemy ze skompilowaniem / uruchomieniem twojego wpisu, poproszę o pomoc w komentarzach. Jeśli nie odpowiesz lub nie uda mi się go uruchomić, zostanie zdyskwalifikowany.
Wyniki (22 maja 2014 r.)
Nowe wyniki już są! UntangleBot dość mocno pokonał konkurencję. TwoSwapBot odniósł siedem zwycięstw, a SANNbot również odniósł zwycięstwo. Oto tablica wyników i link do surowego wyniku :
Wins Contestant
22 (2) ./UntangleBot
7 (0) TwoSwapBot
1 (5) SANNbot.R
0 (1) BozoBot
0 (3) Threader
0 (4) DivideAndConquer
Jak stoi teraz , UntangleBot zdobył zaznaczenie. Nie zniechęcaj cię jednak do wzięcia udziału w turnieju, ponieważ poprowadzę turniej, gdy pojawi się więcej uczestników i odpowiednio zmienię przyjętą odpowiedź.
źródło
Odpowiedzi:
UntangleBot (wcześniej NiceBot)
Bot C ++ 11 korzystający z dwóch strategii.
Najpierw spróbuje „rozplątać” ścieżkę, jeśli to możliwe, wykrywając przecięcia między ścieżkami, które są bliżej niż 25 punktów (ponieważ rozplątywanie oznacza modyfikację wszystkich punktów pomiędzy).
Jeśli pierwsza strategia zawiedzie, losowo zamienia punkty, aby znaleźć lepsze odległości, dopóki nie zostanie znaleziona lepsza ścieżka.
Ten bot konsekwentnie bije TwoSwapBot o przybliżonym stosunku pięciu zwycięstw za jedną stratę w moich testowych turniejach.
źródło
SANNbot
(symulowany bot wyżarzający w R )
Powinny być wywoływane z
Rscript SANNbot.R
.Pomysł jest stosunkowo prosty: każda tura to jeden „etap chłodzenia” symulowanego wyżarzania z liczbą graczy wciąż obecnych w grze jako „temperatura” (modyfikowana aktualną odległością ponad 12000, tj. Mniej więcej odległością początkową). Jedyną różnicą przy odpowiednim symulowanym wyżarzaniu jest to, że sprawdziłem, czy nie permutuję więcej niż 25 elementów i jeśli wykorzystałem 20 ruchów, ale wynikowa sekwencja jest warta niż początkowa, to zaczyna się od nowa.
źródło
java Tourney "java Swapbot" "Rscript SANNbot.R"
i wydawało się, że działa.u
limity czeków, tak się nie dzieje (i działa znacznie lepiej). Chociaż twój kod wydaje się dość prosty, nie znam dziwactw R, więc nie mogę powiedzieć, czy logika jest zła. (najnowsza wersja kontrolera wyświetli komunikat o tym, dlaczego botGame
BozoBot
Wykorzystuje złożoną logikę stojącą za Bozosort, aby znaleźć lepszą ścieżkę. To wygląda tak.
BozoBot został teraz ulepszony dzięki wielowątkowości ! Cztery stwory bezcelowo żonglują punktami, dopóki nie natkną się na ulepszenie. Pierwszy, który znajdzie rozwiązanie, otrzymuje plik cookie!Najwyraźniej nie potrafię wielowątkowości.
źródło
new Thread(new Minion()).start()
TwoSwapBot
Ulepszenie
SwapBot
tego faceta sprawdza każdą parę zamian. Najpierw sprawdza, czy jakakolwiek pojedyncza zamiana skróci ścieżkę. Jeśli tak, natychmiast wraca. Jeśli nie, sprawdza każdą z nich, aby sprawdzić, czy kolejna zamiana ją skróci. Jeśli nie, po prostu umiera.Chociaż ścieżka jest nadal w połowie losowa, zwykle powraca po około 100 ms. Jeśli będzie musiał sprawdzać każde 2-zamiany (około 25 mln), zajmuje to około 20 sekund.
W momencie zgłoszenia pokonało to wszystkich innych zawodników w rundach testowych.
źródło
Gwintownica
Ten bot
410 części po2510 punktówChodzi o to, aby znaleźć najlepszą poprawę ścieżki, tak aby inne boty zawiodły swoją logiką.
źródło
println
abyprint
pozbyć się nowej linii na końcu twoich wyników. W przeciwnym razie ulega awarii.println
naprint
i zdynamizowano liczenie wątków. Teraz zaczyna się od 10 wątków ...Divide And Conquer + Greedy Bot
UWAGA: Przejrzałem twój kod,
Game
który zawiera następujące elementy w Game.parsePath:Jednak nie ma żadnego
catch(NumberFormatException)
bloku, więc twój program najprawdopodobniej ulegnie awarii, gdy program odtwarzający wyświetli ciąg znaków (jak pokazano na końcu metody mojego programumain
). Radzę to naprawić, ponieważ programy mogą wyświetlać wyjątki, ślady stosu itp. W przeciwnym razie skomentuj ten wiersz w moim programie, zanim go uruchomisz.Powrót do tematu
Ta implementacja (w Javie) dzieli listę punktów na kawałki po 25, losowo rozmieszczone na liście. Następnie tworzy wątki, aby skrócić ścieżkę między punktami w każdej części (stąd „Dziel i rządź”). Główny wątek monitoruje pozostałe i zapewnia przedstawienie najkrótszego rozwiązania w wyznaczonym terminie. Jeśli wątek umiera z rozwiązaniem lub bez niego, rozpoczyna kolejny wątek na innym fragmencie.
Każdy wątek wykorzystuje algorytm „chciwy”, który rozpoczyna się od losowego punktu, przechodzi do najbliższego punktu i powtarza, aż wszystkie punkty zostaną pokryte (stąd „chciwy”).
Notatki
Wystarczy skompilować i użyć,
java DivideAndConquer.class
aby uruchomić.źródło
<200
tokeny, zanim spróbuje parsować. Mimo to lepiej to sprawdzić.)
wiersz 19; zmianasubstr
nasubstring
na 38; zainicjowaćidx
na coś wrun()
metodzie.