2D 배열에서 모양 찾기 및 최적화


11

방금 이미지가 허용되었습니다 ... 게임에서 아래 이미지는 "T"모양의 일부로 인식 된 어두운 블록을 보여줍니다. 알 수 있듯이 코드는 빨간 점으로 블록을 어둡게하고 녹색 윤곽선으로 "T"모양을 보지 못했습니다.

원하는 패턴을 찾았지만 아직 최적화되지 않았습니다

내 코드는 x / y를 반복하고, 사용 된대로 블록을 표시하고, 모양을 회전하고, 반복하고, 색상을 변경하고, 반복합니다.

나는이 확인을 큰 떨림으로 고치기 시작했습니다. 현재 아이디어는 다음과 같습니다.

  • 그리드를 반복하고 모든 패턴 어커런스를 기록하고 (사용 된대로 마킹하지 않음)이를 어레이에 배치
  • 어떤 블록이 어떤 패턴에 의해 점유되는지, 따라서 어떤 패턴이 여러 패턴에 의해 점유되는지를 주목하면서, 그리드를 다시 루프한다.
  • 그리드를 다시 반복하면서 이번에는 어떤 패턴이 어떤 패턴을 방해하는지 주목

기분이 너무 좋아 ... 이제 어떻게해야합니까?

내가 해야 할 것 같아

  • 가장 다른 패턴을 먼저 방해하는 형태부터 시작하여 충돌하는 형태의 다양한 조합을 시도하십시오. 이것에 어떻게 접근합니까?
  • 8 개의 블록을 차지하는 3 개의 상충되는 모양이 있고 각 모양은 4 개의 블록이므로 최대 2 개의 모양 만 가질 수 있다는 합리적인 설명을 사용하십시오.

(나는 또한 다른 모양을 통합하려고하며 충돌하는 모양을 겪을 때 고려해야 할 점수 가중치가있을 것이지만 다른 날이 될 수 있습니다)

빈 포장 문제라고 생각하지 않지만 무엇을 찾아야할지 모르겠습니다. 이해가 되길 바랍니다. 도움을 주셔서 감사합니다.

편집 질문의 명확성에도 불구하고 모두가 이해 한 것 같습니다.

각 색상 내에서 최대 "T"모양을 찾고 싶습니다

(내가 당신에게 2 점을 주었고 당신이 3 점을 만들었다면, 당신은 약간 짜증날 것입니다)


탐욕스러운 알고리즘은 보드를 결합 된 블록 모음으로 분할하는 것입니다. 그런 다음 각 컬렉션에 대해 모양으로 채우기를 시도하고 어둡지 않은 블록의 양에 따라 채우기에 점수를 줄 수 있습니다. 내가 en.wikipedia.org/wiki/Knapsack_problem을 생각하게 만듭니다 .
Jonathan Connell

2
질문에 빠진 것이 있다고 생각합니다. "T"모양의 그룹을 가능한 많이 찾는 알고리즘을 만들고 싶습니까?
Markus von Broady

내가 당신을 이해한다면 당신은 올바른 길을 가고 있습니다. 당신은 매우 명확하지 않으며 당신이 정교하게 할 수 있다면 그것을 좋아할 것입니다.
AturSams

답변:


3

빨간색으로 표시된 블록이 파란색이고 알고리즘이 T 모양을 발견하고 빨간색으로 표시했는지 확인하겠습니다. 맞습니까? 귀하의 목표는 동일한 색상 블록으로 가능한 많은 T 모양을 찾는 것입니다. 현재는 일단 찾은 후에 표시하면 알고리즘의 유용성이 떨어집니다 (최적의 솔루션을 놓칠 수 있으므로). 모든 모양을 검색 한 다음 사용할 모양과 사용하지 않을 모양을 선택하려고합니다. 지금까지 내가 맞습니까? 알고리즘이 완료 될 때 T 모양 안에 포함 된 블록의 양을 최대화하려고합니다.

내가 맞다면 다음은 귀하의 상황에 맞는 최적의 솔루션입니다.

