[Algorithm] 백트래킹의 구원자, AC-3 알고리즘 (feat. 제약 만족 문제)

2026. 3. 1. 21:54·◈ Study/인공지능 AI🛸
인공지능(AI) 알고리즘을 공부하다 보면 스도쿠, 십자말풀이, 스케줄링 같은 문제들을 마주하게 됩니다. 이를 제약 만족 문제(CSP, Constraint Satisfaction Problem)라고 부릅니다. 이런 문제를 풀 때 가장 직관적인 접근은 '백트래킹(Backtracking)'입니다. 하지만 무작정 값을 찔러보고 아니면 되돌아오는 방식은 경우의 수가 조금만 늘어나도 연산 시간이 우주를 뚫고 나갑니다.

이때 탐색 공간을 극적으로 압축하여 백트래킹 엔진에 날개를 달아주는 전처리 알고리즘이 있습니다. 바로 AC-3 (Arc Consistency 3) 알고리즘입니다. 오늘은 이 알고리즘이 어떻게 불가능한 오답들을 미리 가지치기하는지, 그 직관적인 원리를 파헤쳐 보겠습니다.

1. CSP의 3대 핵심 용어

알고리즘을 이해하기 위해 먼저 우리가 다룰 데이터를 정의해 보겠습니다.
  • 노드(Node): 값을 할당해야 할 변수 (예: 십자말풀이의 빈칸 X, Y)
  • 도메인(Domain): 각 변수에 들어갈 수 있는 후보 값들의 집합 (Dx, Dy)
  • 아크(Arc): 두 변수 사이의 제약 조건 (방향성을 가진 간선 X → Y)
여기서 가장 헷갈리기 쉬운 개념이 바로 아크(Arc)입니다. "단순히 두 빈칸이 겹친다는 뜻 아닌가? 왜 하필 화살표(→)로 방향성을 표현할까?"라는 의문이 들 수 있습니다.

2. 아크(X → Y)의 진짜 의미: 단방향 필터링

아크를 단순한 연결선이 아니라, '단방향 검증 명령서'라고 생각해 보세요. X → Y라는 아크는 다음과 같은 철저한 역할 분담을 의미합니다.
  • 도착점 Y (심사위원): 평가의 기준이 됩니다. Y의 도메인(단어장)은 절대 깎이지 않습니다.
  • 출발점 X (참가자): 필터링을 당하는 대상입니다. Y의 기준에 맞지 않는 후보 단어들은 가차 없이 삭제됩니다.

이를 코드로 구현한 것이 바로 revise(X, Y) 함수입니다.

"심사위원 Y의 도메인에 있는 어떤 단어와도 교차점 스펠링이 맞지 않는 X의 단어들을 모두 지워라!"라는 뜻이죠. 방향성이 반대인 Y → X 라면, 반대로 X가 심사위원이 되어 Y를 평가합니다.

3. AC-3 알고리즘: 상태 전파의 예술

단순히 모든 변수 쌍을 한 번씩 비교하고 끝난다면, 그것은 완벽한 알고리즘이 아닙니다. 퍼즐 한쪽에서 일어난 변화는 연쇄적으로 다른 쪽의 일관성을 깨뜨릴 수 있기 때문입니다. AC-3는 큐(Queue)를 활용하여 이 '나비효과'를 네트워크 전체로 전파시킵니다.

- AC-3 파이썬 수도코드

def ac3(csp):
    # 1. 모든 아크(교차점 쌍)를 큐에 넣고 시작
    queue = [(X, Y) for X in csp.variables for Y in csp.neighbors(X)]
    
    while queue:
        X, Y = queue.pop(0)
        
        # 2. Y를 심사위원으로 삼아 X의 도메인을 다이어트!
        if revise(csp, X, Y):
            if len(csp.domains[X]) == 0:
                return False # 남은 후보가 없으면 퍼즐 실패
            
            # 3. 나비효과: X의 상태가 변했으니, X를 믿고 있던 이웃 Z들을 다시 큐에 넣음
            for Z in csp.neighbors(X) - {Y}:
                queue.append((Z, X))
                
    return True

