trunk preprocessor: various minor changes in MinimumFeedbackSet.{cc,hh}
git-svn-id: https://www.dynare.org/svn/dynare/trunk@2797 ac1d8469-bf42-47a9-8791-bf33cf982152issue#70
parent
0e665123e7
commit
762c5140fe
|
@ -17,6 +17,8 @@
|
||||||
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "MinimumFeedbackSet.hh"
|
#include "MinimumFeedbackSet.hh"
|
||||||
|
|
||||||
namespace MFS
|
namespace MFS
|
||||||
|
@ -24,8 +26,6 @@ namespace MFS
|
||||||
void
|
void
|
||||||
Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G)
|
Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*clear all in and out edges of vertex_to_eliminate
|
|
||||||
and remove vertex_to_eliminate from the graph*/
|
|
||||||
clear_vertex(vertex_to_eliminate, G);
|
clear_vertex(vertex_to_eliminate, G);
|
||||||
remove_vertex(vertex_to_eliminate, G);
|
remove_vertex(vertex_to_eliminate, G);
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,7 @@ namespace MFS
|
||||||
void
|
void
|
||||||
Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G)
|
Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*before the vertex i suppression replace all edges e_k_i and e_i_j by e_k_j*/
|
if (in_degree (vertex_to_eliminate, G) > 0 && out_degree (vertex_to_eliminate, G) > 0)
|
||||||
if (in_degree (vertex_to_eliminate, G) > 0 and out_degree (vertex_to_eliminate, G) > 0)
|
|
||||||
{
|
{
|
||||||
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
||||||
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
||||||
|
@ -67,16 +66,15 @@ namespace MFS
|
||||||
color[u] = gray_color;
|
color[u] = gray_color;
|
||||||
graph_traits<AdjacencyList_type>::out_edge_iterator vi, vi_end;
|
graph_traits<AdjacencyList_type>::out_edge_iterator vi, vi_end;
|
||||||
for (tie(vi, vi_end) = out_edges(u, g); vi != vi_end; ++vi)
|
for (tie(vi, vi_end) = out_edges(u, g); vi != vi_end; ++vi)
|
||||||
if (color[target(*vi, g)] == white_color)
|
if (color[target(*vi, g)] == white_color && has_cycle_dfs(g, target(*vi, g), color, circuit_stack))
|
||||||
{
|
|
||||||
if (has_cycle_dfs(g, target(*vi, g), color, circuit_stack))
|
|
||||||
{
|
{
|
||||||
|
// cycle detected, return immediately
|
||||||
circuit_stack.push_back(v_index[target(*vi, g)]);
|
circuit_stack.push_back(v_index[target(*vi, g)]);
|
||||||
return true; // cycle detected, return immediately
|
return true;
|
||||||
}
|
}
|
||||||
}
|
else if (color[target(*vi, g)] == gray_color)
|
||||||
else if (color[target(*vi, g)] == gray_color) // *vi is an ancestor!
|
|
||||||
{
|
{
|
||||||
|
// *vi is an ancestor!
|
||||||
circuit_stack.push_back(v_index[target(*vi, g)]);
|
circuit_stack.push_back(v_index[target(*vi, g)]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -85,31 +83,26 @@ namespace MFS
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
has_cylce(AdjacencyList_type& g, vector<int> &circuit_stack)
|
has_cycle(vector<int> &circuit_stack, AdjacencyList_type& g)
|
||||||
{
|
{
|
||||||
|
// Initialize color map to white
|
||||||
color_type color;
|
color_type color;
|
||||||
graph_traits<AdjacencyList_type>::vertex_iterator vi, vi_end;
|
graph_traits<AdjacencyList_type>::vertex_iterator vi, vi_end;
|
||||||
for (tie(vi, vi_end) = vertices(g); vi != vi_end; vi++)
|
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
|
||||||
color[*vi] = white_color;
|
color[*vi] = white_color;
|
||||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, g);
|
|
||||||
for (tie(vi, vi_end) = vertices(g); vi != vi_end; vi++)
|
// Perform depth-first search
|
||||||
if (color[*vi] == white_color)
|
for (tie(vi, vi_end) = vertices(g); vi != vi_end; ++vi)
|
||||||
if (has_cycle_dfs(g, *vi, color, circuit_stack))
|
if (color[*vi] == white_color && has_cycle_dfs(g, *vi, color, circuit_stack))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G)
|
|
||||||
{
|
|
||||||
return has_cylce(G, circuit_stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Print(AdjacencyList_type& G)
|
Print(AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
AdjacencyList_type::vertex_iterator it, it_end, it_begin;
|
AdjacencyList_type::vertex_iterator it, it_end;
|
||||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||||
cout << "Graph\n";
|
cout << "Graph\n";
|
||||||
cout << "-----\n";
|
cout << "-----\n";
|
||||||
|
@ -150,7 +143,7 @@ namespace MFS
|
||||||
void
|
void
|
||||||
Print(GraphvizDigraph& G)
|
Print(GraphvizDigraph& G)
|
||||||
{
|
{
|
||||||
GraphvizDigraph::vertex_iterator it, it_end, it_begin;
|
GraphvizDigraph::vertex_iterator it, it_end;
|
||||||
property_map<GraphvizDigraph, vertex_index_t>::type v_index = get(vertex_index, G);
|
property_map<GraphvizDigraph, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||||
cout << "Graph\n";
|
cout << "Graph\n";
|
||||||
cout << "-----\n";
|
cout << "-----\n";
|
||||||
|
@ -192,14 +185,14 @@ namespace MFS
|
||||||
property_map<GraphvizDigraph, vertex_index_t>::type v1_index = get(vertex_index, G1);
|
property_map<GraphvizDigraph, vertex_index_t>::type v1_index = get(vertex_index, G1);
|
||||||
set<int>::iterator it = select_index.begin();
|
set<int>::iterator it = select_index.begin();
|
||||||
map<int,int> reverse_index;
|
map<int,int> reverse_index;
|
||||||
for (unsigned int i = 0;i < n;i++, it++)
|
for (unsigned int i = 0;i < n;i++, ++it)
|
||||||
{
|
{
|
||||||
reverse_index[v1_index[*it]]=i;
|
reverse_index[v1_index[*it]]=i;
|
||||||
put(v_index, vertex(i, G), v1_index[*it]);
|
put(v_index, vertex(i, G), v1_index[*it]);
|
||||||
put(v_index1, vertex(i, G), i);
|
put(v_index1, vertex(i, G), i);
|
||||||
}
|
}
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
for (it = select_index.begin(), i = 0;i < n;i++, it++)
|
for (it = select_index.begin(), i = 0;i < n;i++, ++it)
|
||||||
{
|
{
|
||||||
GraphvizDigraph::out_edge_iterator it_out, out_end;
|
GraphvizDigraph::out_edge_iterator it_out, out_end;
|
||||||
GraphvizDigraph::vertex_descriptor vi = vertex(*it, G1);
|
GraphvizDigraph::vertex_descriptor vi = vertex(*it, G1);
|
||||||
|
@ -216,15 +209,13 @@ namespace MFS
|
||||||
vector_vertex_descriptor
|
vector_vertex_descriptor
|
||||||
Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G)
|
Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph
|
|
||||||
and return the vector of doublet*/
|
|
||||||
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
||||||
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
||||||
vector<AdjacencyList_type::vertex_descriptor> Doublet;
|
vector<AdjacencyList_type::vertex_descriptor> Doublet;
|
||||||
if (in_degree(vertex, G) > 0 and out_degree(vertex, G) > 0)
|
if (in_degree(vertex, G) > 0 && out_degree(vertex, G) > 0)
|
||||||
for (tie(it_in, in_end) = in_edges(vertex, G); it_in != in_end; ++it_in)
|
for (tie(it_in, in_end) = in_edges(vertex, G); it_in != in_end; ++it_in)
|
||||||
for (tie(it_out, out_end) = out_edges(vertex, G); it_out != out_end; ++it_out)
|
for (tie(it_out, out_end) = out_edges(vertex, G); it_out != out_end; ++it_out)
|
||||||
if (source(*it_in, G) == target(*it_out, G) and source(*it_in, G) != target(*it_in, G)) // not a loop
|
if (source(*it_in, G) == target(*it_out, G) && source(*it_in, G) != target(*it_in, G)) // not a loop
|
||||||
Doublet.push_back(source(*it_in, G));
|
Doublet.push_back(source(*it_in, G));
|
||||||
return Doublet;
|
return Doublet;
|
||||||
}
|
}
|
||||||
|
@ -232,35 +223,34 @@ namespace MFS
|
||||||
bool
|
bool
|
||||||
Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G)
|
Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*Detect all the clique (all vertex in a clique are related to each other) in the graph*/
|
|
||||||
vector<AdjacencyList_type::vertex_descriptor> liste;
|
vector<AdjacencyList_type::vertex_descriptor> liste;
|
||||||
bool agree = true;
|
bool agree = true;
|
||||||
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
||||||
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
AdjacencyList_type::out_edge_iterator it_out, out_end;
|
||||||
tie(it_in, in_end) = in_edges(vertex, G);
|
tie(it_in, in_end) = in_edges(vertex, G);
|
||||||
tie(it_out, out_end) = out_edges(vertex, G);
|
tie(it_out, out_end) = out_edges(vertex, G);
|
||||||
while (it_in != in_end and it_out != out_end and agree)
|
while (it_in != in_end && it_out != out_end && agree)
|
||||||
{
|
{
|
||||||
agree = (source(*it_in, G) == target(*it_out, G) and source(*it_in, G) != target(*it_in, G)); //not a loop
|
agree = (source(*it_in, G) == target(*it_out, G) && source(*it_in, G) != target(*it_in, G)); //not a loop
|
||||||
liste.push_back(source(*it_in, G));
|
liste.push_back(source(*it_in, G));
|
||||||
it_in++;
|
++it_in;
|
||||||
it_out++;
|
++it_out;
|
||||||
}
|
}
|
||||||
if (agree)
|
if (agree)
|
||||||
{
|
{
|
||||||
if (it_in != in_end or it_out != out_end)
|
if (it_in != in_end || it_out != out_end)
|
||||||
agree = false;
|
agree = false;
|
||||||
unsigned int i = 1;
|
unsigned int i = 1;
|
||||||
while (i < liste.size() and agree)
|
while (i < liste.size() && agree)
|
||||||
{
|
{
|
||||||
unsigned int j = i + 1;
|
unsigned int j = i + 1;
|
||||||
while (j < liste.size() and agree)
|
while (j < liste.size() && agree)
|
||||||
{
|
{
|
||||||
AdjacencyList_type::edge_descriptor ed;
|
AdjacencyList_type::edge_descriptor ed;
|
||||||
bool exist1, exist2;
|
bool exist1, exist2;
|
||||||
tie(ed, exist1) = edge(liste[i], liste[j] , G);
|
tie(ed, exist1) = edge(liste[i], liste[j] , G);
|
||||||
tie(ed, exist2) = edge(liste[j], liste[i] , G);
|
tie(ed, exist2) = edge(liste[j], liste[i] , G);
|
||||||
agree = (exist1 and exist2);
|
agree = (exist1 && exist2);
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -269,28 +259,22 @@ namespace MFS
|
||||||
return agree;
|
return agree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G)
|
Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*Graph reduction: eliminating purely intermediate variables or variables outside of any circuit*/
|
|
||||||
bool something_has_been_done = false;
|
bool something_has_been_done = false;
|
||||||
bool not_a_loop;
|
bool not_a_loop;
|
||||||
int i;
|
int i;
|
||||||
AdjacencyList_type::vertex_iterator it, it1, ita, it_end, it_begin;
|
AdjacencyList_type::vertex_iterator it, it1, ita, it_end;
|
||||||
tie(it, it_end) = vertices(G);
|
|
||||||
it_begin = it;
|
|
||||||
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
property_map<AdjacencyList_type, vertex_index_t>::type v_index = get(vertex_index, G);
|
||||||
for ( i = 0; it != it_end; ++it, i++)
|
for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++)
|
||||||
{
|
{
|
||||||
int in_degree_n = in_degree(*it, G);
|
int in_degree_n = in_degree(*it, G);
|
||||||
int out_degree_n = out_degree(*it, G);
|
int out_degree_n = out_degree(*it, G);
|
||||||
if (in_degree_n <= 1 or out_degree_n <= 1)
|
if (in_degree_n <= 1 || out_degree_n <= 1)
|
||||||
{
|
{
|
||||||
not_a_loop = true;
|
not_a_loop = true;
|
||||||
if (in_degree_n >= 1 and out_degree_n >= 1) //do not eliminate a vertex if it loops on its self!
|
if (in_degree_n >= 1 && out_degree_n >= 1) // Do not eliminate a vertex if it loops on itself!
|
||||||
{
|
{
|
||||||
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
AdjacencyList_type::in_edge_iterator it_in, in_end;
|
||||||
for (tie(it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in)
|
for (tie(it_in, in_end) = in_edges(*it, G); it_in != in_end; ++it_in)
|
||||||
|
@ -327,17 +311,13 @@ namespace MFS
|
||||||
return something_has_been_done;
|
return something_has_been_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G)
|
Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*Graphe reduction: elimination of a vertex inside a clique*/
|
AdjacencyList_type::vertex_iterator it, it1, ita, it_end;
|
||||||
AdjacencyList_type::vertex_iterator it, it1, ita, it_end, it_begin;
|
|
||||||
bool something_has_been_done = false;
|
bool something_has_been_done = false;
|
||||||
int i;
|
int i;
|
||||||
tie(it, it_end) = vertices(G);
|
for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++)
|
||||||
it_begin = it;
|
|
||||||
for (i = 0;it != it_end; ++it, i++)
|
|
||||||
{
|
{
|
||||||
if (Vertex_Belong_to_a_Clique(*it, G))
|
if (Vertex_Belong_to_a_Clique(*it, G))
|
||||||
{
|
{
|
||||||
|
@ -360,21 +340,13 @@ namespace MFS
|
||||||
return something_has_been_done;
|
return something_has_been_done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G)
|
Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G)
|
||||||
{
|
{
|
||||||
/*If a vertex loop on itself it's a feedback variable
|
|
||||||
we eliminate it from the graph and store the vertex
|
|
||||||
in the minimum feedback set*/
|
|
||||||
bool something_has_been_done = false;
|
bool something_has_been_done = false;
|
||||||
AdjacencyList_type::vertex_iterator it, it_end, it_begin, ita;
|
AdjacencyList_type::vertex_iterator it, it_end, ita;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
tie(it, it_end) = vertices(G);
|
for (tie(it, it_end) = vertices(G); it != it_end; ++it, i++)
|
||||||
it_begin = it;
|
|
||||||
for (;it != it_end; ++it, i++)
|
|
||||||
{
|
{
|
||||||
AdjacencyList_type::edge_descriptor ed;
|
AdjacencyList_type::edge_descriptor ed;
|
||||||
bool exist;
|
bool exist;
|
||||||
|
@ -413,7 +385,7 @@ namespace MFS
|
||||||
AdjacencyList_type G(G1);
|
AdjacencyList_type G(G1);
|
||||||
while (num_vertices(G) > 0)
|
while (num_vertices(G) > 0)
|
||||||
{
|
{
|
||||||
while (something_has_been_done and num_vertices(G) > 0)
|
while (something_has_been_done && num_vertices(G) > 0)
|
||||||
{
|
{
|
||||||
//Rule 1
|
//Rule 1
|
||||||
something_has_been_done = (Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(G) /*or something_has_been_done*/);
|
something_has_been_done = (Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(G) /*or something_has_been_done*/);
|
||||||
|
@ -422,13 +394,13 @@ namespace MFS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Rule 2
|
//Rule 2
|
||||||
something_has_been_done = (Elimination_of_Vertex_belonging_to_a_clique_Step(G) or something_has_been_done);
|
something_has_been_done = (Elimination_of_Vertex_belonging_to_a_clique_Step(G) || something_has_been_done);
|
||||||
#ifdef verbose
|
#ifdef verbose
|
||||||
cout << "2 something_has_been_done=" << something_has_been_done << "\n";
|
cout << "2 something_has_been_done=" << something_has_been_done << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Rule 3
|
//Rule 3
|
||||||
something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) or something_has_been_done);
|
something_has_been_done = (Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(feed_back_vertices, G) || something_has_been_done);
|
||||||
#ifdef verbose
|
#ifdef verbose
|
||||||
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
|
cout << "3 something_has_been_done=" << something_has_been_done << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
@ -436,7 +408,7 @@ namespace MFS
|
||||||
vector<int> circuit;
|
vector<int> circuit;
|
||||||
if (!has_cycle(circuit, G))
|
if (!has_cycle(circuit, G))
|
||||||
{
|
{
|
||||||
#ifdef verobse
|
#ifdef verbose
|
||||||
cout << "has_cycle=false\n";
|
cout << "has_cycle=false\n";
|
||||||
#endif
|
#endif
|
||||||
//sort(feed_back_vertices.begin(), feed_back_vertices.end());
|
//sort(feed_back_vertices.begin(), feed_back_vertices.end());
|
||||||
|
@ -494,7 +466,7 @@ namespace MFS
|
||||||
for (its = feedback_vertices.begin(); its != feedback_vertices.end(); its++)
|
for (its = feedback_vertices.begin(); its != feedback_vertices.end(); its++)
|
||||||
fv.insert(*its);
|
fv.insert(*its);
|
||||||
int i=0;
|
int i=0;
|
||||||
for (its = fv.begin(); its != fv.end(); its++, i++)
|
for (its = fv.begin(); its != fv.end(); ++its, i++)
|
||||||
{
|
{
|
||||||
//cout << "supress " << v_index[vertex(*its, G)]+1 << " " << *its << "\n";
|
//cout << "supress " << v_index[vertex(*its, G)]+1 << " " << *its << "\n";
|
||||||
Suppress(*its, G);
|
Suppress(*its, G);
|
||||||
|
@ -504,10 +476,8 @@ namespace MFS
|
||||||
while (something_has_been_done)
|
while (something_has_been_done)
|
||||||
{
|
{
|
||||||
something_has_been_done = false;
|
something_has_been_done = false;
|
||||||
AdjacencyList_type::vertex_iterator it, it_end, it_begin, ita;
|
AdjacencyList_type::vertex_iterator it, it_end, ita;
|
||||||
tie(it, it_end) = vertices(G);
|
for (tie(it, it_end) = vertices(G), i = 0; it != it_end; ++it, i++)
|
||||||
int i = 0;
|
|
||||||
for (it_begin = it;it != it_end; ++it, i++)
|
|
||||||
{
|
{
|
||||||
if (in_degree(*it, G) == 0)
|
if (in_degree(*it, G) == 0)
|
||||||
{
|
{
|
||||||
|
@ -529,7 +499,4 @@ namespace MFS
|
||||||
cout << "Error in the computation of feedback vertex set\n";
|
cout << "Error in the computation of feedback vertex set\n";
|
||||||
return Reordered_Vertices;
|
return Reordered_Vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,10 +17,9 @@
|
||||||
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef MFE_BOOST
|
#ifndef _MINIMUMFEEDBACKSET_HH
|
||||||
#define MFE_BOOST
|
#define _MINIMUMFEEDBACKSET_HH
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <boost/graph/graphviz.hpp>
|
#include <boost/graph/graphviz.hpp>
|
||||||
|
@ -29,8 +28,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
|
|
||||||
//#define verbose
|
namespace MFS
|
||||||
|
{
|
||||||
typedef property<vertex_index_t, int,
|
typedef property<vertex_index_t, int,
|
||||||
property<vertex_index1_t, int,
|
property<vertex_index1_t, int,
|
||||||
property<vertex_degree_t, int,
|
property<vertex_degree_t, int,
|
||||||
|
@ -40,23 +39,21 @@ using namespace boost;
|
||||||
typedef map<graph_traits<AdjacencyList_type>::vertex_descriptor,default_color_type> color_type;
|
typedef map<graph_traits<AdjacencyList_type>::vertex_descriptor,default_color_type> color_type;
|
||||||
typedef vector<AdjacencyList_type::vertex_descriptor> vector_vertex_descriptor;
|
typedef vector<AdjacencyList_type::vertex_descriptor> vector_vertex_descriptor;
|
||||||
|
|
||||||
namespace MFS
|
//! Eliminate a vertex i
|
||||||
{
|
|
||||||
//! Eliminate a vertex i:
|
|
||||||
/*! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i*/
|
/*! For a vertex i replace all edges e_k_i and e_i_j by a shorcut e_k_j and then Suppress the vertex i*/
|
||||||
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
void Eliminate(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||||
//!collect all doublet (for each edge e_i_k there is an edge e_k_i with k!=i) in the graph
|
//! Collect all doublets (edges e_i_k such that there is an edge e_k_i with k!=i in the graph)
|
||||||
/*! and return the vector of doublet*/
|
/*! Returns the vector of doublets */
|
||||||
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
vector_vertex_descriptor Collect_Doublet(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||||
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
|
//! Detect all the clique (all vertex in a clique are related to each other) in the graph
|
||||||
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
bool Vertex_Belong_to_a_Clique(AdjacencyList_type::vertex_descriptor vertex, AdjacencyList_type& G);
|
||||||
//! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
|
//! Graph reduction: eliminating purely intermediate variables or variables outside of any circuit
|
||||||
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G);
|
bool Elimination_of_Vertex_With_One_or_Less_Indegree_or_Outdegree_Step(AdjacencyList_type& G);
|
||||||
//! Graphe reduction: elimination of a vertex inside a clique
|
//! Graph reduction: elimination of a vertex inside a clique
|
||||||
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
|
bool Elimination_of_Vertex_belonging_to_a_clique_Step(AdjacencyList_type& G);
|
||||||
//! A vertex belong to the feedback vertex set if the vertex loop on itself.
|
//! A vertex belong to the feedback vertex set if the vertex loops on itself.
|
||||||
/*! We have to suppress this vertex and store it into the feedback set.*/
|
/*! We have to suppress this vertex and store it into the feedback set.*/
|
||||||
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(vector<pair<int, AdjacencyList_type::vertex_descriptor> > &looping_variable, AdjacencyList_type& G);
|
bool Suppression_of_Vertex_X_if_it_loops_store_in_set_of_feedback_vertex_Step(set<int> &feed_back_vertices, AdjacencyList_type& G1);
|
||||||
//! Print the Graph
|
//! Print the Graph
|
||||||
void Print(GraphvizDigraph& G);
|
void Print(GraphvizDigraph& G);
|
||||||
void Print(AdjacencyList_type& G);
|
void Print(AdjacencyList_type& G);
|
||||||
|
@ -67,18 +64,16 @@ namespace MFS
|
||||||
//! Create an adjacency graph from a GraphvizDigraph
|
//! Create an adjacency graph from a GraphvizDigraph
|
||||||
AdjacencyList_type GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index);
|
AdjacencyList_type GraphvizDigraph_2_AdjacencyList(GraphvizDigraph& G1, set<int> select_index);
|
||||||
//! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise)
|
//! Check if the graph contains any cycle (true if the model contains at least one cycle, false otherwise)
|
||||||
|
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& g);
|
||||||
bool has_cycle_dfs(AdjacencyList_type& g, AdjacencyList_type::vertex_descriptor u, color_type& color, vector<int> &circuit_stack);
|
bool has_cycle_dfs(AdjacencyList_type& g, AdjacencyList_type::vertex_descriptor u, color_type& color, vector<int> &circuit_stack);
|
||||||
bool has_cylce(AdjacencyList_type& g, vector<int> &circuit_stack, int size);
|
|
||||||
bool has_cycle(vector<int> &circuit_stack, AdjacencyList_type& G);
|
|
||||||
//! Return the feedback set
|
//! Return the feedback set
|
||||||
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
|
AdjacencyList_type Minimal_set_of_feedback_vertex(set<int> &feed_back_vertices, const AdjacencyList_type& G);
|
||||||
//! clear all in and out edges of vertex_to_eliminate
|
//! Clear all in and out edges of vertex_to_eliminate and remove vertex_to_eliminate from the graph
|
||||||
/*! and remove vertex_to_eliminate from the graph*/
|
|
||||||
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
void Suppress(AdjacencyList_type::vertex_descriptor vertex_to_eliminate, AdjacencyList_type& G);
|
||||||
void Suppress(int vertex_num, AdjacencyList_type& G);
|
void Suppress(int vertex_num, AdjacencyList_type& G);
|
||||||
//! reorder the recursive variable:
|
//! Reorder the recursive variables
|
||||||
/*! They appear first in a quasi triangular form and they are followed by the feedback variables */
|
/*! They appear first in a quasi triangular form and they are followed by the feedback variables */
|
||||||
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
vector<int> Reorder_the_recursive_variables(const AdjacencyList_type& G1, set<int> &feed_back_vertices);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif // _MINIMUMFEEDBACKSET_HH
|
||||||
|
|
Loading…
Reference in New Issue