이분 도 최대 일치 하 는 헝가리 알고리즘 전체 코드
16097 단어 이분 도
먼저 이분 도의 2 측 을 A 측 과 B 측 으로 명명 하 다.헝가리 알고리즘 에서 이분 도의 최대 일치 성 을 구 하 는 관건 적 인 명 사 는 확대 경로 이다. 정 의 는 P 가 그림 G 에서 두 개의 일치 하지 않 는 정점 을 연결 하 는 경로 이 고 M 에 속 하 는 변 과 M 에 속 하지 않 는 변 (즉 일치 하고 일치 하 는 변) 이 P 에서 교체 되면 P 를 M 에 대한 확대 경로 라 고 한다.예: (1) A 측 점 a1 과 B 측 점 b1 사이 에 변 이 연결 되 어 있 고 변 a1b1 이 일치 하지 않 으 며 점 a1, b1 도 다른 일치 변 의 점 에 속 하지 않 는 다 면 a1b1 은 확대 경로 입 니 다.다시 말 하면 이렇게 이해 하면 하나의 이분 도 에 대해 초기 상황 에서 임의의 A 와 B 가 연 결 된 변 은 모두 확대 경로 이다.(2) 변 a1b1, b1a 2, a2b 2 가 있 고 b1a 2 가 일치 하 며 a1b1, a2b 2 가 일치 하지 않 으 며 점 a1 과 b2 가 다른 일치 하 는 점 에 속 하지 않 으 면 이 세 변 은 확장 경 로 를 구성한다.
증 광로 의 정의 에서 다음 과 같은 세 가지 결론 을 내 릴 수 있다. 1. P 의 경로 길 이 는 반드시 홀수 이 고 첫 번 째 변 과 마지막 변 은 모두 M 에 속 하지 않 습 니 다. 2. P 는 역작 동 을 통 해 더 큰 일치 M 을 얻 을 수 있 습 니 다. 3. M 은 G 의 최대 일치 이 며 M 에 대한 확장 경로 가 존재 하지 않 는 다 고 생각 합 니 다.
알고리즘 윤곽:
(1) M( ) (2) P, M’ M (3) (2) 。
만약 네가 이 알고리즘 을 배 운 적 이 없다 면, 여기까지 이해 할 수 있 을 것 이다.많은 글 에서 확대 경 로 를 찾 으 면 다음 글 이 없다 고 언급 했 습 니 다. 완전한 코드 비교 도 어렵 습 니 다. 다음 문 제 는 다음 과 같 습 니 다. (3) 중복 (2) 어떻게 합 니까?더욱 세분 화 하려 면 반드시 이렇게 해 야 한다.
for A i do i , ( )。
이 산법 의 정확성 은 내 가 아직 하지 않 았 다 는 것 을 증명 하 니, 먼저 실현 을 고려 한 후에 다시 이야기 하 자.우 리 는 알고리즘 을 디자인 할 때 정확성 증명 을 할 생각 을 하지 않 는 다. 일반 알고리즘 책의 욕심 산법 1 장 은 정확성 증명 이론 (의 진) 과 관련 되 지만 중시 되 지 않 는 다.최대 일치 라 는 문제 에 부 딪 히 면 정확성 증명의 중요성 을 알 수 있 고, 그렇지 않 으 면 항상 좀 불안 하 다.먼저 체험 해 볼 수 있 습 니 다. 만약 에 우리 가 A 측 각 점 에서 출발 하여 최대 일치 하 는 경 로 를 찾 을 수 있다 면 마지막 으로 얻 은 최대 일치 하 는 변 수 는 A 측 점 의 수량 과 같 습 니 다. 즉, A 측의 점 을 모두 사용 하면 자 연 스 럽 게 최대 일치 합 니 다.
여기까지 아직 끝나 지 않 았 습 니 다. 기껏해야 1 / 2 를 할 수 있 는 셈 입 니 다. 순환 중의 매번 확대 경 로 를 찾 는 것 도 쉽 지 않 습 니 다.투 령 상 수상자 의 유명한 공식 을 떠 올 리 면 '프로그램 = 알고리즘 + 데이터 구조' 이다.나 는 이 언론 을 발표 한 논문 을 본 적 이 없다. 이전에 나 는 이 말 에 대해 항상 불확실 한 느낌 을 가지 거나 더 많은 실증 이 필요 했다.나중에 저 는 알고리즘 프로그램 을 작성 하 는 과정 에서 이 말 은 대체적으로 알고리즘 의 윤곽 만 알 면 아직 멀 었 습 니 다. 이 알고리즘 을 적당 한 데이터 구조 에서 실현 해 야 알 수 있 습 니 다. 알고리즘 구 조 를 아 는 것 부터 실현 하 는 것 까지 큰 차이 가 있 기 때 문 입 니 다.이것 은 단지 깨 달 은 한 방면 일 뿐이다.
알고리즘 을 더욱 세분 화 합 니 다. 이분 도 를 A, B 양측 으로 나 누 는데 이런 방법 은 A 측의 깊이 를 옮 겨 다 니 는 것 으로 볼 수 있 고 A 측 과 B 측의 점 처리 방법 이 다르다 고 볼 수 있 습 니 다.
A ( A ) , : 1. A[i] 。 2. A B 。 (1) A A[i]: 。 B , ( ), 。 B , B B[j], (2)。 , 。 , A[i] 。 , A ( ),B 。 (2) B B[j], , , B[j] A A[k], A[k] (1)。
이 과정 에서 하나의 대기 열 기록 으로 확대 경로 가 A 와 B 에서 지나 간 점 을 찾 으 면 확대 경 로 를 찾 은 후에 최대 일치 하 는 것 을 수정 할 수 있 습 니 다.
자신 이 알고리즘 을 설계 할 때 위조 코드 의 역할 이 나 타 났 다.다음은 위조 코드 를 바탕 으로 완전한 실현 코드 입 니 다.
#include<iostream> #include<deque>
using namespace std; const int COUNTA=6,COUNTB=7; // A、B
int connection[COUNTA][COUNTB] = {0}; // A、B ( )
int match[COUNTA][COUNTB] = {0}; //A、B
struct elem{ int element; int currentpartner; }; deque<elem> que; void init() { connection[0][0] = 1; connection[0][1] = 1; connection[0][3] = 1; connection[1][1] = 1; connection[1][4] = 1; connection[2][0] = 1; connection[2][3] = 1; connection[2][6] = 1; connection[3][2] = 1; connection[3][3] = 1; connection[3][5] = 1; connection[4][3] = 1; connection[5][3] = 1; } bool bPointInMatch(int point)// B
{ for(int i=0;i<COUNTA;i++) { if(match[i][point]==1) { return true; } } return false; } int bFindMatchPoint(int point)// B A
{ for(int i=0;i<COUNTA;i++) { if(match[i][point]==1) { return i; } } return -1; } void maxMatch() { elem queElem; for(int i=0;i<COUNTA;i++) { bool findAugmentPathA = false; int counter=0; queElem.element = i; queElem.currentpartner = -1; que.push_back(queElem);//
while(findAugmentPathA==false && counter>=0) { if(!findAugmentPathA) { int aPoint; bool findAugmentPathB = false; for(int j=que[counter].currentpartner+1;j<COUNTB;j++) { if(connection[que[counter].element][j]==1 && match[que[counter].element][j]==0 && !bPointInMatch(j))//
{ que[counter].currentpartner++; findAugmentPathA = true; //B
counter++; queElem.element = j; queElem.currentpartner = -1; que.push_back(queElem); break; } else if(connection[que[counter].element][j]==1 && match[que[counter].element][j]==0 && bPointInMatch(j)) { que[counter].currentpartner++; findAugmentPathB = true; counter++;//B
queElem.element = j; queElem.currentpartner = -1; que.push_back(queElem); // B A
aPoint = bFindMatchPoint(j); counter++; queElem.element = aPoint; queElem.currentpartner = -1; que.push_back(queElem); break; } else{ //TODO: if ?
} } if(!findAugmentPathB) { counter = counter-2; } } } //
if(findAugmentPathA==true) { bool direction = false; for(int i=0;i<que.size()-1;i++) { if(direction==false) { direction=true; match[que[i].element][que[i+1].element]=1; } else{ direction=false; match[que[i+1].element][que[i].element]=0; } } } while(que.size()>0)//
{ que.pop_front(); } } //
for(int i=0;i<COUNTA;i++) { for(int j=0;j<COUNTB;j++) { if(match[i][j]==1) { cout<<"("<<i<<","<<j<<")"<<endl; break; } } } } int main() { init(); maxMatch(); return 0; }
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
POJ 2492 이분 도 판단 및 수집POJ - 2492 제목: N 개의 BUG 와 M 개의 BUG 의 성관 계 를 제시 하여 동성 관계 여 부 를 판단 한다. 이분 도 판단 해서 할 수도 있 고, 병 찰 집 으로 할 수도 있 고, 내일 보충 해서 집 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.