기금넷 공식사이트 - 복권 조회 - C 언어의 반복 방법은 무엇입니까?
C 언어의 반복 방법은 무엇입니까?
반복은 수치 해석에서 초기 추정치에서 일련의 근사치를 찾아 문제 (일반적으로 방정식 또는 방정식 해결) 를 해결하는 프로세스입니다. 이 과정을 실현하는 방법을 통칭하여 반복법이라고 한다.
일반적으로 주어진 선형 방정식 x=Bx+f (여기서 x, b, f 는 모든 선형 방정식을 변환할 수 있는 행렬임) 에 대해 x (k+1) = bx (k) 공식을 점진적으로 도입하도록 정의할 수 있습니다 K 가 무한대가 될 때 limx(k) 가 존재하면 x* 로 기록됩니다. 이 반복 방법을 수렴이라고 합니다. 분명히 x* 는 이 방정식의 해법이다. 그렇지 않으면 반복 발산이라고 한다.
반복법에 해당하는 것은 직접 방법 (또는 1 회 솔루션) 입니다. 즉, 예를 들어 루트를 구하여 방정식 x +3= 4 를 해결하는 것과 같이 한 번에 빠르게 문제를 푸는 것입니다. 일반적으로 가능한 경우 직접 해결이 항상 선호됩니다. 하지만 복잡한 문제, 특히 미지수가 많고 방정식이 비선형일 때는 직접 풀 수 없습니다 (예: 5 회 이상의 대수학 방정식이 해결되지 않은 경우 아벨 정리 참조). 이때 우리는 반복법으로 방정식 (그룹) 의 근사치를 구할 수 있을 것이다.
가장 일반적인 반복법은 뉴턴법이다. 기타에는 가장 빠른 하강 방법, 멍에 반복 방법, 가변 스케일 반복 방법, 최소 평방, 선형 계획, 비선형 계획, 심플 렉스 방법, 벌칙 함수 방법, 기울기 투영법, 유전 알고리즘, 시뮬레이션 어닐링 등이 있습니다.
반복 알고리즘을 사용하여 문제를 해결하려면 다음 세 가지 작업을 수행해야 합니다.
반복 변수 결정
반복 알고리즘에서 해결할 수 있는 문제 중 하나 이상의 변수가 이전 값에서 직접 또는 간접적으로 새 값을 파생합니다. 이 변수는 반복 변수입니다.
반복 관계 설정
반복 관계란 한 변수의 이전 값에서 다음 값을 파생시키는 공식 (또는 관계) 입니다. 반복 관계의 수립은 반복 문제를 해결하는 열쇠이며, 일반적으로 앞으로 밀거나 뒤로 밀면 됩니다.
반복 프로세스를 제어합니다.
존재
반복 과정은 언제 끝날까요? 이것은 반복 프로그램을 작성할 때 고려해야 할 문제입니다. 반복 과정은 끝없이 반복해서는 안 된다. 반복 프로세스의 제어는 일반적으로 두 가지 경우로 나눌 수 있습니다. 하나는 원하는 반복 횟수입니다.
계산할 수있는 값입니다. 다른 하나는 필요한 반복 횟수를 결정할 수 없다는 것입니다. 이전 경우 반복 프로세스를 제어하기 위해 고정된 수의 루프를 구성할 수 있습니다. 후자의 경우 다음을 수행해야 합니다
반복 프로세스를 종료하는 데 사용되는 조건을 더 분석할 필요가 있습니다.
예를 하나 들어보죠
새로운 품종의 토끼가 한 농장에 도입되었다. 이런 토끼는 생후 두 달부터 매달 새 토끼 한 마리를 낳고, 새 토끼도 같은 방식으로 번식한다. 모든 토끼가 죽지 않았다면 12 월 이 농장에 몇 마리의 토끼가 있습니까?
분석: 이것은 전형적인 재귀 문제입니다. 두 번째 1 달의 토끼 수가 u 1, 두 번째 달의 토끼 수는 u 2, 세 번째 달의 토끼 수는 u 3 ... 문제의 의미에 따르면, "이런 토끼는 태어난 다음 달부터 매월 새 토끼 한 마리를 낳는다" 고 가정해 보자.
U 1 = 1, U2 = u1+u1×1= 2,
이 법칙에 따라 다음과 같은 재귀 공식을 요약할 수 있다.
U n = u(n-1)× 2 (n ≥ 2)
U n 과 u (n- 1) 에 해당하는 두 개의 반복 변수 y 와 x 가 정의되어 있으며 위의 반복 공식은 다음과 같은 반복 관계로 변환할 수 있습니다.
Y=x*2
X=y
컴퓨터가 이 반복 관계 1 1 회를 반복하게 하면 12 월의 토끼 수를 계산할 수 있다. 참조 절차는 다음과 같습니다.
Cls
X= 1
I=2 부터 12 까지의 경우
Y=x*2
X=y
다음으로 저는
인쇄 y
끝
예 2: 아메바는 간단한 분열을 통해 번식하며, 분열할 때마다 3 분이 걸린다. 아메바 원충 몇 마리를 영양인삼액이 들어 있는 용기에 넣으면 45 분 후 용기에 아메바 원충이 가득 차게 된다. 이 용기는 최대 220,220 마리의 아메바 원충을 수용할 수 있는 것으로 알려져 있다. 처음에 용기에 아메바 몇 마리를 넣었습니까? 프로그래밍해 주세요.
해설: 문제의 의미에 따르면 아메바 원충은 3 분마다 분열하기 때문에 아메바 원충을 처음부터 용기에 45 까지 넣는다
분 후에 컨테이너를 가득 채우는 데 45/3= 15 회 걸립니다. "용기에 20 아메바를 최대 2 개까지 담을 수 있다" 는 것은 아메바를 15 회로 나눈 뒤 얻은 숫자는
2 20. 제목은 우리가 분류하기 전에 아메바충의 수량을 먼저 계산해야 한다고 요구한다. 15 나누기 후 2 20 에서 15 나누기 전 수 (즉 14
분할 후) 그런 다음 13 분할 후 12 분할 후 1 분할 전의 수를 더 도출합니다.
첫 번째 1 보조 분할 전의 수를 x 0, 두 번째 1 보조 분할 후의 수를 x1,두 번째 분할 후의 수를 x 2, ../kloc 로 설정합니다
X 14 =x 15 /2, x 13 =x 14 /2, ...;
15 번째 분할 후의 수는 알려져 있으므로 반복 변수가 x 로 정의된 경우 위의 역산 공식을 다음과 같은 반복 공식으로 변환할 수 있습니다.
X = x=x/2 (x 번째 15 분할 후 x 의 초기 값은 2 20 임).
이 반복 공식을 15 회 반복하면 1 분열 전의 아메바 수를 추정할 수 있다. 필요한 반복 횟수가 결정된 값이므로 고정 루프 수를 사용하여 반복 프로세스를 제어할 수 있습니다. 참조 절차는 다음과 같습니다.
Cls
X = 2 20
I= 1 끝 15 의 경우
X=x/2
다음으로 저는
X 인쇄
끝
Ps: 자바의 전력 알고리즘은 Math.pow (2 2,20) 입니다. 회귀쌍입니다. 조금만 주의하세요.
예 3: 곡각 추측 확인. 일본 수학자 곡담정은 자연수를 연구할 때 이상한 현상을 발견했다. 임의의 자연수 N 에 대해 n 이 짝수라면 2 로 나눈다. N 이 홀수인 경우 3 을 곱한 다음 1 을 추가합니다. 유한한 차연산을 거쳐 항상 자연수 1 을 얻을 수 있다. 사람들은 타나키 좌사의 이 발견을' 타나키 추측' 이라고 부른다.
요구 사항: 키보드를 통해 자연수 N 을 입력하여 유한 연산을 거쳐 N 이 자연수 1 이 되는 전 과정을 인쇄하는 프로그램을 작성합니다.
해결: 반복 변수를 N 으로 정의합니다. 밸리 각도 추측의 내용에 따라 n 이 짝수인 경우 n = n/2 의 반복 관계를 얻을 수 있습니다. N 이 홀수인 경우 n=n*3+ 1 입니다. QBASIC 언어로 설명하면 다음과 같습니다.
N 이 짝수인 경우
N=n/2
기타
N=n*3+ 1
만약 ... 끝날거야
이것은 컴퓨터 반복이 필요한 반복 과정입니다. 이 반복 과정을 몇 번이나 반복해야 반복변수 N 이 결국 자연수 1 이 됩니까?
이것은 우리의 계산을 초월한다. 따라서 반복 프로세스를 종료하는 데 사용되는 조건을 추가로 결정해야 합니다. 제목 요구 사항을 자세히 분석하면 임의로 주어진 자연수 N 에 대해 쉽게 알 수 있다
한정된 연산 후에 자연수 1 을 얻을 수 있다면 검증 작업이 완료됩니다. 따라서 반복 프로세스를 종료하는 조건은 n= 1 으로 정의할 수 있습니다. 참조 절차는 다음과 같습니다.
Cls
"n =" 을 입력합니다. N
N= 1 까지
N 모드 2=0 이면
Rem n 이 짝수인 경우 반복 공식 n=n/2 가 호출됩니다.
N=n/2
\ "\" 인쇄; N;
기타
N=n*3+ 1
\ "\" 인쇄; N;
만약 ... 끝날거야
고리
끝
제곱근 반복 방법;
# include & ltstdio.h & gt
# include & ltmath.h & gt
Void main ()
{
이중 a, x0, x1;
Printf ("a: \ n 입력");
Scanf("%lf ",& AMPA); //VC6.0 에서 "scanf ("%f") 로 쓸 수 없는 이유는 무엇입니까? A); " -응?
(a<0) 인 경우
Printf ("오류! \ n ");
기타
{
X0 = a/2;
X1= (x0+a/x0)/2;
하다
{
X0 = x1;
X1= (x0+a/x0)/2;
} while (fabs (x0-x1) > =1e-6);
}
Printf ("result: \ n");
Printf("sqrt(%g)=%g\n ",a, x1);
}
제곱근을 구하는 반복 공식: x 1= 1/2*(x0+a/x0).
알고리즘: 1. 먼저 초기 값 x0 을 A 의 제곱근 값으로 정의하고 a/2 를 우리 프로그램에서 A 의 초기 값으로 사용합니다. 반복 공식을 사용하여 x 1 을 찾습니다. 이 값은 A 의 실제 제곱근 값에 비해 오차가 크다.
3. 새로 얻은 x 1 대입 x0, 이 새로운 x0 으로 새로운 x 1 을 찾을 준비를 합니다.
13. 반복 공식을 사용하여 x 1 의 새 값을 구합니다. 즉, new x0 을 사용하여 x 1 의 새 제곱근 값을 구하면 실제 제곱근 값에 더 가까워집니다.
2. 비교 전후에 두 번 얻은 제곱근 값 x0 과 x 1, 그 차이가 우리가 지정한 값보다 작으면, 즉 우리가 원하는 정밀도에 도달한 경우 x 1 은 a 의 제곱근 값이라고 생각하고 단계 5 로 이동합니다. 그렇지 않으면 2 단계, 즉 루프 반복을 수행합니다.
반복법은 흔히 사용되는 방정식 또는 방정식의 대략적인 루트를 구하는 알고리즘 설계 방법입니다. 방정식을 f(x)=0 으로 설정하고, 어떤 수학적 방법으로 등가형 x=g(x) 를 도출한 후, 다음 단계를 따릅니다.
(1) 방정식의 대략적인 루트를 선택하여 변수 X0 에 할당합니다.
⑵ 변수 x 1 에 x0 값을 저장한 다음 g(x 1) 를 계산하여 변수 x0 에 결과를 저장합니다.
(3) x0 과 x 1 의 절대값이 지정된 정밀도 요구사항보다 작을 때 단계 (2) 계산을 반복합니다.
방정식에 루트가 있고 위의 방법으로 계산된 대략적인 루트 시퀀스가 수렴되는 경우 위의 방법으로 계산된 x0 이 방정식의 루트인 것으로 간주됩니다. 위의 알고리즘은 c 프로그램으로 다음과 같이 표시됩니다.
방정식의 뿌리를 찾는 반복 알고리즘
{x0= 초기 근사 루트;
을 (를) 하다
X1= x0;
X0 = g (x1); /* 특정 방정식에 따라 새로운 근사 루트 계산 */
} while (fabs (x0-x1) > ε);
Printf ("방정식의 대략적인 루트는 %f\n", x0);
}
반복 알고리즘은 종종 방정식의 뿌리를 찾는 데도 사용됩니다.
X=(x0, x 1, ..., xn- 1)
방정식을 다음과 같이 만듭니다.
Xi=gi(X) (I=0, 1, ..., n- 1)
방정식의 루트를 찾는 반복 알고리즘은 다음과 같이 설명 할 수 있습니다.
방정식의 뿌리를 찾는 반복 알고리즘
{for(I = 0;; 나
X= 초기 근사 루트;
을 (를) 하다
For(I = 0;; 나
Y = x;;
For(I = 0;; 나
X = gi (x);
For(δ= 0.0, I = 0;; 나
If (fabs (y-x) > 델타) 델타 = fabs (y-x);
} while (델타 > ε);
For(I = 0;; 나
Printf ("변수 x[%d] 의 대략적인 루트는 %f", I, x);
Printf ("\ n");
}
반복법으로 루트를 구할 때, 다음 두 가지 가능한 상황에 주의해야 한다.
(1) 방정식이 풀리지 않으면 알고리즘에서 얻은 근사 루트 시퀀스가 수렴되지 않고 반복 프로세스가 무한 루프가 됩니다. 따라서 반복 알고리즘을 사용하기 전에 먼저 방정식에 대한 솔루션이 있는지 확인하고 프로그램에서 반복 횟수를 제한해야 합니다.
⑵ 방정식에는 해결책이 있지만 반복 공식 선택이 부적절하거나 초기 근사치 루트 선택이 불합리하면 반복이 실패할 수 있습니다.
재귀적
재귀는 알고리즘을 설계하고 설명하는 강력한 도구입니다. 복잡한 알고리즘에 대한 설명에 자주 사용되기 때문에 다른 알고리즘 설계 방법을 소개하기 전에 먼저 논의해야 합니다.
재귀적으로 설명할 수 있는 알고리즘은 일반적으로 다음과 같은 특징을 가지고 있습니다. N 크기의 문제를 해결하기 위해 가능한 한 작은 문제로 분해한 다음 이러한 작은 문제의 해결을 통해 큰 문제의 해결을 쉽게 구성할 수 있습니다. 이러한 작은 문제도 동일한 분해 합성 방법을 사용하여 작은 문제로 분해할 수 있으며, 이러한 작은 문제의 해결로 큰 문제의 해결을 구성할 수 있습니다. 특히, N= 1 을 스케일할 때 직접 해석할 수 있습니다.
문제는 피보나치 수열의 N 번째 함수인 fib(n) 를 쓰고 계산하는 것이다.
피보나치 수열은 0, 1, 1, 2,3, ... 입니다.
Fib (0) = 0;
Fib ⑴=1;
Fib(n)=fib(n- 1)+fib(n-2) (n > 인 경우 : 1).
재귀 함수로 기록되는 것은 다음과 같습니다.
중간 섬유 (중간 섬유)
{if (n==0) 는 0 을 반환합니다.
If (n== 1) 는1을 반환합니다
(n> 1) 가 광섬유 (n- 1)+ 광섬유 (n-2) 를 반환하는 경우
}
재귀 알고리즘의 구현 과정은 재귀와 회귀의 두 단계로 나뉜다. 반복 단계에서 더 복잡한 문제 (n 스케일) 에 대한 해답은 원래 문제보다 더 간단한 문제로 밀려납니다. (데이비드 아셀, Northern Exposure (미국 TV 드라마), 반복명언)
문제에 대한 해결책 (n 보다 작은 스케일). 위의 예와 같이 fib(n) 를 풀고 fib(n- 1) 와 fib(n-2) 를 푸십시오. 즉, fib(n) 를 계산하려면 먼저 계산해야 합니다.
광섬유 (n- 1) 및 광섬유 (n-
2) 대신 fib(n- 1) 와 fib(n-2) 를 계산하려면 fib(n-3) 와 fib(n-4) 를 먼저 계산해야 합니다. Fib (1) 와 fib(0) 가 계산될 때까지 기다려 주십시오
즉시 1 과 0 의 결과를 얻다. 재귀 단계에서는 재귀를 종료하는 경우가 있어야 합니다. 예를 들어 함수 fib 에서 N 이 1 과 0 일 때.
회귀 단계에서 가장 간단한 상황에 대한 해법을 얻을 때, 점진적으로 복귀하여, 약간 복잡한 문제에 대한 해법을 차례로 얻는다. 예를 들어 FIB (1) 및 fib(0) 를 얻은 후 fib(n-2) 의 결과를 반환합니다.
반복 함수를 작성할 때 함수의 로컬 변수 및 매개 변수에 대한 지식은 현재 호출 레이어로 제한됩니다. 단순 문제 레이어로 푸시되면 원래 레이어의 매개변수와 로컬 변수가 숨겨집니다. 일련의 단순 문제 레이어에는 모두 고유한 매개변수와 로컬 변수가 있습니다.
재귀로 인해 일련의 함수 호출이 발생하고 일련의 반복 계산이 있을 수 있으므로 재귀적 알고리즘은 비효율적입니다. 재귀 알고리즘을 재귀 알고리즘으로 쉽게 변환할 수 있는 경우 프로그램은 일반적으로 재귀 알고리즘에 따라 작성됩니다. 예를 들어, 위 예제에서 반복 알고리즘을 사용하여 피보나치 수열의 N 번째 항목에 대한 함수 fib(n) 를 계산해야 합니다. 즉, 피보나치 수열의 처음 두 항목부터 시작하여 원하는 N 번째 항목이 계산될 때까지 다음 항목을 하나씩 계산합니다.
문제 조합 문제
문제 설명: 자연수 1, 2 에서 R 수의 모든 조합을 구합니다 ..., N ... 예를 들어 n=5, r=3 의 모든 조합은 (1) 5,4 입니다.
⑷5, 3, 2 ⑸5, 3, 1 ⑹5, 2, 1
⑺4, 3, 2 ⑻4, 3, 1 ⑼4, 2, 1
⒇ 3, 2, 1
나열된 10 조합을 분석하여 이 재귀 사상을 사용하여 조합 함수를 구하는 알고리즘을 고려할 수 있습니다. 함수를 void comb(int) 로 설정합니다
M, int
K) 자연수 1, 2 에서 임의의 수의 k 를 찾기 위해 ..., m ... 조합의 첫 번째 번호가 선택되면 다음 번호는 나머지 m- 1 개 중 k-/kloc 입니다 이렇게 하면 M 을 찾을 수 있다.
K 수의 조합 문제를 m- 1 수에서 k- 1 수를 취하는 조합 문제로 변환합니다. 함수를 작업 배열 a[
] 조합의 계산된 수를 저장합니다. 규칙 함수는 결정된 K 수 조합의 첫 번째 수를 a[k] 에 배치합니다. 조합을 계산할 때 [
] 는 조합 출력입니다. 첫 번째 숫자는 m, m- 1, ... 함수가 결정된 조합의 첫 번째 숫자를 배열에 넣은 후 두 가지 옵션을 사용할 수 있습니다. 조합의 나머지 요소가 아직 제거되지 않았기 때문에 전송을 계속합니다.
확인으로 돌아가기 또는 조합의 모든 요소가 확인되었기 때문에 조합을 출력합니다. 아래 절차의 함수 빗을 참조하십시오.
프로그램
# 포함
# maxn/kloc 정의-0/00
Int a [maxn];
빈 빗 (정수 m, 정수 k)
{int I, j;
For(I = m;; 나>= k;; 나-)
{a [k] = I;
If(k & gt;; 1)
빗 (I- 1, k-1);
기타
{for (j = a [0]; J>0; J-)
Printf("%4d ",a [j]);
Printf ("\ n");
}
}
}
Void main ()
{a [0] = 3;
빗 (5, 3);
}
배낭 문제
문제 설명: n 개의 서로 다른 값과 가중치를 가진 항목이 n 개의 항목 가운데 섹션 항목 선택 시나리오를 요청하여 선택한 항목의 총 가중치가 지정된 제한 가중치를 초과하지 않도록 하지만 선택한 항목의 값 합계가 가장 큽니다.
장 n
각 항목의 가중치는 w0, w 1, …, wn- 1, 각 항목의 값은 v0, v 1, …, VN-/klls 입니다 반복 검색 항목을 사용하는 선택 스키마입니다. 앞에 여러 가지 선택이 있다고 가정해 봅시다.
총 가치가 가장 큰 시나리오는 배열 옵션 [] 에 유지되며 시나리오의 총 가치는 변수 maxv 에 저장됩니다. 현재 항목 선택이 배열 CP [
]. 현재 시나리오가 이미 I- 1 항목을 고려했다고 가정하면 이제 I 항목을 고려해야 합니다. 현재 프로그램에 이미 포함된 항목 가중치의 합은 tw 입니다. 지금까지 다른 모든 항목을 선택할 수 있다면 이 방안이 실현될 수 있다
총가치의 기대치는 텔레비전이다. Tv 가 알고리즘에 도입될 때 현재 시나리오의 총 기대치가 이전 시나리오의 총 가치보다 작으면 현재 시나리오를 계속 조사하는 것은 무의미하고 종료되어야 합니다.
현재 계획은 즉시 다음 계획을 조사하기 시작한다. 스키마의 합계가 maxv 보다 크지 않으면 스키마를 더 이상 검사하지 않기 때문에 함수를 찾은 후 찾은 스키마가 이전 스키마보다 우수함을 보장합니다.
제 I 조의 선택에 대해서는 두 가지 가능성이 있다.
(1) 항목 I 선택을 고려해 볼 때, 이 가능성은 시나리오의 총 중량 제한을 초과하지 않는 경우에만 가능합니다. 선택이 완료되면 계속해서 다른 항목의 선택을 재귀적으로 고려합니다.
(2) I 항목이 선택되지 않은 것을 고려하면 I 항목이 없을 때 더 가치 있는 방안을 찾을 수 있는 경우에만 가능합니다 .....
위의 아이디어에 따라 다음과 같이 재귀 알고리즘을 작성하십시오.
Try (첫 번째 항목, 현재 선택이 달성한 가중치의 합계, 시나리오의 가능한 총 값 TV)
{/* 현재 프로그램에 포함 된 첫 번째 항목의 가능성을 고려하십시오 */
(첫 번째 항목을 포함하는 것이 허용 가능한 경우)
{현재 프로그램에 프로젝트 I 포함
만약 (나
시도 (i+ 1, tw+ 문장 I 의 무게, TV);
기타
/* 또 다른 완전한 방안. 이전 방안보다 더 좋고 최선이기 때문이다. */
현재 시나리오를 임시 모범 사례로 저장합니다.
복구 항목 I 에 포함되지 않은 상태
}
/* 현재 프로그램에 포함되지 않은 첫 번째 항목의 가능성을 고려합니다 */
만약 (첫 번째 항목을 제외하면 남성만 고려할 수 있다)
만약 (나
Try(i+ 1, tw, tv- I 항목의 값);
기타
/* 또 다른 완전한 방안. 이전 방안보다 더 좋고 최선이기 때문이다. */
현재 시나리오를 임시 모범 사례로 저장합니다.
}
위의 알고리즘을 이해하기 위해 몇 가지 예가 아래에 나와 있습니다. 가중치 및 값이 표에 표시된 네 가지 항목이 있습니다.
항목 0 1 2 3
무게 5 3 2 1
숫자 4 4 3 1
제한 무게를 7 로 설정합니다. 그런 다음 위의 알고리즘에 따라 다음 그림은 솔루션 프로세스입니다. 그림에서 볼 수 있듯이 일단 솔루션을 찾으면 알고리즘이 더 나은 솔루션을 찾을 수 있습니다. 검색 분기가 더 나은 해결책을 찾지 못할 것으로 확인되면 알고리즘은 해당 분기에서 검색을 계속하지 않고 분기를 즉시 종료하고 다음 분기를 조사합니다.
위의 알고리즘에 따라 작성된 함수 및 프로그램은 다음과 같습니다.
프로그램
# 포함
# 정의 번호 100
듀얼 limitW, totV, maxV
Int option[N], COP [n];
Struct {이중 가중치;
이중 값
} a [n];
Int n;;
Void find(int I, double tw, double TV)
{int k;;
/* 현재 프로그램에 포함 된 첫 번째 항목의 가능성을 고려하십시오 */
If (tw+a.weight < =limitW)
{COP =1;
만약 (나
기타
{for(k = 0;; K
Option [k] = COP [k];
Maxv = TV;
}
COP = 0;;
}
/* 현재 프로그램에 포함되지 않은 첫 번째 항목의 가능성을 고려합니다 */
If (TV-a.value > MaxV) 를 참조하십시오
만약 (나
기타
{for(k = 0;; K
Option [k] = COP [k];
Maxv = TV-a.value;
}
}
Void main ()
{int k;;
이중 w, v;
Printf ("입력 항목 수 \ n");
Scanf(("%d ",& ampn);
Printf ("각 항목의 무게와 가치 입력 \ n");
For (totv=0.0, k = 0;; K
{scanf("% 1f% 1f ",& ampw & amp;; 5);
A[k]. 무게 = w;;
A[k]. 값 = v;;
Tot v+= v;
}
Printf ("입력 제한 중량 \ n");
Scanf("% 1f ",& amplimitv);
Maxv = 0.0 입니다
For(k = 0;; Kfind (0,0.0, totv);
For(k = 0;; K
If (옵션 [k]) printf ("%4d", k+1);
Printf(" \ n 총 가치는 %.2f\n ",maxv);
}
대조적으로, 우리는 같은 문제 해결 아이디어로 비재귀적인 절차적 해법을 고려할 것이다. 솔루션 찾기 속도를 높이기 위해 프로그램은 단순히 모든 후보 솔루션을 하나씩 생성하는 것이 아니라
각 항목이 후보 해법에 미치는 영향으로 더 고려할 만한 후보 해법을 형성하다. 각 항목을 차례로 검사하여 후보 솔루션을 형성합니다. 첫 번째 항목을 조사하는 데는 몇 가지 상황이 있다: 이 항목이 후보자로 등재될 때.
이 솔루션은 여전히 솔루션의 총 중량 제한을 충족하므로 해당 항목이 후보 솔루션에 포함된 것으로 간주해야 합니다. 반대로 이 프로젝트는 현재 형성되고 있는 후보 솔루션에 포함되지 않아야 합니다. 마찬가지로 항목이 포함되어 있지 않은 경우에만
후보 솔루션에서 현재 임시 최적 솔루션보다 더 좋은 후보 솔루션을 찾아 해당 항목이 후보 솔루션에 포함되지 않은 것으로 간주할 수 있습니다. 한편, 이 프로젝트가 현재 후보 프로그램에 포함되지 않은 방안은 더 이상 고려되어서는 안 된다.
더 고려해야 할 모든 방안에 대해 프로그램은 다음 항목을 더 고려할 것이다.
프로그램
# 포함
# 정의 번호 100
이중 제한 w;
Intcop [n];
구조 요소 {이중 중량;
이중 값
} a [n];
Int k, n;
Struct {int
이중 tw;
이중 텔레비전
} twv [n];
다음 유효하지 않음 (int I, double tw, double TV)
{twv. = 1;
Twv tw = tw
Twv TV = TV;
}
이중 찾기 (struct ele *a, int n)
{int I, k, f;
듀얼 maxv, tw, TV, totv
Maxv = 0;;
For (totv=0.0, k = 0;; K
Totv+=a[k] 입니다. 가치;
다음 (0,0.0, totv);
I = 0;;
While(I & gt;; =0)
{f=twv 입니다. 을 눌러 섹션을 인쇄할 수도 있습니다
Tw = twv tw
Tv=twv TV;
스위치 (f)
{사례 1: twv. ++;
If (tw+a.weight < =limitW)
만약 (나
{다음 (i+ 1, tw+a.weight, TV);
I++;+;
}
기타
{maxv = TV
For(k = 0;; K
Cop[k]=twv[k] 입니다. ! =0;
}
깨뜨리다
사례 0: I-;
깨뜨리다
기본값: twv. =0;
If (TV-a.value > Maxv) 를 참조하십시오
만약 (나
{next(i+ 1, tw, TV-a.value);
I++;+;
}
기타
{maxv = TV-a.value;
For(k = 0;; K
Cop[k]=twv[k] 입니다. ! =0;
}
깨뜨리다
}
}
Maxv 로 돌아가기
}
Void main ()
{double maxv
Printf ("입력 항목 수 \ n");
Scanf(("%d ",& ampn);
Printf ("입력 제한 중량 \ n");
Scanf("% 1f ",& amplimitw);
Printf ("각 항목의 무게와 가치 입력 \ n");
For(k = 0;; K
Scanf("% 1f% 1f ",& ampa[k]. 무게 & ampa[k]. 값);
Maxv=find(a, n);
Printf(" \ n 선택한 항목은 \ n ");
For(k = 0;; K
If (옵션 [k]) printf ("%4d", k+1);
Printf(" \ n 총 가치는 %.2f\n ",maxv);
}