PGR21.com
이전 질문 게시판은 새 글 쓰기를 막았습니다. [질문 게시판]을 이용바랍니다.
Date 2008/07/25 22:04:26
Name Luxury Nobless
Subject 수학(혹은 C언어) 질문드립니다.

사실 C언어 문제인데 수학적인 계산을 파악을 못해서 질문드립니다.


어떤 n개의 좌표 x,y를 입력받아

이 점들을 내포함하는 반지름이 가장 작은 원(중심, 반지름)을 찾아보는 문제인데,

조건은, 원의 중심점은 입력받은 x,y 중에 한개여야 하고,

포함의 의미는 원의 선상에 x,y가 존재한다는 뜻입니다.


C언어 코딩을 아는 건 둘째치고 수학적으로 어떻게 접근해야 될지도 모르겠네요.

코딩의 힌트를 주셔도 좋고 수학적으로 어떻게 하면 좋을지 알려주셔도 좋습니다.



통합규정 1.3 이용안내 인용

"Pgr은 '명문화된 삭제규정'이 반드시 필요하지 않은 분을 환영합니다.
법 없이도 사는 사람, 남에게 상처를 주지 않으면서 같이 이야기 나눌 수 있는 분이면 좋겠습니다."
shadowtaki
08/07/25 22:17
수정 아이콘
수학적으로는 두점 사이가 제일 가까운 좌표 2개를 찾으면 되는 문제 같습니다. 저라면 별 생각없이 두점 사이 거리를 구하는 함수를 하나 만들고 순차적으로 모든 두점의 거리를 비교해 보겠습니다.
비육지탄
08/07/25 22:19
수정 아이콘
입력받은 좌표를 차례대로 일단 루프로 넣고(루프1), 루프 안에서 타겟이 된 좌표를 제외한 나머지 좌표들을 또 차례대로 루프로 넣어서(루프2) 그 두 타겟이 된 좌표를 피타고라스 정리로 거리를 구하면 되겠네요. 루프2에서는 각각의 좌표간 거리 중 가장 큰 값(변수1)을 도출시키고, 루프1에서는 각각의 변수1을 비교하여 가장 작은 변수1을 출력시키면 될겁니다. 변수1이 반지름이 되겠네요.
08/07/25 22:22
수정 아이콘
가장 무식한 방법이 가장 단순한 방법입니다.

일단 구조체 배열 정도이 필요하겠습니다.

i는 index x, y 그리고 계산해야 할 인덱스 변수 하나 더 필요합니다. min은 최소값이 되는 인덱스 좌표의 인덱스 번호 min_val은 그 최소값입니다.

i x y min min_val
0 a b
1 c d
2 e f
. . .
. . .
n y z

이런식으로 저장해 주면 되고

for(index가 n이 될때까지)

for(변수 i <=index+1){ // 인덱스 0번은 1번부터 n번까지 인덱스 1번은 2번부터 n번까지 왜냐면 인덱스 1번과 0번은 0번대에서 해결
....

}

....부분이 코딩 부분입니다. 수학적 아이디어를 쓰자면 좌표 x,y에서 1번 인덱스의 x,y까지 거리를 비교합니다.

그것이 원의 반지름이 됩니다. (x1-x2)²+(y1-y2)²의 양의 루트값이죠. 이것은 math.h에 있는 함수로 해결할 수 있습니다.

sqrt였던가...? 잘 기억 안나니 책 찾아서 참고해 주시고요. 0~n까지 돌아가며 최소값이 되는 인덱스와 최소값을 찾는 작업 한번 해주시면 대충 될겁니다.

이상입니다. 시간복잡도는 n²/2입니다.
NiceGuy4U
08/07/25 22:29
수정 아이콘
무식한 방법으로...
각 좌표값이 A1(x1, y1), A2(x2,y2), A3(x3,y3).....라고 가정하고....
입력 값이 (x1, y1), (x2, y2), (x3,y3)...(xn, yn)식으로 값을 받는다고 가정하면...
for(i=1;i<=n;i++)

for(j=1;j<=n;j++){
temp[i][j] = ((x[i]-x[j])^2 + (y[i]-y[j])^2);

}
이렇게 각 좌표간의 반지름 값을 전부 계산한뒤에...
for(i=1;i<=n;i++)