4. 왜 집합 연산 - {Y}를 할까?

위 코드에서 가장 소름 돋는 최적화 포인트는 바로 큐에 이웃들을 다시 넣을 때 원인 제공자인 Y를 빼버리는(- {Y}) 부분입니다. 왜 뺄까요?
  • Z를 큐에 넣는 이유 (Z, X): 방금 X의 도메인에서 단어들이 삭제되었습니다. 그래프 반대편에 있는 이웃 Z의 단어장에는, 방금 삭제된 X의 단어만을 유일한 짝꿍으로 믿고 있던 데이터가 있을 수 있습니다. 짝꿍이 사라졌으니 그 데이터는 이제 쓸모없는 '좀비 데이터'입니다. 따라서 X를 새로운 심사위원으로 모시고 Z를 재검증해야 합니다.
  • Y를 빼는 이유 - {Y}: 방금 X에서 값들이 삭제된 이유는 오로지 "Y의 기준에 맞지 않아서"입니다. 즉, 현재 X에 살아남은 알맹이들은 애초에 Y와 100% 호환됨이 보장된 정예 멤버들입니다. 따라서 굳이 Y를 다시 큐에 넣어서 Y와 X를 또 검사하는 무의미한 연산(무한 루프)을 할 필요가 없는 것입니다.

 


 

특정 노드의 상태 변화를 추적하고,
의존성이 있는 인접 노드에게만 그 변화를 선택적으로 전파한다.

 

AC-3 알고리즘은 탐색 공간을 극단적으로 다이어트시켜 백트래킹의 성공률을 폭발적으로 높여주는 강력한 전처리 엔진입니다. 이 우아한 아키텍처는 비단 AI 탐색뿐만 아니라, 현대 프론트엔드 프레임워크의 반응형 상태 관리나 분산 시스템의 이벤트 전파 모델과도 그 결이 매우 닿아있습니다. 1970년대의 고전 알고리즘이 여전히 현대 소프트웨어 엔지니어링에 큰 영감을 주고 있습니다.
'◈ Study/인공지능 AI🛸' 카테고리의 다른 글
  • [Algorithm] K-NN 알고리즘으로 온라인 쇼핑몰 방문자 구매 예측하기
  • [Dev Note] AI는 정말 '새로운 것'을 창조할 수 있을까? (feat. 생성형 AI의 한계와 대중의 수용성)
  • [Algorithm] 언덕 오르기(Hill Climbing)만 하면 갇힌다? 최적해를 찾는 5가지 변형 기법 총정리
  • [Algorithm] 게임 이론의 정수: 미니맥스(Minimax)와 알파-베타 가지치기(Alpha-Beta Pruning) 심층 분석
