Zobaczę, czy dobrze to zrozumiałem, czerwone bloki oznaczone są na niebiesko, a algorytm znalazł kształt litery T i oznaczył je na czerwono, czy to prawda? Twoim celem jest znalezienie jak największej liczby kształtów T z blokami tego samego koloru, mam nadzieję, że jak dotąd poprawisz. Obecnie zaznaczasz je po ich znalezieniu, co zmniejsza użyteczność algorytmu (ponieważ możesz nie mieć optymalnego rozwiązania). Planujesz wyszukać wszystkie kształty, a następnie wybrać, które z nich użyć, a które nie. Czy mam jak dotąd rację? Ponieważ chcesz zmaksymalizować liczbę bloków zawartych w kształtach T po zakończeniu algorytmu.
Jeśli mam rację, to moim zdaniem optymalne rozwiązanie dla Twojej sytuacji.
Wykorzystamy programowanie całkowite liniowe.
Myślę, że korzystałem z tego w przeszłości:
http://sourceforge.net/projects/lpsolve/
http://lpsolve.sourceforge.net/5.5/Java/README.html
(Możesz sprawić, żeby działał w wielu językach, użyłem go z PHP, Javą i C)
Będziemy rejestrować każdy możliwy kształt litery T na planszy, a następnie użyć ILP, aby zmaksymalizować liczbę bloków, które są pokryte. ILP jest wykładniczo złożona. Biorąc pod uwagę rozmiar planszy, nie będzie to problemem. Uruchomiłem o wiele bardziej skomplikowane pytania min./maks. Na wykresach z ILP i zajęło to ułamek sekundy do ukończenia i do 30-90 sekund z setkami wierzchołków (w twoim przypadku spada to ułamek sekundy).
Co poleciłbym zrobić:
- Znajdź wszystkie możliwe kształty linii
- Znajdź wszystkie przecięcia między kształtami linii tego samego koloru
- Znajdź wszystkie możliwe kształty T, przeszukując wszystkie skrzyżowania.
- Zdefiniuj zmienną boolowską w problemie liniowym dla każdego kształtu T (
0 <= Bi <= 1
) Ponieważ wartości są liczbami całkowitymi, pozostawia to 0 lub 1.
- Utwórz warunki dla każdej pary kształtów T przecinających się (
Bi + Bj <= 1
)
- Funkcja celu będzie (suma bloków w kształcie „T” (i) * Bi)
- Uruchom solver i przyciemnij kształty T, gdzie odpowiadające im logiczne wartości logiczne wynoszą 1 w optymalnym rozwiązaniu.
To cenna wiedza, często korzystałem z rozwiązań liniowych w projektach roboczych.
ILP jest w zasadzie sposobem rozwiązywania problemów z selekcją, w których chcesz osiągnąć maksimum lub minimum dla niektórych funkcji liniowych.
Możesz przeczytać więcej tutaj, używając Integer Programowanie liniowe, a programowanie liniowe jest takie samo dla programisty, tyle że Integer jest znacznie bardziej złożony dla komputera, co może skutkować długim czasem działania. Nie w twoim przypadku, jest to bardzo proste i w najgorszym przypadku powinno to zająć mniej niż milisekundy.
Myślę, że możesz przeczytać więcej tutaj:
http://en.wikipedia.org/wiki/Integer_linear_programming#Integer_unknowns
To dobrze to wyjaśnia:
http://fisher.osu.edu/~croxton_4/tutorial/
Jest to w zasadzie rozwiązanie problemu decyzyjnego, jak podejmować decyzje, które maksymalizują pożądany rezultat. Zakłada to, że funkcja, która ocenia wynik, jest liniowa, co w twoim konkretnym przypadku. Funkcja, która ocenia wynik w tym przypadku, sumuje bloki dla wszystkich kształtów T, które postanowiłeś przyciemnić.
Matematycznie, jak ustawić zmienne: w naszym obecnym przypadku wartości logiczne (czy przyciemniłem kształt T z indeksem i czy nie) do wartości optymalnych, aby zmaksymalizować pożądany wynik: przyciemnienie jak największej liczby bloków bez przyciemniania przecinających się kształtów T. Tak długo, jak pożądany wynik można obliczyć za pomocą funkcji liniowej, gdy masz ustawione wszystkie zmienne, rozwiąże to. W naszym przypadku sprawdzamy, które kształty T przyciemniliśmy i sumujemy bloki, które obejmują.
Wiem, że nie jest to trywialne, więc jeśli zdecydujesz się na skok, nie wahaj się komentować, a ja opracuję.