# Q-Table Version 3.0 변경사항 정리

## 📋 변경 개요

CHANGELOG.md에 기술된 Version 3.0 업데이트를 코드에 반영했습니다.
- **State 공간**: 36 states → **162 states**
- **변수 구조**: 3개 변수 → **5개 변수** (비즈니스 용어 적용)
- **동적 가중치**: 2변수 평균 → **5변수 가중합**

---

## 🔄 주요 변경 파일

### 1. State 모델 (`domain/model/state.py`)

#### 기존 (Version 2.0)
```python
class Scenario(IntEnum): ...        # 4개 값
class PriceZone(IntEnum): ...       # 3개 값  
class AcceptanceRate(IntEnum): ...  # 3개 값

State = (Scenario, PriceZone, AcceptanceRate)  # 4×3×3 = 36
```

#### 변경 (Version 3.0)
```python
class RevenueRange(IntEnum): ...           # 3개 값 (매출액 가격구간)
class DistributionStructure(IntEnum): ...  # 3개 값 (유통 구조)
class PartnerType(IntEnum): ...            # 3개 값 (파트너사 종류)
class AcceptanceRate(IntEnum): ...         # 3개 값 (가격 수용률 구간)
class InputPriceZone(IntEnum): ...         # 2개 값 (입력 금액 구간)

State = (RevenueRange, DistributionStructure, PartnerType, 
         AcceptanceRate, InputPriceZone)  # 3×3×3×3×2 = 162
```

**주요 특징:**
- 모든 클래스에 `.weight` 속성 추가 (동적 가중치 계산용)
- 비즈니스 용어로 명명 (매출액, 유통 구조, 파트너사 등)
- 각 변수마다 `from_*()` 클래스 메서드로 분류 로직 제공

---

### 2. Reward Calculator (`domain/service/reward_calculator.py`)

#### 기존 (Version 2.0)
```python
def calculate_reward(
    scenario: Scenario,
    price_zone: PriceZone,
    ...
)

def _calculate_weight(scenario, price_zone, cfg):
    raw = (scenario.priority_weight + price_zone.zone_weight) / 2.0
    return clip(raw, 0.2, 0.8)
```

#### 변경 (Version 3.0)
```python
def calculate_reward(
    revenue_range: RevenueRange,
    distribution: DistributionStructure,
    partner_type: PartnerType,
    acceptance_rate: AcceptanceRate,
    input_price_zone: InputPriceZone,
    ...
)

def _calculate_weight(...):
    W_raw = (
        config.w1 * revenue_range.weight +
        config.w2 * distribution.weight +
        config.w3 * partner_type.weight +
        config.w4 * acceptance_rate.weight +
        config.w5 * input_price_zone.weight
    )
    return clip(W_raw, 0.2, 0.8)
```

**기본 가중치 계수:**
- w1 = 0.20 (매출액)
- w2 = 0.25 (유통 구조)
- w3 = 0.20 (파트너사)
- w4 = 0.25 (수용률)
- w5 = 0.10 (입력 금액)

---

### 3. State Calculator (`domain/service/state_calculator.py`)

#### 기존 (Version 2.0)
```python
@dataclass
class NegotiationSnapshot:
    scenario_code: str
    anchor_price: float
    target_price: float
    seller_initial_price: float
    current_price: float
```

#### 변경 (Version 3.0)
```python
@dataclass
class NegotiationSnapshot:
    revenue_amount: float          # 매출액 (만원)
    distribution_code: str         # "M", "W", "R"
    partner_count: int             # 파트너사 수
    anchor_price: float
    target_price: float
    input_price: float
    acceptance_ratio: Optional[float]
    initial_price: Optional[float]
```

**변경 이유:**
- 실제 비즈니스 데이터에 맞춰 필드 재구성
- 5개 State 변수를 도출할 수 있는 정보 제공

---

### 4. 모듈 Export (`domain/model/__init__.py`)

```python
# Version 3.0
from .state import (
    AcceptanceRate,
    DistributionStructure,
    InputPriceZone,
    PartnerType,
    RevenueRange,
    State,
)
```

---

## 📊 State 변수 상세 명세

