Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 연결
- error 2002
- 언리얼 엔진4
- ftp 외부접속
- 유니티
- generic
- mysql 외부접속
- 유니티 소켓통신
- 제네릭
- 우분투 mysql
- unity
- 아마존 mysql
- 구글시트
- 원격
- 스프레드시트
- 리눅스 mysql
- error 1045
- AWS EC2 ssh
- workbench 외부접속
- coroutine
- 언리얼 AI
- 소켓통신
- spreadsheet
- AWS EC2 ftp
- ssh pem
- 코루틴
- Read 함수 뻗음
- NetworkStream
- AWS EC2
- read
Archives
- Today
- Total
공부한거 잊었을 때 보려고 만든 블로그
집합 커버 문제 Set Cover Problem 본문

U={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
F={S1, S2, S3, S4, S5, S6, S7, S8, S9, S10}
S1={1, 2, 3, 8}
S2={1, 2, 3, 4, 8}
S3={1, 2, 3, 4}
S4={2, 3, 4, 5, 7, 8}
S5={4, 5, 6, 7}
S6={5, 6, 7, 9, 10}
S7={4, 5, 6, 7}
S8={1, 2, 4, 8}
S9={6, 9}
S10={6, 10}
정답은, 가장 많은 노드를 커버하는 순서대로 4, 6, 1이 정답이 된다.
SetCover Problem Pseudo Code
입력: U, F={Si}, i=1,⋯,n
출력: 집합 커버 C
1. C=∅ // 모든 노드를 커버하는 노드 집합 2. while (U≠∅) do // 모든 노드를 방문할 때까지 반복 { 3. U의 원소들을 가장 많이 포함하고 있는 집합 S(i)를 F에서 선택 4. U=U-S(i) // 선택한 S(i)를 뺀다 5. S(i)를 F에서 제거하고, S(i)를 C에 추가한다. } 6. return C
// 수도코드 2번 int checkEmpty() { // 모든 U의 요소들이 0인지 확인한다. // 즉 모든 노드를 커버한다면 0, 아직 남아있다면 1 for(int i = 0; i < 10; i++) { if(U[i] == 1) return 1; } return 0; }
// 수도코드 3번 int getMaxCover(Node* node) { int max = 0; int maxIndex = -1; int count = 0; // S[i]가 커버하는 노드의 갯수를 count에 저장하고 // 가장많이 커버하는 maxIndex를 구한다. for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { if(U[j] == 1 && node->S[i][j] == 1) count++; } if(max < count) { max = count; maxIndex = i; } count = 0; } return maxIndex; }
void setCover(Node* node) { // U가 안비었을 때 동작, 아직 모든 노드를 커버하지 못할 때 동작 while(checkEmpty()) // 수도코드의 2번 { // 가장 많은 노드를 커버하는 인덱스를 찾음 int maxIndex = getMaxCover(node); // 수도코드의 3번 if(maxIndex != -1){ // 가장 많은 노드를 커버하는 maxIndex를 C에 추가 C[maxIndex] = 1; // 수도코드의 3번 } // 가장 많은 노드를 커버하는 인덱스를 U에서 삭제함 removeIndex(node,maxIndex); } printf("\nSet Cover End\n"); // 결과 출력 int first = 0; printf("C = {"); for(int i = 0; i < 10; i++) { if(C[i] == 1) { if(first == 1) printf(", "); first = 1; printf("S%d ", i+1); } } printf("}\n"); }
// 수도코드의 4번 void removeIndex(Node* node,int i) { // S[i]를 선택했으니 S[i]가 커버하는 곳을 U에서 제거 for(int j = 0; j < 10; j++) { if(node->S[i][j] == 1 && U[j] == 1) { U[j] = 0; } } }
전체코드#include <stdio.h> #include <stdlib.h> int C[10] = {0,0,0,0,0,0,0,0,0,0}; int U[10] = {1,1,1,1,1,1,1,1,1,1}; typedef struct Node{ int S[10][10]; }Node; // 수도코드 2번 int checkEmpty() { // 모든 U의 요소들이 0인지 확인한다. // 즉 모든 노드를 커버한다면 0, 아직 남아있다면 1 for(int i = 0; i < 10; i++) { if(U[i] == 1) return 1; } return 0; } // 수도코드의 4번 void removeIndex(Node* node,int i) { // S[i]를 선택했으니 S[i]가 커버하는 곳을 U에서 제거 for(int j = 0; j < 10; j++) { if(node->S[i][j] == 1 && U[j] == 1) { U[j] = 0; } } } // 수도코드 3번 int getMaxCover(Node* node) { int max = 0; int maxIndex = -1; int count = 0; // S[i]가 커버하는 노드의 갯수를 count에 저장하고 // 가장많이 커버하는 maxIndex를 구한다. for(int i = 0; i < 10; i++) { for(int j = 0; j < 10; j++) { if(U[j] == 1 && node->S[i][j] == 1) count++; } if(max < count) { max = count; maxIndex = i; } count = 0; } return maxIndex; } void printNode(Node node) { for(int i = 0; i < 10; i++) { printf("S%d = {",i+1); int first = 0; for(int j = 0; j < 10; j++) { if(node.S[i][j] == 1) { if(first == 1) printf(", "); first = 1; printf("%d",j+1); } } printf("}\n"); } } void setCover(Node* node) { // U가 안비었을 때 동작, 아직 모든 노드를 커버하지 못할 때 동작 while(checkEmpty()) // 수도코드의 2번 { // 가장 많은 노드를 커버하는 인덱스를 찾음 int maxIndex = getMaxCover(node); // 수도코드의 3번 if(maxIndex != -1){ // 가장 많은 노드를 커버하는 maxIndex를 C에 추가 C[maxIndex] = 1; // 수도코드의 3번 } // 가장 많은 노드를 커버하는 인덱스를 U에서 삭제함 removeIndex(node,maxIndex); } printf("\nSet Cover End\n"); // 결과 출력 int first = 0; printf("C = {"); for(int i = 0; i < 10; i++) { if(C[i] == 1) { if(first == 1) printf(", "); first = 1; printf("S%d ", i+1); } } printf("}\n"); } int main(int argc, char* argv[]) { Node node = { { {1,1,1,0,0,0,0,1,0,0}, {1,1,1,1,0,0,0,1,0,0}, {1,1,1,1,0,0,0,0,0,0}, {0,1,1,1,1,0,1,1,0,0}, {0,0,0,1,1,1,1,0,0,0}, {0,0,0,0,1,1,1,0,1,1}, {0,0,0,1,1,1,1,0,0,0}, {1,1,0,1,0,0,0,1,0,0}, {0,0,0,0,0,1,0,0,1,0}, {0,0,0,0,0,1,0,0,0,1} } }; printNode(node); setCover(&node); }
'자유 주제' 카테고리의 다른 글
자바 스프링 기상청 단기예보 (동네날씨) API (2) 위도경도 격자 변환 (0) | 2023.05.02 |
---|---|
자바 스프링 기상청 단기예보 (동네날씨) API (1) 날짜와 시간 (0) | 2023.05.02 |
파이썬 이미지 압축하기 (0) | 2023.04.12 |
PathVariable, RequestParam, RequestBody 차이 (0) | 2022.12.06 |
mysql 사용자 추가, 사용자 권한 (0) | 2022.12.06 |