Raz-dwa
Jeśli chodzi o stopień złożoności, zadania matematyczno-rozrywkowe można z grubsza podzielić, jak problemy obliczeniowe, na dwa rodzaje: jedne rozwiązuje się głową, drugie komputerem (pomijam to, że głowa potrzebna jest do napisania programu). Podział jest nieostry, bo – przynajmniej teoretycznie – z wieloma zadaniami można uporać się i tak, i tak. Wszystko zależy od tego, czy komuś starczy chęci, cierpliwości i ambicji, aby pokonać przeszkodę „na piechotę”, czy też dojdzie do wniosku, że gra jest niewarta świeczki i lepiej zatrudnić sztuczny mózg. Są też oczywiście takie zadania, o których z góry można powiedzieć, że komputer ich nie ruszy, a człowiek da sobie radę albo takie, o których od razu wiadomo, że zabierać się do nich nie ma sensu bez komputerowego wsparcia. Te drugie pojawiają się na stronach z wyzwaniami dla programistów – najciekawszą jest zapewne Project Euler.
Tak sobie mędrkuję w związku z dwoma zadaniami.
Jednym jest to zamieszczone w poprzednim wpisie – ni takie, ni siakie, bo z jednej strony szukanie maksa na piechotę wydaje się ciekawe, ale nie ma pewności, że cel się osiągnie, więc kuszące jest napisanie programu; z drugiej strony, gdyby maks był podany, to do odpowiadającego mu rozmieszczenia cyfr w diagramie nie tak trudno byłoby dotrzeć – praktycznie wystarczy pół godziny dłubaniny.
Drugie zadanie, które pochopnie zamieściłem w październikowym Świecie Nauki, jest – wbrew pozorom – nie do ruszenia na piechotę. Nawet napisanie programu nie wydaje się proste, ale tu mogę się mylić, bo nie jestem mocny w te klocki. Przedstawię w skrócie w czym rzecz.
Oto rzadka linijka optymalna „raz-dwa” k|d dla k=1 i d=8:
k=1 ponieważ jest na niej tylko jedna kreska (dlatego też jest rzadka); d=8 ponieważ można nią odmierzyć każdą całkowitą liczbę centymetrów od 1 do 8 cm (zakładając, że 1 cm stanowi na niej jednostkę, czyli cała ma długość 4 cm), przykładając linijkę w czasie pomiaru jedno– lub dwukrotnie (dlatego jest „raz-dwa„). Na przykład:
2 cm – przykładamy dwukrotnie odcinek 0_1;
3 cm – przykładamy 1_4;
7 cm – 0_4 i 1_4.
Linijka jest optymalna, ponieważ z jednej strony 8 jest największym d, gdy kreska jest tylko jedna, a z drugiej dla d=8 kresek nie może być mniej.
Wspomniane zadanie w Świecie nauki polegało na skonstruowaniu rzadkiej linijki minimalnej „raz-dwa” 4|d – takiej, aby d było jak największe. Inaczej mówiąc, na linijce powinny znaleźć się cztery kreski podziałki umieszczone w takich miejscach, aby można nią było odmierzyć każdą całkowitą liczbę centymetrów od 1 do maksymalnego d, przykładając linijkę raz lub dwa razy.
Bardziej abstrakcyjnie zadanie można sformułować tak:
Wybieramy pięć liczb całkowitych dodatnich i uzupełniamy ten zbiór dziesięcioma liczbami – dodatnimi różnicami między każdą parą wybranych liczb. W ten sposób tworzymy zbiór A złożony z piętnastu liczb. Jakie pięć liczb należałoby wybrać na początku, aby dodając parami liczby ze zbioru A (w grę wchodzą także dwukrotności każdej z nich), można było utworzyć każdą liczbę całkowitą od 1 do największego możliwego d.
Osobom, które, jak ja, nie są mocne w programowaniu, proponuję utworzyć na piechotę linijkę „raz-dwa” o dwa oczka mniejszą, czyli 2|d z największym d. Nawet wówczas zadanie nie jest proste.
Komentarze
Czy można odmierzyć odległość będącą różnicą odległości?
Aby doprecyzować pytanie podam przykład:
Mamy linijkę o długości 5 z kreską przy 1 (o jedną jednostkę dłuższą, niż w treści zadania). Czy za jej pomocą możemy odmierzyć długość 3 jako różnicę odcinków 1_5 oraz 0_1?
Pytam, bowiem z oryginalnej treści zadania wnioskuje, że tak można, natomiast z wersji abstrakcyjnej wynika, że nie można.
Sprytne, ale nie – uwzględniamy tylko sumowanie dwóch dystansów na linijce. Praktycznie wygląda to tak, że zaznaczamy kreskę na mierzonym przedmiocie po odłożeniu jednego dystansu i od niej odkładamy drugi dystans. Gdybyśmy dopuścili różnice, to kreska wypadłaby poza przedmiotem.
Z drugiej jednak strony można by się zastanowić i nad takim sumowo-różnicowym wariantem linijki, ale to w ramach odrębnego zadania. Temat podpada pod addytywną teorię liczb.
mp
k=2 to d = 16
Kreski na linijce w pozycjach: 1, 4, 10 (kolejne odstępy: 1,3,6)
To potwierdza moje przypuszczenie, że nawet dla 2 kresek zadanie na piechotę nie jest proste.
mp
k=2 to d = 18
Kreski na linijce w pozycjach: 1, 6, 9 (kolejne odstępy: 1,5,3)
Jak się patrzy na rozwiązanie, to nie powinno być trudno na nie wpaść, zwłaszcza jeżeli się wie, że d=16 nie jest poprawną odpowiedzią… czyli linijka ma długość co najmniej 9.
Kłopot może sprawić określenie najdłuższej możliwej linijki, mi wychodzi, że na pewno nie może być dłuższa niż 1+3 + 9 = 13.
gdzie 9 = 2(1+3)+1.
W rozwiązaniu na piechotę wypadałoby więc sprawdzić linijki o długości od 9 do 13, wiedząc, że jeden z odcinków elementarnych ma długość 1, a drugi co najwyżej 3.
Dla 9 daje to odcinki elementarne 1,2,6 lub 1,3,5 +- nie wszystkie permutacje (linijkę można obrócić),
dla długości 10-13 podobnie, więc da się to rozgryźć ręcznie w skończonym czasie.
18 jest oczywiście OK. Uwalniam wcześniej, bo ciekawe jest uzupełnienie tematu „najdłuższą możliwą linijką”.
mp
k=3 to d = 37:
długość linijki: 20
pozycje kresek: 3 4 15
odstępy elementarne: 3,1,11,5
k=4 to d = 68:
długość linijki: 34
pozycje kresek: 1 3 21 30
odstępy elementarne: 1,2,18,9,4
Ja mam odcinki o długościach 1, 5 i 3 (w tej kolejności), czyli kreski na 1 i 6, bądź równoważnie 3 i 8, długość linijki l=9. W tej sytuacji d=18=2*l, twierdzę, że jest to najlepsze rozwiązanie, gdy możemy zmierzyć wszystko aż do maxa, czyli 2*l. W warunkach zadania nie podano jednak, że d musi być równe 2*l, choć niewątpliwie tak byłoby najszlachetniej, wszak 2*l z definicji daje się zmierzyć naszą linijką, zostaną więc dziury tak jak 17 w przykładzie cpp z godz. 14.43.
Z komputerem nie jest trudno: 4|68 – Można pomierzyć do: 68 linijką o długości 34 z podziałką:
[1, 3, 21, 30]
Przy okazji mam też linijkę 3|37 o długości 20.
Pozdrawiam (i dziękuje za link do strony ProjectEuler)
Tomasz
k=2, d=19
kreski na linijce długości 12 na pozycjach: 1, 5 (długości: 1, 4, 7)
Przykładowo dł=3 tworzymy odmierzając dł=4 a następnie skracając ją o odmierzoną dł=1. Jest to dopuszczalne?
Podsumowanie
Poniżej Połowa rozwiązania dla k=2,3,…,6; drugą połowę można uzyskać przez odbicie lustrzane.
Kolejno: wartość d, dwukropek, położenia kresek, długość linijki
k = 2
18 : 2 3 10
18 : 1 6 9
k = 3
37 : 3 4 15 20
k = 4
68 : 1 8 10 31 34
68 : 1 3 21 30 34
68 : 7 30 31 33 41
68 : 7 30 32 33 42
68 : 1 21 25 31 34
68 : 7 29 32 33 41
k = 5
116 : 1 14 16 49 55 58
k = 6
180 : 13 39 82 86 88 89 104
Złożoność obliczeniowa rośnie makabrycznie szybko, dla k = 4,5,6 obliczenia zajęły odpowiednio 0.04 s, 8.8 s oraz 1 godz. 27 s
Dla k=6 nie znałem, komputer był za słaby i nie wyrabiał (dwa dni bezskutecznego liczenia).
mp
Ojj, późno już było. Widzę, ze Miodziu już o to pytał.
Zamiana laptopa na komputer „obliczeniowy” w moim przypadku przyspieszyła program ok. 6 razy. Poza tym o ile w pierwszej wersji programu szukałem k kresek, w drugiej szukałem k + 1 „segmentów elementarnych” pomiędzy sąsiednimi kreskami, a potem sprawdzałem ich permutacje. Generowałem tylko monotoniczne (niemalejące) ciągi segmentów – stąd potrzeba permutacji. Część kombinacji segmentów można wyeliminować na podstawie odpowiadającej im wartości długości linijki oraz na podstawie sumy segmentów na pozycji mniejszej od danego segmentu. Spośród permutacji eliminowałem połowę, o której wiedziałem, że ma odpowiednik „lustrzany”, stąd tylko połowa wyników.
Długość n-tego segmentu jest ograniczona z góry przez min(3^n, 2 + (k+1)(k+2)).
PS. Znalazłem coś podobnego:
Golomb ruler (http://en.wikipedia.org/wiki/Golomb_ruler) z przykładami zastosowań.
Dodatkowo warto poszukać: sparse ruler i perfect ruler. Nie znalazłem linijek raz-dwa, ciekawe też byłoby sprawdzenie linijek raz-dwa-trzy 🙂
Pozdrawiam
/Tomasz
O sparse i perfect było właśnie w październikowym ŚN, o linijkach Golomba też kiedyś pisałem. Te tematy są zresztą dość znane i pojawiają się w różnych popularnych publikacjach. Linijki raz-dwa to mój pomysł, więc byłbym mile 🙁 zaskoczony, gdyby okazało się, że ktoś nań wcześniej wpadł.
mp
Bardzo dobrze się stało, że zadanie zostało zamieszczone w „Świecie Nauki”, a jeszcze lepiej, że ma ono swój ciąg dalszy w Łamiblogu.
Ciekawi mnie, dlaczego (wg autora?) jest ono nie do ruszenia na piechotę? Czyżby istniał na to dowód?
Silnego dowodu nie ma, ale są silne poszlaki – nikt bez komputera (prawie 60 osób) go nie rozwiązał, najlepszy wynik to 55.
Oczywiście trudno wykluczyć, że przy dostatecznie silnym bodźcu „liczydła” by wystarczyły.
mp
Rozumiem że „kreski podziałki” to kreski stawiane wewnątrz linijki. Innymi słowy krańców linijki nie liczymy jako kreski.
Jeśli to co napisałem wyżej jest poprawne to czemu rozwiązania cpp nie zostały oprotestowane ? (k=2 i kreski w trzech pozycjach zamiast dwóch). O co chodzi ???
„Trzecia kreska” to koniec linijki (małe uchybienie formalne, ale nietrudno się domyślić w czym rzecz).
mp
k=2, d=18, długość linijki 10, kreski przy odległościach 0,2,3,10 (odstepy 2,1,7)
„Są silne poszlaki, że mocnego dowodu nie ma” – zabrzmiało to tak jakbyśmy chcieli usprawiedliwić własną słabość umysłową.
Kiedy rozwiązywałem (zgadywałem) to zadanie zamieszczone w „Umyśle giętkim”, to potraktowałem je na zasadzie – jak daleko (metodą próbowania, zgadywania) jestem w stanie dojść. Wynik jaki uzyskałem, to 62 (0, 2, 18, 25, 30, 31) i w pewnym sensie, ani o krok nie przybliżyło mnie to do rozwiązania zadania, bo nie mogło. Po prostu rozwiązywałem inne zadanie, niż to zamieszczone w ŚN, gdzie trzeba było znaleźć (udowodnić) maksymalne d, a nie d do którego jest się w stanie dojść.
Dlatego dobrze, że zadanie znalazło swoją kontynuację na Łamiblogu i zobaczę jak powinno zostać ono rozwiązane (mam nadzieję, że nie będą to rozwiązania „komputerowe”, ale tzw. „normalne”).
Sam się skarciłem za to zadanie i reprymendę podtrzymuję, ponieważ „normalna” metoda jego rozwiązywania straszną dłubaniną (próby i błędy). Gdybym je zamieścił na Project Euler to bym się nie karcił.
mp
Dając kolejne odległości: 1, 3, 8, 10, 17 można odmierzyć wszystkie odległości od 1 do 57.
Metoda półautomatyczna, tzn próbkowanie liczb i ich kolejność ustalane ręczne, natomiast wszystkie sumy i sprawdzenie czy wynik jest w zakresie od 1 do 100 robi excel.
Lekka modyfikacja: 3,1,9,15,17 i już mamy wszystkie sumy od 1 do 60
@Miodziu rozwiązał pozytywnie problem, który mi świtał, czyli czy da się zrobić dla k=2 i d=18 linijkę raz-dwa niedoskonałą (spocząłem na laurach po uzyskaniu doskonałej 1, 5, 3 – długości odcinków). Oczywiście linijki doskonałej dla k=2 nie da się zrobić, gdy odcinek = 1 jest w środku, to chyba elementarne.
Tak też podejrzewałem ale musiałem się upewnić 🙂
Dla k=2 są jeszcze dwie możliwości, dające d=18, aczkolwiek „dualne” do tych, które podali cpp i miodziu: (3,8,9) i (7,8,10). Dlaczego dualne? Bo prowadzą do tych samych szóstek liczb.
Dla k=4 najlepszy wynik to d=68. Znalazłem (tzn. komputer znalazł) 12 układów kresek:
1,3,21,30,34
1,8,10,31,34
1,21,25,31,34
3,9,13,33,34
3,24,26,33,34
4,13,31,33,34
7,29,32,33,41
7,30,31,33,41
7,30,32,33,42
8,9,12,34,41
8,10,11,34,41
9,10,12,35,42
2|18 (przykładowe odstępy: 7, 1, 2)
4|68 (przykładowe odstępy: 4, 9, 18, 2, 1)
Jeśli dopuścić odejmowanie, to:
2|24 (przykładowe odstępy: 3, 8, 1)
Ręcznie udało mi się znaleźć d=55, co nie jest rozwiązaniem najlepszym.
Komputerowo sprawdziłem wszystkie linijki o długości mniejszej niż 100 (wydaje się, że dla większych linijek lepszego rozwiązania nie uda się znaleźć), znajdując rozwiązanie d=68. Co ciekawe, istnieje 6 różnych linijek, dla których da się osiągnąć ten wynik (+ sześć układów dualnych, otrzymanych z poniższych przez odwrócenie kolejności przedziałów na linijce). n oznacza długość linijki, kolejne liczby oznaczają miejsca na linijce, w których powinny znaleźć się linie, w nawiasie podane są odległości pomiędzy kolejnymi zaznaczonymi na linijce liniami:
n=34: 0 1 3 21 30 34 (1,2,18,9,4)
n=34: 0 1 8 10 31 34 (1,7,2,21,3)
n=34: 0 1 21 25 31 34 (1,20,4,6,3)
n=41: 0 7 29 32 33 41 (7,22,3,1,8)
n=41: 0 7 30 31 33 41 (7,23,1,2,8)
n=42: 0 7 30 32 33 42 (7,23,2,1,9)
Dla zainteresowanych zamieszczam kod źródłowy programu, którym obliczyłem powyższe:
http://www.gg.pl/dysk/rycE5AEF88JQricE5AEF4-s/raz-dwa.zip
Dla k=4 osiągalne jest d=68. Wykryłem (tj. komputer) 12 wariantów, w tym 6 krótkich:
1, 3, 21, 30, 34
1, 8, 10, 31, 34
1, 21, 25, 31, 34
3, 9, 13, 33, 34
3, 24, 26, 33, 34
4, 13, 31, 33, 34
i 6 dłuższych:
7, 29, 32, 33, 41
7, 30, 31, 33, 41
7, 30, 32, 33, 42
8, 9, 12, 34, 41
8, 10, 11, 34, 41
9, 10, 12, 35, 42
Są dwie linijki dla k=4 dające d=68. Obie mają długość 34.
kreski: 0 1 3 21 30 34
odstępy: 1 2 18 9 4
kreski: 0 1 8 10 31 34
odstępy: 1 7 2 21 3
Jednocześnie linijki dłuższe niż 34 nie dają już d=68.
Pozwoliłem sobie uruchomić program dla k=5 oraz k=6, otrzymując następujące wyniki:
k=5, d=116, n=58: 0 1 14 16 49 55 58 (1 13 2 33 6 3)
k=6, d=174, n=87: 0 1 13 15 46 78 84 87 (1 12 2 31 32 6 3)
Niestety w obu przypadkach nie mam gwarancji, że są to najlepsze rozwiązania, bowiem program działał zbyt długo 🙁
4|63
kolejne długości to: 3, 1, 15, 11, 9
nadal szukane ręcznie, chciałem dzisiaj napisać program, ale obowiązki w pracy nie pozwoliły :/
Udało mi się określić liczbę, która jest równa lub większa od d. Wzory umieściłem tutaj: http://pokazywarka.pl/djun9n/.
R – liczba odcinków możliwych do odmierzenia ‚na raz’.
D – liczba odcinków możliwych do odmierzenia ‚na raz-dwa’.
Tam gdzie będę pisał słowo ‚odcinek’, chodzi dosłownie o ‚odcinek możliwy do odmierzenia ‚na raz”.
W skrócie rzecz ujmując: D = I – II – III + IV
I – Liczba par odcinków.
II – Liczba takich par odcinków, których suma jest zawsze równa jednemu (innemu) odcinkowi. Liczbę tą należy odjąć od I, by sumy tych par odcinków nie powielały się z pojedynczymi odcinkami.
III – Liczba takich par odcinków, których częścią wspólną jest inny odcinek. Tą liczbę także należy odjąć od I, ponieważ suma pary odcinków posiadających wspólny (krótszy) odcinek jest równa sumie pary odcinków, w której jeden (krótszy) jest tym wyżej wspomnianym odcinkiem wspólnym a drugi (dłuższy) rozciąga się między krańcowymi punktami odcinków wchodzących w skład ww. pary odcinków posiadających wspólny odcinek.
IV – Liczba odcinków możliwych do odmierzenia ‚na raz’.
Tak określona liczba D jest większa lub równa d. Dla k=1, D=8 i D=d (ciekawe czy istnieją inne k dla których D=d). Czyli możemy szukać linijek, które odmierzą aż D różnych długości. Nie jest jednak powiedziane, że te D różnych długości da się przedstawić po kolei co jeden od 1 do D.
No, no, poważna sprawa. Przyjrzę się bliżej w wolnej chwili.
mp