동적 계획 시리즈 중 하나 머리말: 한 문제 에서 나 온 알고리즘
머리말 - 한 문제 에서 끌 어 낸 알고리즘
다음 과 같은 문 제 를 고려 하 다.
[예 1] 최 단 경로 문제
현재 지도 한 장 이 있 는데 각 결점 은 도 시 를 대표 하고 두 결점 간 의 연결선 은 도 로 를 대표 하 며 온라인 숫자 는 도시 간 의 거 리 를 나타 낸다.그림 1 에서 보 듯 이 결점 A 에서 결점 E 까지 의 최 단 거 리 를 찾 아 보 자.
그림 1
우 리 는 깊이 우선 검색 법 으로 이 문 제 를 해결 할 수 있 습 니 다. 이 문제 의 재 귀 식 은?
그 중에서 v 와 인접 한 노드 의 집합 이 고 w (v, u) 는 v 에서 u 까지 의 길 이 를 나타 낸다.
구체 적 인 알고리즘 은 다음 과 같다.
function MinDistance(v):integer;
begin
if v=E then return 0
else
begin
min:=maxint;
for i do
if v i then
begin
i ;
t:=v i +MinDistance(i);
i ;
if t<min then min=t;
end;
end;
end;
시작 할 때 모든 정점 에 접근 하지 않 았 음 을 표시 하고, MinDistance (A) 는 A 에서 E 까지 의 최 단 거 리 를 표시 합 니 다.
이 프로그램의 효율 은 어 떻 습 니까?우 리 는 매번 이미 방문 한 도 시 를 제외 하고 다른 도 시 를 방문 해 야 하기 때문에 시간 복잡 도 는 O (n!) 이다. 이것 은 '지수 급' 의 알고리즘 이다. 그러면 더 좋 은 알고리즘 이 있 을 까?
우선 이 알고리즘 을 살 펴 보 자.B1 에서 E 까지 의 최 단 거 리 를 구 할 때 먼저 C2 에서 E 까지 의 최 단 거 리 를 구한다.B2 에서 E 까지 의 최 단 거 리 를 구 할 때 C2 에서 E 까지 의 최 단 거 리 를 구 했다.C2 에서 E 까지 의 최 단 거 리 를 두 번 이나 구 했다 는 것 이다.마찬가지 로 C1, C2 에서 E 까지 최 단 거 리 를 구 하 는 과정 에서 D1 에서 E 까지 최 단 거리 도 두 번 구 한 것 으로 나 타 났 다.전체 프로그램 에 서 는 D1 에서 E 까지 최 단 거 리 를 네 번 이나 구 했다.해답 을 구 하 는 과정 에서 구 하 는 최 단 거 리 를 '사건 에 기록' 하면 서 수시로 호출 하면 이런 상황 을 피 할 수 있다.따라서 이 알고리즘 을 개선 할 수 있 습 니 다. 매번 구 하 는 v 에서 E 까지 의 최 단 거 리 를 기록 하고 알고리즘 에서 MinDistance (v) 를 재 귀적 으로 구 할 때 예전 에 MinDistance (v) 를 구 했 는 지 확인 합 니 다. 구 했 으 면 다시 구 할 필요 가 없습니다. 예전 의 기록 만 찾 으 면 됩 니 다.이렇게 하면 모든 점 이 n 개가 있 기 때문에 서로 다른 상태 수 는 n 개가 있 고 이 알고리즘 의 수량 급 은 O (n) 이다.
더 나 아가 이런 재 귀 를 전달 으로 바 꾸 면 재 귀 호출 비용 을 줄 일 수 있다.
그림 1 을 보 세 요. A 는 Bi 와 만 인접 하고 Bi 는 Ci 와 만 인접 하 며..........................................................이렇게 하면 우 리 는 원래 문제 의 해결 과정 을 4 단계 로 나 눌 수 있다. S1 = {A}, S2 = {B1, B2}, S3 = {C1, C2, C3, C4}, S4 = {D1, D2, D3}, Fk (u) 는 Sk 에서 점 u 에서 E 까지 의 최 단 거 리 를 나타 낸다.
그리고 경계 조건 이 있 습 니 다.
분명히 F1 (A), 즉 A 에서 E 까지 의 최 단 거 리 를 점차적으로 구 할 수 있다.이 알고리즘 의 복잡 도 는 O (n) 입 니 다. 모든 상태 총수 (노드 총수) 가 n 이기 때문에 모든 상태 에 한 번 만 옮 겨 다 니 고 프로그램 이 간결 합 니 다.
구체 적 인 알고리즘 은 다음 과 같다.
procedure DynamicProgramming;
begin
F5[E]:=0;
for i:=4 downto 1 do
for each u ∈Sk do
begin
Fk[u]:= ;
for each v∈Sk+1∩δ(u) do
if Fk[u]>w(u,v)+Fk+1[v] then Fk[u]:=w(u,v)+Fk+1[v];
end;
F1[A];
end;
이런 고 효율 알고리즘 은 바로 동적 기획 알고리즘 이다.
다음은 상술 한 두 알고리즘 의 구체 적 인 실현 이다.
#include <fstream>
ifstream fin("in.txt");
#define maxLength 20
#define maxPath 20
#define MAX 1000000
int matrix[maxLength][maxLength];//
int minPath[maxPath];//
int trace[maxLength];//
int v_n;//
int visited[maxLength];
int MinDistance_1(int v)
{
if(v==v_n-1)
{
return 0;
}
int min=MAX,t,j;
for(int i=v+1;i<=v_n-1;i++)// i
{
if(!visited[i]&&matrix[v][i]!=0)// i
{
visited[i]=true;
t=matrix[v][i]+MinDistance_1(i);
visited[i]=false;
if(t<min)
min=t;
}
}
return min;
}
int MinDistance(int v)
{
if(minPath[v]>0)//
return minPath[v];
if(v==v_n-1)
return 0;//
int min=1000,t,j;
for(int i=v+1;i<v_n;i++)
{
if(matrix[v][i]>0)
{
t=matrix[v][i]+MinDistance(i);
if(min>t)
{
min=t;
j=i;
}
}
}
minPath[v]=min;
trace[v]=j;//trace[i]
return minPath[v];
}
int main()
{
fin>>v_n;
for(int i=0;i<v_n;i++)
{
for(int j=0;j<v_n;j++)
{
fin>>matrix[i][j];
cout<<matrix[i][j]<<"-";
}
cout<<endl;
}
memset(visited,0,sizeof(int)*maxLength);
memset(minPath,0,sizeof(int)*maxLength);
memset(trace,0,sizeof(int)*maxLength);
int minD=MinDistance_1(0);
cout<<" :"<<minD<<endl;
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.