for(j=1;j<=n;j++){
if(temp[i][j] < temp[i+1][j+1]){
min = temp[i][j];
else{
min = temp[i+1][j+1];
}
각 배열에 있는 값중에 0이 아닌(0 이면 원이 아니죠) 최소값을 찾아내면..
그게 정답이 아닌지요???
C 코딩을 손 놓은지가...어언 4년이 넘어서...ㅡㅡ;;
그냥 간략히 정리만 해봤는데...뒤에 고수분께 패스....*^^*
꿀호떡a
08/07/25 22:47
수정 아이콘
정확히 '원 위에' 있어야 포함인지, 아니면 '원 안에' 있어도 포함으로 인정하는지에 따라 다를 것 같습니다.

뭐 설명은 윗분들이 해주셨으니 넘어가고, 한 가지 팁은 Sqrt를 씌워 굳이 거리로 비교할 것이 아니라, 그냥 거리^2을 가지고 비교하는 것이 더 낫습니다. 특히 입력되는 좌표가 정수라면 더더욱 말이죠. Int가 아닌 Double에서는 연산 회수를 최소화해야 오차를 줄일 수 있습니다.
NULL Pointer
08/07/25 22:50
수정 아이콘
다른분들 답주신게 조금씩 이상한게 있는것 같은데;;;;
제가 생각하는 답은 이렇습니다.

1. 주어진 N개의 좌표를 가지고 중심점 C 를 구한다.
2. 주어진 N개의 좌표중 중심점 C와 가장 가까운 좌표 (Cx, Cy)를 구한다.
3. 주어진 N개의 좌표중 (Cx, Cy)와 가장 먼 좌표 (Rx, Ry)를 구한다.
4. (Cx, Cy)와 (Rx, Ry)사이의 거리를 구한다.

2번에서 중심점 구하고, 4번에서 원의 반지름이 나옵니다.
08/07/25 22:53
수정 아이콘
아 문제 보니까 점을 내포하는 반지름이 작은 원이군요...

...이런 자료구조의 기초인 요구 파악부터 실패를...ㅠ_-
08/07/25 22:54
수정 아이콘
전 막연히 입력받은 거리중에 가장 작은 것만 생각했으니...;
꿀호떡a
08/07/25 22:54
수정 아이콘
NULL Pointer님 // '중심점'이 어떤것을 의미하나요?
shadowtaki
08/07/25 22:57
수정 아이콘
헉.. 이런 제가 제일 처음 달아놓은 답변이 혼란을 가중시킨거 같네요..ㅡㅡ;; 저도 문제 파악을 제대로 못했군요...
꿀호떡a
08/07/25 22:59
수정 아이콘
음.. N이 매우 크다면 Convex Hull을 우선 그려놓고, N개의 점들에 대해 Convex Hull 위에 있는 점들과의 거리만 계산하면 될 것 같습니다. 시간복잡도는 N * (Convex Hull 위의 정점 수) 이고 Convex Hull 위의 정점 수는 제 기억엔 평균적으로 lg N정도였던것으로..
비육지탄
08/07/25 23:06
수정 아이콘
꿀호떡a님// 입력받은 좌표들의 평균점(산술평균)을 의미하는 것일겁니다. 그 평균점과 입력받은 좌표간 거리를 비교하여 가장 가까운 좌표가 중심점이 되겠죠. 연산처리도 빨라질테고요.
NULL Pointer
08/07/25 23:10
수정 아이콘
#include "stdafx.h"
#include <stdlib.h>
#include <math.h>
#include <float.h>

struct Point

float x;
float y;
;

const int num_points = 4;

Point points[num_points] =

{10, 10
,
20, 20
,
30, 30
,
40, 40

};


int _tmain(int argc, _TCHAR* argv[])

float xSum = 0;
float ySum = 0;

int i;
for ( i = 0; i < num_points; ++i )
{
xSum += points[i].x;
ySum += points[i].y;


float cX = xSum / num_points;
float cY = ySum / num_points;

float dist;
float distMin = FLT_MAX;
int indexMin = -1;

for ( i = 0; i < num_points; ++i )

dist = (points[i].x - cX) * (points[i].x - cX) + (points[i].y - cY ) * (points[i].y - cY );
if ( dist <= distMin )
{
indexMin = i;
distMin = dist;

}
if ( indexMin == -1 )
exit( -1 );

cX = points[indexMin].x;
cY = points[indexMin].y;

float distMax = 0;
int indexMax = -1;

for ( i = 0; i < num_points; ++i )

dist = (points[i].x - cX) * (points[i].x - cX) + (points[i].y - cY ) * (points[i].y - cY );
if ( dist >= distMax )
{
indexMax = i;
distMax = dist;

}

if ( indexMax == -1 )
exit( -1 );

float rX = points[indexMax].x;
float rY = points[indexMax].y;


dist = sqrt( (rX - cX) * (rX - cX) + (rY - cY) * (rY - cY) );

printf( " Center : (%f, %f), Radius = %f\n", cX, cY, dist );

return 0;
}

대충 짜봤습니다. 컴파일 에러는 안나는것만 확인하고 테스트로 넣은 값에서는 정상 동작은 확인했습니다.
와후-만세
08/07/25 23:21
수정 아이콘
문제는 확실한것 같습니다.
내포함이라고 하였으니
원의 내부 또는 포함입니다.
모든 점을 원 안에 들이거나 원 상에 놓이게 할 수 있는 최소 반지름과 중심점을 구하는 문제이겠네요.
와후-만세
08/07/25 23:23
수정 아이콘
NULL POINTER님 증명 가능하십니까?
중심점을 산술평균이라고 했을때 그게 성립하지 않는 경우가 있습니다.
(0,0) 부근에 점들이 10만개쯤 몰려있고,
(5,0)에 한개,
(10,0)에 한 개 있으면,
중심점은 5,0이 되어야 하지만, 제시하신 알고리즘은 0,0 부근의 점을 선택합니다.
와후-만세
08/07/25 23:26
수정 아이콘
제가 생각하는 방법은 꿀호떡a님이 제시해주신 방법과 같구요, 아마 맞는것 같습니다.
Convex Hull 내부의 점에서 가장 거리가 먼 점은 반드시 Convex Hull 위에 있게 됩니다.
이 성질을 잘 이용하면, Rotating Calipers 방법을 이용하여 O ( N log N ) 시간내에 답을 구할 수 있을 지도 모르겠습니다만, 여기까지는 안 해봤고 될지도 모르겠습니다....
와후-만세
08/07/25 23:26
수정 아이콘
물론 그냥 C언어를 익히기 위한 과제였다면 O(N^2)의 Naive한 알고리즘으로도 충분할 것 같습니다.
가장 간단한 방법은 모든 점에 대해서 각각 중심점이라고 가정한 뒤, 이 때 필요한 원의 반지름의 크기(O(N)의 루프를 돌면서 각각의 점과 가정한 중심점과의 거리의 최대값)를 비교해서 최소를 찾아주면 되겠습니다.
NULL Pointer
08/07/25 23:26
수정 아이콘
와후-만세님 말이 맞군요. 중심점을 모든점들의 산술평균 말고 다른 방법으로 구해야 겠네요.
08/07/25 23:31
수정 아이콘
n이 작다면,
각 점을 중점으로 가정해서 나머지 점과의 거리중 가장 큰 것이 반지름입니다.
모든 점을 중점으로 가정해서 가장 작은 반지름이 나온 점이 중점이고 그 점에서 가장 먼거리가 반지름이 됩니다.
n이 크다면,
Convex Hull로 울타리에 위치하는 점들을 골라내고
n개의 점을 중점으로 가정해서 울타리 점들과의 거리를 계산합니다. 방법은 위와 비슷하지만 불필요한 연산이 제거 됩니다.

정점중에 하나가 중심이 되는 것으로 봐서 상단의 방법으로 풀이하라는 의도 같습니다.
하단의 방법(Convex Hull)을 의도했다면 정점 중심 조건도 빼버렸을 것같네요.

n의 범위를 제시하지 않은걸로 봐서 그냥 학부 코딩연습 과제인듯 합니다. 시간복잡도는 고려하지 말고 편한방법(상단)으로 푸세요.
Luxury Nobless
08/07/26 00:01
수정 아이콘
어디 갔다 온 사이에 많은 댓글이 달렸네요.
댓글 달아주신 분들 감사합니다. ^^
Luxury Nobless
08/07/26 00:10
수정 아이콘
아, 문제를 확실히 하자면
원안에 좌표가 포함해야 되고 원의 선상에 포함하는 부분까지라는 의미입니다.
n은 0~100까지 였는데 수학적으로 어떻게 해야되는지가 궁금해서 적진 않았습니다.

원래 문제는 이거였습니다. -
n개의 좌표(실수 x, y)가 입력되어 있다. 이 파일의 이름은 c드라이브에 input.txt라고 하자. 이 파일의 좌표를, 구조체를 동적할당으로 생성하여 입력 처리하고, 이 점들을 내포함하는 반지름이 가장 작은 원을 찾아본다. 여기서 원의 중심점은 입력되는 점들 가운데 하나이어야 하고, 포함한다는 의미는 원의 선상에 존재하는 점도 해당된다. 이 결과는 c드라이브에 학번.txt 파일에 출력하도록 한다. 좌표는 0~100사이의 실수로 입력되고, 점의 개수는 최대 100개로 한정한다.

아직 댓글들을 다 못읽어 봤지만 다시한번 감사의 말씀 드리겠습니다. ^^
와후-만세
08/07/26 00:15
수정 아이콘
아 참고로 n이 100개정도면 Memex님이 언급하신 n이 작은 경우에 해당됩니다. 이런 문제의 경우엔 10000개이상이면 좀 크다고 할 수 있습니다.
08/07/26 00:21
수정 아이콘
역시 후덜덜한 pgr 질게...
Luxury Nobless
08/07/26 00:23
수정 아이콘
감사합니다. 아직 C언어를 배운지 한달도 채 안됐는지라, 기초적 수준의 질문이었습니다. ^^
비빔면
08/07/26 01:28
수정 아이콘
이거 뭐야... 무서워...
목록 삭게로! 맨위로
번호 제목 이름 날짜 조회
39978 컴퓨터 공학과 진로 질문인데요... [3] Epicurean2133 08/07/26 2133
39977 2게이트...어떻게 막아야되나요...? [7] Jess:D1936 08/07/25 1936
39976 본떡스앤하모니(Bone Thugs N Harmony) 프로필을 알고 싶습니다. [2] on&on1837 08/07/25 1837
39975 컴퓨터가 안켜집니다.. [5] SaladiN2136 08/07/25 2136
39974 배심원제에서 판사의 역할은? [3] kikira2120 08/07/25 2120
39973 컴퓨터 견적좀 봐주세요 [3] 기적소리만큼1651 08/07/25 1651
39972 수학(혹은 C언어) 질문드립니다. [28] Luxury Nobless2966 08/07/25 2966
39971 일지매 결말에 대해서 [2] 마이스타일2312 08/07/25 2312
39970 프로리그 팀플과 빌드에대해 질문드릴께요 [6] 스타나라1634 08/07/25 1634
39969 회사와 법인에 관한 질문입니다. [2] 행복하게살자1698 08/07/25 1698
39968 컴퓨터 조립에 관한 질문(2) [2] Ex-sports1910 08/07/25 1910
39966 통계학 졸업후 진로에 대해 질문 드리겠습니다. [5] TheOthers1874 08/07/25 1874
39965 이럴 경우 누구의 책임인가요? [2] 엑스칼리버2092 08/07/25 2092
39964 이한철의 슈퍼스타 [1] 바람과쓰러지2037 08/07/25 2037
39963 스타2에 이명박 대통령이 나오나요? [6] 포셀라나2107 08/07/25 2107
39962 베넷어택에서 프로게이머가 진경기 알려주세요^^ [9] 신동v2106 08/07/25 2106
39961 은하철도999 전편을 구할 방법... [7] 설탕가루인형2888 08/07/25 2888
39960 편입학원 질문드립니다. Bikini2158 08/07/25 2158
39959 기타를 배우고싶습니다... [8] Best[AJo]2508 08/07/25 2508
39958 발톱이 빠졌는데요.. [2] Kaga2204 08/07/25 2204
39954 컴퓨터 견적좀 봐주세요. [5] 햇빛이좋아2165 08/07/25 2165
39953 키보드(전자 피아노) 추천해주세요. [1] UZOO1865 08/07/25 1865
39952 현금영수증 관련 질문 드립니다. [2] 기용패트리1605 08/07/25 1605
목록 이전 다음
댓글

+ : 최근 6시간내에 달린 댓글
+ : 최근 12시간내에 달린 댓글
맨 위로