우리는 Integer Linear Programming을 사용할 것입니다.

나는 이것을 과거에 사용했다고 생각합니다.

http://sourceforge.net/projects/lpsolve/

http://lpsolve.sourceforge.net/5.5/Java/README.html

(여러 언어로 작동하도록 할 수 있습니다 .PHP, Java 및 C와 함께 사용했습니다)

우리가 할 일은 보드에 가능한 모든 T 모양을 등록한 다음 ILP를 사용하여 덮는 블록의 양을 최대화하는 것입니다. ILP는 기하 급수적으로 복잡합니다. 보드의 크기를 고려하면 문제가되지 않습니다. ILP가있는 그래프에서 훨씬 더 복잡한 최소 / 최대 질문을 실행했으며 수백 개의 정점으로 30 분에서 90 초까지 완료되었습니다 (귀하의 경우 1 초에 해당).

내가 추천하는 것 :

  1. 가능한 모든 선 모양 찾기
  2. 같은 색상의 선 모양 사이의 모든 교차점 찾기
  3. 모든 교차점을 검색하여 가능한 모든 T 모양을 찾으십시오.
  4. 각 T 모양에 대한 선형 문제에서 부울 변수 정의 ( 0 <= Bi <= 1) 값은 정수이므로 0 또는 1로 남습니다.
  5. 교차하는 T 모양의 각 쌍에 대한 조건을 만듭니다 ( Bi + Bj <= 1).
  6. 목적 함수는 다음과 같습니다 ( "T"모양의 블록 합계 (i) * Bi)
  7. 솔버를 실행하고 최적의 솔루션에서 솔버의 해당 부울이 1 인 T 모양을 어둡게합니다.

이것은 귀중한 지식입니다. 작업 프로젝트에 선형 솔버를 자주 사용했습니다.

ILP는 기본적으로 일부 선형 함수에 대해 최대 또는 최소를 달성하려는 선택 문제를 해결하는 방법입니다.

Integer를 사용하여 더 많은 것을 읽을 수 있습니다. 선형 프로그래밍 및 선형 프로그래밍은 프로그래머에게 동일하며 Integer는 컴퓨터에서 훨씬 더 복잡하여 실행 시간이 길어질 수 있습니다. 귀하의 경우가 아니라면 매우 간단하며 최악의 경우 밀리 초 미만이어야합니다.

나는 당신이 여기에서 더 많은 것을 읽을 수 있다고 생각합니다 :

http://en.wikipedia.org/wiki/Integer_linear_programming#Integer_unknowns

이것은 그것을 잘 설명합니다 :

http://fisher.osu.edu/~croxton_4/tutorial/

기본적으로 의사 결정 문제 해결사이며 원하는 결과를 최대화하는 의사 결정 방법입니다. 이것은 결과를 판단하는 기능이 특정 현재의 경우 선형이라고 가정합니다. 이 경우 결과를 판단하는 기능은 어둡게하기로 결정한 모든 T 모양의 블록을 요약합니다.

수학적으로 변수를 설정하는 방법 : 현재의 경우 부울 (인덱스 i로 T 모양을 어둡게 했습니까?)을 최적의 값으로 설정하여 원하는 결과를 최대화합니다. 교차하는 T 모양을 어둡게하지 않고 가능한 한 많은 블록을 어둡게합니다. 모든 변수를 설정했을 때 원하는 결과를 선형 함수로 계산할 수 있으면 해결됩니다. 이 경우 어둡게 한 T 모양을 확인하고 해당 블록을 합산합니다.

여기에 이미지 설명을 입력하십시오

나는 이것이 사소한 것이 아니라는 것을 알고 있습니다.


도와 주셔서 감사합니다. 다이제스트하는 데 몇 번의 읽기가 필요할 수 있습니다. 그리고 네, 당신은 문제를 올바르게 이해했습니다. 나는 당신이 정교해야한다면 매우 관심이있을 것입니다 (아니, 사소한 것이 아닙니다).
어셈블러

구현에 어떤 언어를 사용하고 있습니까?
AturSams