| 변수 | 클래스 | 값 | 설명 | 가중치 |
|------|--------|---|------|--------|
| 매출액 가격구간 | `RevenueRange` | LOW (≤1,000만원) | 낮은 매출액 | 0.3 |
| | | MID (1,000~3,000만원) | 중간 매출액 | 0.6 |
| | | HIGH (>3,000만원) | 높은 매출액 | 1.0 |
| 유통 구조 | `DistributionStructure` | MANUFACTURER | 제조사 직공급 | 0.2 |
| | | WHOLESALER | 총판 경유 | 0.5 |
| | | RETAILER | 유통 경유 | 1.0 |
| 파트너사 종류 | `PartnerType` | NONE | 파트너 없음 | 0.3 |
| | | SINGLE | 단독 파트너 | 0.5 |
| | | MULTIPLE | 다수 파트너 | 1.0 |
| 가격 수용률 | `AcceptanceRate` | LOW (<30%) | 낮은 수용률 | 0.3 |
| | | MID (30~90%) | 중간 수용률 | 0.6 |
| | | HIGH (>90%) | 높은 수용률 | 1.0 |
| 입력 금액 구간 | `InputPriceZone` | PZ1 (A≤P≤T) | 목표 범위 내 | 1.0 |
| | | PZ2 (P>T or P<A) | 목표 범위 밖 | 0.3 |

---

## 🧪 새로운 테스트 파일

### `tests/Q_Table/test_state_v3.py`
- State 변수 분류 로직 검증
- State ↔ index 변환 정합성 테스트
- 162개 state 전체 순회 검증
- 가중치 값 검증

### `tests/Q_Table/test_reward_v3.py`
- NegotiationSnapshot → State 변환 테스트
- 동적 가중치 계산 검증
- 성공/실패/진행중 보상 계산 검증
- 최소/최대 가중치 경계 케이스 테스트

---

## 📚 문서 업데이트

### `REFACTORING_SUMMARY.md`
- Version 3.0 변경사항 추가
- 사용 예시 업데이트 (36 → 162 states)
- State 구조 비교표 추가

### `MIGRATION_V3.md` (신규)
- Version 2.0 → 3.0 마이그레이션 가이드
- Before/After 코드 비교
- 호환성 주의사항
- 체크리스트 제공

### `CHANGELOG.md` (기존 파일 참조)
- Version 3.0 변경사항 문서화
- 비즈니스 용어 적용 배경 설명

---

## ⚠️ Breaking Changes

### 1. Q-Table 크기 변경
```python
# Before
QTable(state_space_size=36, action_space_size=21)

# After
QTable(state_space_size=162, action_space_size=21)
```

### 2. State 생성 방식 변경
```python
# Before
State(
    scenario=Scenario.PRICE_FIRST,
    price_zone=PriceZone.AT_OR_BELOW_ANCHOR,
    acceptance_rate=AcceptanceRate.MEDIUM,
)

# After
State(
    revenue_range=RevenueRange.MID,
    distribution=DistributionStructure.WHOLESALER,
    partner_type=PartnerType.SINGLE,
    acceptance_rate=AcceptanceRate.MID,
    input_price_zone=InputPriceZone.PZ1,
)
```

### 3. 기존 학습 모델 호환 불가
- Version 2.0 모델 파일(.npy)은 36×N 크기
- Version 3.0은 162×N 크기로 로드 불가
- **재학습 필수**

---

## ✅ 검증 항목

- [x] State 클래스 5개 변수로 재정의
- [x] 각 변수의 `.weight` 속성 구현
- [x] State.to_index() / from_index() 162 states 대응
- [x] RewardConfig에 w1~w5 가중치 계수 추가
- [x] _calculate_weight() 5변수 가중합으로 변경
- [x] NegotiationSnapshot 필드 재구성
- [x] build_state() 5변수 매핑 로직 구현
- [x] __init__.py export 업데이트
- [x] REFACTORING_SUMMARY.md 업데이트
- [x] MIGRATION_V3.md 작성
- [x] 단위 테스트 작성 (test_state_v3.py, test_reward_v3.py)

---

## 🚀 다음 단계

1. **Python 환경 설정**
   ```bash
   poetry install
   # or
   pip install -r requirements.txt
   ```

2. **테스트 실행**
   ```bash
   pytest tests/Q_Table/test_state_v3.py -v
   pytest tests/Q_Table/test_reward_v3.py -v
   ```

3. **기존 코드 마이그레이션**
   - `MIGRATION_V3.md` 가이드 참조
   - State 생성 코드 일괄 변경
   - Q-Table 초기화 크기 변경

4. **모델 재학습**
   - 새로운 162-state 공간으로 학습 데이터 재수집
   - Q-Table 재학습 실행

---

## 📞 문의

Version 3.0 적용 중 문제 발생 시:
1. `MIGRATION_V3.md` 참조
2. 테스트 코드 참조 (`test_state_v3.py`, `test_reward_v3.py`)
3. 팀 리드에게 문의
