graph.hpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #include <climits>
00039
00040 namespace Gecode { namespace Int { namespace ViewValGraph {
00041
00042 template<class View>
00043 forceinline
00044 Graph<View>::Graph(void)
00045 : view(NULL), val(NULL), n_view(0), n_val(0), count(1U) {}
00046
00047 template<class View>
00048 forceinline bool
00049 Graph<View>::initialized(void) const {
00050 return view != NULL;
00051 }
00052
00053 template<class View>
00054 forceinline void
00055 Graph<View>::init(Space& home, ViewNode<View>* x) {
00056 Edge<View>** edge_p = x->val_edges_ref();
00057 ViewValues<View> xi(x->view());
00058 ValNode<View>** v = &val;
00059 while (xi() && (*v != NULL)) {
00060 if ((*v)->val() == xi.val()) {
00061
00062 *edge_p = new (home) Edge<View>(*v,x);
00063 edge_p = (*edge_p)->next_edge_ref();
00064 v = (*v)->next_val_ref();
00065 ++xi;
00066 } else if ((*v)->val() < xi.val()) {
00067
00068 v = (*v)->next_val_ref();
00069 } else {
00070
00071 ValNode<View>* nv = new (home) ValNode<View>(xi.val(),*v);
00072 *v = nv; v = nv->next_val_ref();
00073 *edge_p = new (home) Edge<View>(nv,x);
00074 edge_p = (*edge_p)->next_edge_ref();
00075 ++xi; n_val++;
00076 }
00077 }
00078
00079 while (xi()) {
00080 ValNode<View>* nv = new (home) ValNode<View>(xi.val(),*v);
00081 *v = nv; v = nv->next_val_ref();
00082 *edge_p = new (home) Edge<View>(nv,x);
00083 edge_p = (*edge_p)->next_edge_ref();
00084 ++xi; n_val++;
00085 }
00086 *edge_p = NULL;
00087 }
00088
00089 template<class View>
00090 forceinline bool
00091 Graph<View>::match(ViewNodeStack& m, ViewNode<View>* x) {
00092 count++;
00093 start:
00094
00095 {
00096 Edge<View>* e = x->val_edges();
00097
00098 assert(e != NULL);
00099 do {
00100 if (!e->val(x)->matching()) {
00101 e->revert(x); e->val(x)->matching(e);
00102
00103 while (!m.empty()) {
00104 x = m.pop(); e = x->iter;
00105 e->val(x)->matching()->revert(e->val(x));
00106 e->revert(x); e->val(x)->matching(e);
00107 }
00108 return true;
00109 }
00110 e = e->next_edge();
00111 } while (e != NULL);
00112 }
00113
00114 Edge<View>* e = x->val_edges();
00115 do {
00116 if (e->val(x)->matching()->view(e->val(x))->min < count) {
00117 e->val(x)->matching()->view(e->val(x))->min = count;
00118 m.push(x); x->iter = e;
00119 x = e->val(x)->matching()->view(e->val(x));
00120 goto start;
00121 }
00122 next:
00123 e = e->next_edge();
00124 } while (e != NULL);
00125 if (!m.empty()) {
00126 x = m.pop(); e = x->iter; goto next;
00127 }
00128
00129 return false;
00130 }
00131
00132 template<class View>
00133 forceinline void
00134 Graph<View>::purge(void) {
00135 if (count > (UINT_MAX >> 1)) {
00136 count = 1;
00137 for (int i=n_view; i--; )
00138 view[i]->min = 0;
00139 for (ValNode<View>* v = val; v != NULL; v = v->next_val())
00140 v->min = 0;
00141 }
00142 }
00143
00144 template<class View>
00145 forceinline void
00146 Graph<View>::scc(Space& home) {
00147 Region r(home);
00148
00149 Support::StaticStack<Node<View>*,Region> scc(r,n_val+n_view);
00150 Support::StaticStack<Node<View>*,Region> visit(r,n_val+n_view);
00151
00152 count++;
00153 unsigned int cnt0 = count;
00154 unsigned int cnt1 = count;
00155
00156 for (int i = n_view; i--; )
00157
00158
00159
00160
00161
00162
00163
00164 if (view[i]->min < count-1) {
00165 Node<View>* w = view[i];
00166 start:
00167 w->low = w->min = cnt0++;
00168 scc.push(w);
00169 Edge<View>* e = w->edge_fst();
00170 while (e != w->edge_lst()) {
00171 if (e->dst(w)->min < count) {
00172 visit.push(w); w->iter = e;
00173 w=e->dst(w);
00174 goto start;
00175 }
00176 next:
00177 if (e->dst(w)->low < w->min)
00178 w->min = e->dst(w)->low;
00179 e = e->next();
00180 }
00181 if (w->min < w->low) {
00182 w->low = w->min;
00183 } else {
00184 Node<View>* v;
00185 do {
00186 v = scc.pop();
00187 v->comp = cnt1;
00188 v->low = UINT_MAX;
00189 } while (v != w);
00190 cnt1++;
00191 }
00192 if (!visit.empty()) {
00193 w=visit.pop(); e=w->iter; goto next;
00194 }
00195 }
00196 count = cnt0+1;
00197 }
00198
00199
00200 }}}
00201
00202