액션 스크립트 3! 모두가 좋아하는!
어셈블러

여기에서도 마찬가지입니다. 나는 as3로 구현을 작성하고 단계별로 작업하면서 주석이 달린 다운로드를 위해 github에 업로드 할 것입니다
AturSams

의견을 추가하거나 정교하게 설명 할 특정 영역이 1 ~ 7 있습니까? btw, AS3 애호가들에게 희소식, Adobe는 C ++를 지원하는 FlasCC를 출시하여 기존 선형 솔버를 쉽게 사용할 수 있습니다. :)
AturSams

4

그리드에서 발생하는 모든 (겹칠 수있는) T 자형 목록이 있으면 남은 것은 최대 세트 패킹 문제입니다.

일반적으로 이것은 NP- 완전 문제입니다. 그러나 그리드는 크기가 작아서 (일반적으로 더 작은 독립적 인 하위 문제로 분류 됨) 정확한 솔루션을 얻는 것이 가능할 수 있습니다.


부록 : 다음은 트릭을 수행 할 수있는 기본 역 추적 검색 알고리즘입니다.

function max_packing_recursive ( set A, set S, set M ):
    if |M| < |S| then let M = S;
    for each shape X in A do:
        remove X from A;
        let B = A;
        remove all shapes that intersect with X from B;
        if |M| < |B| + |S| + 1 then:        // upper bound
            let M = max_packing_recursive( B, S + {X}, M );
        end if
        if |M| >= |A| + |S| then return M;  // shortcut
    end for
    return M;
end function

function max_packing( set A ):
    return max_packing_recursive( A, {}, {} );
end function

여기서, {X, Y, Z}요소를 포함하는 세트이고 X, YZ(와 {}공집합 인), 및 |Q|세트의 크기를 나타낸다 Q.

재귀 함수에서 집합 A은 나머지 솔루션에 사용 가능한 S모양을 포함하고 현재 솔루션 후보의 모양을 포함하며 M지금까지 최대 솔루션입니다 (이를 다시 반환하는 대신 전역 변수로 저장하려고 할 수 있음) 콜 체인). 중요한 최적화는로 표시된 줄에 있으며 // upper bound,이 방법은보다 나은 솔루션을 반환 할 수없는 검색 트리 분기를 제거합니다 M.

(사실, 우리는 각각의 T 자형 정확히 네 개의 사이트를 포함 것을 알고 있기 때문에 더 나은 상단 대체함으로써 얻을 수 바인딩 |B|의 모양에 포함 별개의 사이트 수에 B대한 유사 네 가지로 나누어, 그리고 내림 (그리고 |A|온 라인으로 표시 // shortcut). 상기 알고리즘을 지정하지만, 임의의 형상의 컬렉션에 대해 작동한다.)

위에서 구현하지 않은 가능한 추가 최적화는 재귀 함수의 시작 부분 A에서 서로 다른 하위 집합의 모양이 겹치지 않는다는 의미에서 독립적 인 여러 하위 집합으로 나뉘 는지 여부를 확인 하는 것입니다. 알고리즘을 각 하위 집합에 개별적으로 할당합니다. (어쨌든 재귀 알고리즘을 호출 하기 전에 최상위 수준에서이 작업을 적어도 한 번 이상 수행하고 싶을 것 입니다.) A반복되는 모양의 수에 따라 순서를 반복하여 반복하기 전에 모양을 적절히 정렬하면 도움이 될 수 있습니다. .


그래, 나는 문제의 크기 때문에 ILP를 사용하여 상대적으로 고통없이 해결할 수 있다고 생각합니다. . 그것은 분명히 지수 적으로 복잡합니다 (적어도 누군가 p = np임을 증명할 때까지). 크기는 비교적 간단한 경우 휴리스틱을 피할 수 있습니다.
AturSams

일 마리, 대단히 감사합니다. 이 답변도 이해하는 데 몇 가지가 필요합니다. 임의의 모양 비트는 향후 반복에 유용 할 수 있습니다.
어셈블러
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.