2012-02-16 4 views
3

두 문단의 열로 된 텍스트 단락이 있습니다. 내 임무의 목적은 그것을 해독하는 것입니다두 개의 char 열의 텍스트 스크램블을 해결하기위한 접근 방법

|de| | f|Cl|nf|ed|au| i|ti| |ma|ha|or|nn|ou| S|on|nd|on| 
|ry| |is|th|is| b|eo|as| | |f |wh| o|ic| t|, | |he|h | 
|ab| |la|pr|od|ge|ob| m|an| |s |is|el|ti|ng|il|d |ua|c | 
|he| |ea|of|ho| m| t|et|ha| | t|od|ds|e |ki| c|t |ng|br| 
|wo|m,|to|yo|hi|ve|u | t|ob| |pr|d |s |us| s|ul|le|ol|e | 
| t|ca| t|wi| M|d |th|"A|ma|l |he| p|at|ap|it|he|ti|le|er| 
|ry|d |un|Th|" |io|eo|n,|is| |bl|f |pu|Co|ic| o|he|at|mm| 
|hi| | |in| | | t| | | | |ye| |ar| |s | | |. | 

내 현재의 접근 방식은 컬럼의 올바른 순서가 반복적으로 단어 발생 횟수 기준에 따라 각 컬럼의 최적의 위치를 ​​찾기 위해 노력하고있다 찾을 수 있습니다.

내가 생각하고있는 알고리즘의 핵심의 의사 코드는 다음과 같습니다

function unscramble(scrambledMatrix,indexOfColumnIveJustMoved) 
    for each column on scrambledMatrix as currentIndex=>currentColumn 
     if (currentIndex!=indexOfColumnIveJustMoved) 
      maxRepeatedWords=0;maxIndex=0; 
      for (i=0;i<numberOfColumnsOfScrambledMatrix;i++) 
       repWordsCount=countRepWords(moveFromToOn(currentIndex,i,scrambledMatrix)) 
       if (maxRepeatedWords<repWordsCount) 
        maxRepeatedWords=repWordsCount; 
        maxIndex=i; 
       endif 
      endfor 
      if (maxIndex!=currentIndex) 
       return unscramble(moveFromToOn(currentIndex,maxIndex,scrambledMatrix),maxIndex); //recursive call 
      endif 
     endif 
    endfor 
    return(scrambledMatrix); //returns the unscrambled matrix; 
endfunction 

알고리즘은 더 열이 각 하나를 반복 한 후 이동하지 않을 경우 중단됩니다. 글자가 글자로 된 단어를 기반으로하고 표본이 충분히 크면 모든 언어 (영어에 대한 솔루션에만 관심이 있지만)에서 작동해야한다고 생각합니다.

다른 접근 방식이나 개선점에 대해 제안 하시겠습니까? 나는이 문제에 대한 최선의 해결책을 알고 싶다. (아마 사전을 쓰는 대신에 일반적인 단어의 출현을 원한다. 재귀를 피하기 위해 알고리즘을 재구성하는 것이 훨씬 빠를까?).

답변

1

몇 더 많은 아이디어 :

  • 지수는 열려있는 각 인용을 위해 후 최종 견적이 있어야합니다.
  • 대문자, 보통 문장의 시작하거나 명사 등 (
  • 을 적용 할 추가 문법 규칙은 메모리에 모든 맞게, 그리고 특정 배열에 유효한 단어의 수를 계산하기 위해 충분히 작은 사전을 사용합니다.

한 가지 방법은, 일반적으로이 방법이 있지만 대부분의 시간 consuming- 중 하나는 유전자 알고리즘을 사용하는 것입니다.

컬럼의 현재 기본 배열은 말할 수 있습니다

|de| | f|Cl|nf|ed|au| i|ti| |ma|ha|or|nn|ou| S|on|nd|on| 
[0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18] <--- define this to be a chromosome 

당신은 무작위로 할당 시작 (중복되는 번호를 가질 수 없습니다 염두에두고 '무작위'할당을 유지하고 유효해야합니다) 염색체의/전자 번호 w 100, 1000의 인구를 만들 수

그런 다음에 피트니스 기능을 실행 각 할당, 또는 여러 가지 피트니스 기능을 사용하면됩니다. 각 과제에 적합성 값을 할당하는 슈퍼 피트니스 기능 하나부터 시작하십시오.

염색체의 상위 50 % 만 가져 와서 차세대로 이동하십시오. 여기서 크로스 오버 기능 및 변형 가능성에 기반하여 '어린이'염색체를 만듭니다. 이러한 유형의 문제에 대해서는 매우 좋습니다 가벼운 교차 기능 (또는 없음 ...)과 적절한 돌연변이 비율. 단어/피트니스 기능에 기여하지 않는 항목을 많이 찾을 수 있다면 주위를 뒤집을 수도 있습니다.

여러 세대 동안 계속 이렇게하고 최상위 등급 할당이 각 세대마다 어떻게 나타나는지 확인하십시오. 일정 시점에서 유효 기간이 예상되어 올바른 할당 일 것입니다.

이 접근법은 피트니스 기능이있는 무차별 대항력보다 약간 낫지 만 꽤 좋을 수도 있습니다.

마지막 아이디어 : '첫 번째 열, 두 번째 열'에서 추상화하고 단어를 구성하는 청크로 열을 할당하십시오. 왜냐하면 [1,4,6 ....]이 " ""그 ""그녀 "등, 그것은 그것이 처음에 바로 속한다는 것을 의미하지 않는다.

나는 다른 종류의 접근법을 사용합니다. 동적 알고리즘이 더 적합 할 것 같습니다.

편집 : 또 다른 방법

다시 사전 접근 방식을 기반으로하지만 나머지 전에 처음 몇 열을 선택에 초점을 맞출 것, 그것이 무너지게하고 있다면 당신은 어떤 특정 행에 말을 못하고있다 그것은 당신의 이전 선택이 틀렸다는 것을 의미하고 당신은 되돌아 갈 필요가 있습니다.

행 선택 1. 여기에 단어가 너무 많지는 않지만 첫 번째 열의 문자로 시작하는 단어가있는 하위 집합 인 사전의 하위 집합으로 좁힐 수 있습니다.

이제 행이 작동하고 오른쪽의 인접한 행을 선택하십시오. 완전한 단어를 만들거나 여전히 유효한 단어가있는 경우 (단어의 끝을 나타내는 공백이없는 경우). 반복하십시오.

이전 선택 사항으로 주어진 인접 행이 없으면 한 행을 왼쪽으로 되돌리고 동일한 것을 다시 선택하지 마십시오.

약점은 사전에 문장의 모든 단어와 단어의 모든 변형을 포함해야한다는 것입니다. "90 %의 단어가 일치하므로 여전히 유효한 시도입니다 ..."또는 이와 비슷한 것으로 알려진 피트니스 기능과 비슷한 경험적 방법을 찾아야 할 수도 있습니다.