예르미(yermi)
예르미(yermi)
끊임없이 제 자신을 계발하는 개발자입니다👨🏻‍💻
  • 예르미(yermi)
    예르미의 코딩노트
    예르미(yermi)
  • 전체
    오늘
    어제
    • 분류 전체보기 (972)
      • ◎ Java (133)
        • Java☕ (93)
        • JSP📋 (26)
        • Applet🧳 (6)
        • Interview👨🏻‍🏫 (8)
      • ◎ JavaScript (48)
        • JavaScript🦎 (25)
        • jQuery🌊 (8)
        • React🌐 (2)
        • Vue.js🔰 (6)
        • Node.js🫒 (3)
        • Google App Script🐑 (4)
      • ◎ HTML5+CSS3 (17)
        • HTML5📝 (8)
        • CSS3🎨 (9)
      • ──────────── (0)
      • ▣ Framework (67)
        • Spring🍃 (36)
        • Spring Boot🍀 (12)
        • Bootstrap💜 (3)
        • Selenium🌕 (6)
        • MyBatis🐣 (10)
      • ▣ Tools (47)
        • API🎯 (18)
        • Library🎲 (15)
        • JitPack🚀 (3)
        • Jenkins👨🏻 (7)
        • Thymeleaf🌿 (4)
      • ▣ Server (30)
        • Apache Tomcat🐱 (14)
        • Apache HTTP Server🛡️ (1)
        • Nginx🧶 (7)
        • OracleXE💿 (4)
        • VisualSVN📡 (4)
      • ▣ OS : 운영체제 (18)
        • cmd : 명령프롬프트💻 (10)
        • Linux🐧 (8)
      • ▣ SQL : Database (56)
        • Oracle SQL🏮 (26)
        • PL SQL💾 (9)
        • MySQL🐬 (6)
        • MariaDB🦦 (6)
        • H2 Database🔠 (3)
        • SQL 실전문제🐌 (6)
      • ────────── (0)
      • ◈ Human Project (86)
        • Mini : Library Service📚 (15)
        • 화면 설계 [HTML]🐯 (10)
        • 서버 프로그램 구현🦁 (15)
        • Team : 여수어때🛫 (19)
        • Custom : Student🏫 (9)
        • Custom : Board📖 (18)
      • ◈ Yermi Project (40)
        • 조사모아(Josa-moa)📬 (5)
        • Riddle-Game🧩 (6)
        • 맛있을 지도🍚 (2)
        • 어디 가! 박대리!🙋🏻‍♂️ (5)
        • 조크베어🐻‍❄️ (4)
        • Looks Like Thirty🦉 (2)
        • Toy Project💎 (12)
        • 오픈소스 파헤치기🪐 (4)
      • ◈ Refactoring (15)
        • Mini : Library Service📚 (8)
        • 서버 프로그램 구현🦁 (1)
        • Team : 여수어때🛫 (0)
        • 쿼리 튜닝일지🔧 (6)
      • ◈ Coding Test (80)
        • 백준(BOJ)👨🏻‍💻 (71)
        • 프로그래머스😎 (2)
        • 코드트리🌳 (7)
      • ◈ Study (129)
        • 기초튼튼 개발지식🥔 (25)
        • HTTP 웹 지식💡 (4)
        • 클린코드(Clean Code)🩺 (1)
        • 디자인패턴(GoF)🥞 (12)
        • 알고리즘(Algorithm)🎡 (14)
        • 다이어그램(Diagram)📈 (4)
        • 파이썬(Python)🐍 (16)
        • 에러노트(Error Note)🧱 (34)
        • 웹 보안(Web Security)🔐 (11)
        • 인공지능 AI🛸 (8)
      • ◈ 공부모임 (50)
        • 혼공학습단⏰ (18)
        • 코드트리 챌린지👊🏻 (2)
        • 개발도서 100독👟 (8)
        • 나는 리뷰어다🌾 (13)
        • 국가기술자격 서포터즈🌻 (9)
      • ◈ 자격증 공부 (37)
        • 정보처리기사🔱 (16)
        • 정보처리산업기사🔅 (9)
        • 컴퓨터활용능력 1급📼 (12)
      • ─────────── (0)
      • ◐ 기타 (119)
        • 알아두면 좋은 팁(tip)✨ (46)
        • 개발자의 일상🎈 (50)
        • 개발도서 서평🔍 (10)
        • 개발관련 세미나🎤 (2)
        • 블로그 꾸미기🎀 (9)
        • 사도신경 프로젝트🎚️ (2)
  • 인기 글

  • 최근 댓글

  • 태그

    백준 티어
    꿀팁
    Project
    백준
    html
    Oracle
    javascript
    코딩 테스트
    프로그래밍
    일상
    jsp
    코딩
    Error Note
    spring
    Database
    자바스크립트
    SQL
    CSS
    Java
    BOJ
  • hELLO· Designed By정상우.v4.10.3
예르미(yermi)
[Algorithm] 백트래킹의 구원자, AC-3 알고리즘 (feat. 제약 만족 문제)
상단으로

티스토리툴바