Summary of Class 13. Hamiltonian path
Success is not final, failure is not fatal: it is the courage to continue that counts.
A Hamiltonian path or traceable path is a path that visits each vertex of the graph exactly once.
A Hamiltonian cycle (or Hamiltonian circuit) is a Hamiltonian Path such that there is an edge (in graph) from the last vertex to the first vertex of the Hamiltonian Path.
0. Permutation and combination
set and subset:
sequence and subsequence:
https://www.mathsisfun.com/sets/sets-introduction.html
http://www.mathsisfun.com/algebra/sequences-series.html
permutation: the act of arranging all the members of a set into some sequence or order
combination: a selection of items from a collection without order
Problem: print all the combination of "abcd". backtracking-like method and bitmask method.
Solution: recursive, bit-mask
1. brute force (STL next_permutation)
Hamiltonian cycle search : permutation of all nodes (n!)
STL: next_permutation(begin(), end()), bidirectional iterator
int adj[MAXN][MAXN];
bool hamiltonian (int n){
int v[n];
for (int i=0; i<n; i++)
v[i] =i;
do {
bool valid=true;
for(int i=0; i<v.size()-1; i++) {
if(adj[v[i]][v[i+1]] == false){
valid=false;
break;
}
}
if(valid)
return true;
} while(next_permutation(v, v+n));
return false;
}
2. backtracking
void hamCycleUtil(bool graph[V][V], bool visited[V], vector<int> &path, int pos, int times)
void hamCycle(bool graph[V][V])
3. DP (I think it has little value in application)
Invented by Bellman, Held, and Karp. Good material for learning DP.
My explanation:
For every subset S of vertices check whether there is a path that visits "EACH and ONLY" the vertices in S exactly once and ends at a vertex v. This is the state. I use S(X) to represent the possible hamitonian path if it exists (true).
state: dp[i][j]
i: the ending vertex of hamitonian path
j: the subset of all vertices. You can use the bitmask to represent it.
initial state:
For every subset S(x), which only includes one vertex x, it is true, because the hamitonian path starts at x and ends at x.
state transition:
for every vertex y, if subset S does not include it has hamitonian path, which ends at vertext x, and there is a connection betweek x and y, the subset {S(x), y} will have a hamitinian path, which ends at y.
result:
for n vertex, 2^n-1 will have all the vertices in it. If any of them is true, there is hamitonian path
bool check_using_dp(int adj[][MAXN], int n){
bool dp[MAXN][1<<MAXN]={0};
for(int i=0; i<n; i++)
dp[i][1<<i]=true;
for(int i=0; i<(1<<n); i++){
for(int j=0; j<n; j++)
if(i&(1<<j)){
for(int k=0; k<n; k++)
if(i&(1<<k) && adj[k][j] && k!=j && dp[k][i^(1<<j)]){
dp[j][i]=true;
break;
}
}
}
for(int i=0; i<n; i++)
if(dp[i][(1<<n)-1])
return true;
return false;
}
Question: Why DP is faster than Brute Force method in this case?
Comments
Post a Comment