/* * Main authors: * Grégoire Dooms * * Copyright: * Grégoire Dooms (Université catholique de Louvain), 2005 * * Last modified: * $Date: 2006-01-26 14:18:00 +0100 (Thu, 26 Jan 2006) $ * $Revision: 318 $ * * This file is part of CP(Graph) * * See the file "contribs/graph/LICENSE" for information on usage and * redistribution of this file, and for a * DISCLAIMER OF ALL WARRANTIES. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "graph.hh" #undef TRACE #define TRACE(A) //using namespace boost; //using namespace std; namespace Gecode { namespace Graph { OutAdjSetsGraphView::OutAdjSetsGraphView(void){ } OutAdjSetsGraphView::OutAdjSetsGraphView(const OutAdjSetsGraphView& x): nodes(x.nodes), outN(x.outN){ } OutAdjSetsGraphView::OutAdjSetsGraphView(Space *home, SetVar nodes, SetVarArray outN): nodes(nodes), outN(outN){ arcImpliesNodes(home); } OutAdjSetsGraphView::OutAdjSetsGraphView(Space * home, int numNodes):nodes(home,IntSet::empty,0,numNodes-1), outN(home, numNodes, IntSet::empty, 0, numNodes-1) { arcImpliesNodes(home); } OutAdjSetsGraphView::OutAdjSetsGraphView(Space *home, const pair,vector > >& graph){ //FIXME node values ignored, still have to translate nodes to [0, numNodes-1] const vector >& arcs = graph.second; std::vector >::const_iterator it; int numNodes = graph.first.size(); for (it = arcs.begin(); it != arcs.end(); ++it){ assert(it->first < numNodes); assert(it->second < numNodes); } typedef std::vector > al; al out(numNodes); for (it= arcs.begin(); it!= arcs.end(); ++it){ TRACE(cout <<"arc("<first<<","<second<<")"); out[it->first].push_back(it->second); } TRACE(cout < vals(out[i].size()); int j=0; for (list::const_iterator k=out[i].begin(); k!=out[i].end(); ++k,++j){ vals[j] = *k; } IntSet a(&vals[0], out[i].size()); Gecode::Set::SetView s(outN[i]); Gecode::IntSetRanges ar(a) ; GECODE_ME_FAIL(home,s.intersectI(home, ar )); } TRACE(cout << "upperbounds set up" < no incoming arc, arc -> target node*/ for (int i=numNodes; i--;){ TRACE(cout<node 1 set up" < no outgoing arc, arc -> source node*/ BoolVar True(home,1,1); for (int i=0 ; inode 2 set up" <failed()) return; int numNodes = outN.size() ; for (int i=0; ifailed()) return; //not reached assert(outN[i].assigned()); } Set::SetView v(nodes); GECODE_ME_FAIL(home,v.cardMin(home,v.cardMax())); if (home->failed()) return; //not reached assert(nodes.assigned()); } /** Stuff for propagators */ /** Returns the PropCond for the nodes and the arcs according to the graph propCond*/ std::pair OutAdjSetsGraphView::pc_g_to_set(PropCond pc){ return make_pair(Set::PC_SET_ANY,Set::PC_SET_ANY); } /** subscribes all implem variables with the propagator */ void OutAdjSetsGraphView::subscribe(Space* home, Propagator* p, PropCond pc){ PropCond npc,apc; boost::tie(npc,apc) = pc_g_to_set(pc); VarArgArray outNVA(outN); ViewArray outNV(home,outNVA); outNV.subscribe(home,p,apc); Set::SetView nodesV(nodes); nodesV.subscribe(home,p,npc); } void OutAdjSetsGraphView::cancel(Propagator* p, PropCond pc){ int numNodes = outN.size(); PropCond npc,apc; boost::tie(npc,apc) = pc_g_to_set(pc); for (int i=numNodes;--i; ){ Set::SetView outNiV(outN[i]); outNiV.cancel(p,apc); } // outNV.cancel(p,apc); // not possible because building a ViewArray from a VarArgArray needs the home Set::SetView nodesV(nodes); nodesV.cancel(p,npc); } void OutAdjSetsGraphView::update(Space* home, bool share, OutAdjSetsGraphView& x){ outN.update(home, share, x.outN); nodes.update(home, share, x.nodes); } /* basic tells for propagators */ forceinline ModEvent OutAdjSetsGraphView::_arcIn(Space* home, int a, int b){ #ifdef CPGCHECKTELLS bool in = && ! arcIsInLB(a,b); if (! arcIsInUB(a,b)){ TRACE(cout << "returning arcIn" << a << " "<< b<< " ME_GRAPH_FAILED"<< endl); return Set::ME_GRAPH_FAILED; } //XXX if (arcIsInLB(a,b)){ TRACE(cout << "returning arcIn" << a << " "<< b<< " ME_GRAPH_NONE"<< endl); return Set::ME_GRAPH_NONE; } //XXX #endif Set::SetView v(outN[a]); return v.include(home,b); } forceinline ModEvent OutAdjSetsGraphView::_arcOut(Space* home, int a, int b){ #ifdef CPGCHECKTELLS if (arcIsInLB(a,b)){ TRACE(cout << "returning arcOut" << a << " "<< b<< " ME_GRAPH_FAILED"<< endl); return Set::ME_GRAPH_FAILED; } //XXX if (!arcIsInUB(a,b)){ TRACE(cout << "returning arcOut" << a << " "<< b<< " ME_GRAPH_NONE"<< endl); return Set::ME_GRAPH_NONE; } //XXX #endif Set::SetView v(outN[a]); return v.exclude(home,b); } forceinline ModEvent OutAdjSetsGraphView::_nodeIn(Space* home, int a){ #ifdef CPGCHECKTELLS if (!nodeIsInUB(a)){ TRACE(cout << "returning nodeIn" << a << " ME_GRAPH_FAILED"<< endl); return Set::ME_GRAPH_FAILED; } //XXX if (nodeIsInLB(a)){ TRACE(cout << "returning nodeIn" << a << " ME_GRAPH_NONE"<< endl); return Set::ME_GRAPH_NONE; } //XXX #endif Set::SetView v(nodes); return v.include(home,a); } forceinline ModEvent OutAdjSetsGraphView::_nodeOut(Space* home, int a){ #ifdef CPGCHECKTELLS if (nodeIsInLB(a)){ TRACE(cout << "returning nodeOut" << a << " ME_GRAPH_FAILED"<< endl); return Set::ME_GRAPH_FAILED; } //XXX if (!nodeIsInUB(a)){ TRACE(cout << "returning nodeOut" << a << " ME_GRAPH_NONE"<< endl); return Set::ME_GRAPH_NONE; } //XXX #endif Set::SetView v(nodes); return v.exclude(home,a); } /// \brief includes all the arcs in the lower bound of the graph template ModEvent OutAdjSetsGraphView::_arcsIn(Space * home, I& i){ if (!i()) {return Gecode::Graph::ME_GRAPH_NONE; } int t,h; boost::tie(t,h) = i.val(); ModEvent me=Gecode::Graph::ME_GRAPH_NONE; while (i()){ int cur_t = t; list heads; while (t==cur_t){ heads.push_back(h); ++i; if (!i()) break; boost::tie(t,h) = i.val(); } // either !i() or t,h is new pair with t!= cur_t Set::SetView v(outN[cur_t]); StlToGecodeValIterator::iterator> iv(heads.begin(),heads.end()); Iter::Values::ToRanges::iterator> > r(iv); ModEvent me1 = v.includeI(home,r); GECODE_ME_CHECK(me1); if (me_modified(me1)) me = Gecode::Graph::ME_GRAPH_GLB; } return me; } /// \brief excludes all the arcs from the upper bound of the graph template ModEvent OutAdjSetsGraphView::_arcsOut(Space * home, I& i){ if (!i()) {return Gecode::Graph::ME_GRAPH_NONE; } int t,h; boost::tie(t,h) = i.val(); ModEvent me=Gecode::Graph::ME_GRAPH_NONE; while (i()){ int cur_t = t; list heads; while (t==cur_t){ heads.push_back(h); ++i; if (!i()) break; boost::tie(t,h) = i.val(); } // either !i() or t,h is new pair with t!= cur_t Set::SetView v(outN[cur_t]); StlToGecodeValIterator::iterator> iv(heads.begin(),heads.end()); Iter::Values::ToRanges::iterator> > r(iv); ModEvent me1 = v.excludeI(home,r); GECODE_ME_CHECK(me1); if (me_modified(me1)) me = Gecode::Graph::ME_GRAPH_LUB; } return me; } /// \brief includes all the nodes in the lower bound of the graph template ModEvent OutAdjSetsGraphView::_nodesIn(Space * home, I& i){ Iter::Values::ToRanges r(i); Set::SetView v(nodes); return v.includeI(home,r); } /// \brief excludes all the nodes from the upper bound of the graph template ModEvent OutAdjSetsGraphView::_nodesOut(Space * home, I& i){ Iter::Values::ToRanges r(i); Set::SetView v(nodes); return v.excludeI(home,r); } /// \brief Arc iterator for the OutAdjSetsGraphView template class OutAdjSetsGraphView::_int_pair_gecode_iterator_outn { OutAdjSetsGraphView *gp; int N; int numNodes; Iter::Ranges::ToValues outNIter; public: _int_pair_gecode_iterator_outn(OutAdjSetsGraphView *g): gp(g),N(0), numNodes(gp->outN.size()) { It it(g->outN[N]); outNIter = Iter::Ranges::ToValues(it); } bool operator() (void) { // has next while (!outNIter() && NoutN[N]); outNIter = Iter::Ranges::ToValues(it); } return outNIter(); } pair val (void){ return make_pair(N,outNIter.val()); } void operator++ (void){ // go to next ++outNIter; } }; forceinline OutAdjSetsGraphView::GlbArcIterator OutAdjSetsGraphView::iter_arcs_LB() { OutAdjSetsGraphView::GlbArcIterator it(this); return it; } forceinline OutAdjSetsGraphView::LubArcIterator OutAdjSetsGraphView::iter_arcs_UB() { OutAdjSetsGraphView::LubArcIterator it(this); return it; } forceinline OutAdjSetsGraphView::GlbNodeRangesIterator OutAdjSetsGraphView::iter_nodes_ranges_LB(){ SetVarGlbRanges l(nodes); return l; } forceinline OutAdjSetsGraphView::LubNodeRangesIterator OutAdjSetsGraphView::iter_nodes_ranges_UB(){ SetVarLubRanges u(nodes); return u; } forceinline OutAdjSetsGraphView::GlbNodeIterator OutAdjSetsGraphView::iter_nodes_LB(){ SetVarGlbRanges l(nodes); Iter::Ranges::ToValues lv(l) ; return lv; } forceinline OutAdjSetsGraphView::LubNodeIterator OutAdjSetsGraphView::iter_nodes_UB(){ SetVarLubRanges u(nodes); Iter::Ranges::ToValues uv(u); return uv; } /* Reflexion */ int OutAdjSetsGraphView::lubOrder(){ return nodes.lubSize(); } int OutAdjSetsGraphView::glbOrder(){ return nodes.glbSize(); } int OutAdjSetsGraphView::lubSize(){ int sum = 0; for (int i=outN.size(); --i;) sum += outN[i].lubSize(); return sum; } int OutAdjSetsGraphView::glbSize(){ int sum = 0; for (int i=outN.size(); --i;) sum += outN[i].glbSize(); return sum; } int OutAdjSetsGraphView::maxNodeId(){ return nodes.lubMax(); } bool OutAdjSetsGraphView::nodeIsInUB(int a){ return !nodes.notContains(a); } bool OutAdjSetsGraphView::nodeIsInLB(int a){ return nodes.contains(a); } bool OutAdjSetsGraphView::arcIsInUB(int a, int b){ return ! outN[a].notContains(b); } bool OutAdjSetsGraphView::arcIsInLB(int a, int b){ return outN[a].contains(b); } void OutAdjSetsGraphView::inNeighboursUB(int a, vector &nei){ int numNodes = outN.size(); nei.clear(); for (int i=0 ; i &nei){ int numNodes = outN.size(); nei.clear(); for (int i=0 ; i &nei){ SetVarLubRanges i(outN[a]); nei.clear(); while(i()){ for (int j=i.min(); j<=i.max(); ++j) { nei.push_back(j); } ++i; } } void OutAdjSetsGraphView::outNeighboursLB(int a, vector &nei){ SetVarGlbRanges i(outN[a]); nei.clear(); while(i()){ for (int j=i.min(); j<=i.max(); ++j) nei.push_back(j); ++i; } } int OutAdjSetsGraphView::inDegreeUB(int a ){ int numNodes = outN.size(); int d=0; for (int i=0 ; i,vector,vector >,vector > > OutAdjSetsGraphView::get_domain(){ //Return values int numNodes = outN.size(); vector nL; vector nU; vector > aL; vector > aU; SetVarLubRanges nodesU(nodes); Iter::Ranges::ToValues nodesUV(nodesU); for (;nodesUV();++nodesUV){ nU.push_back(nodesUV.val()); } SetVarGlbRanges nodesL(nodes); Iter::Ranges::ToValues nodesLV(nodesL); for (;nodesLV();++nodesLV){ nL.push_back(nodesLV.val()); } for (int tail=0; tail < numNodes; tail++){ SetVarLubRanges outNU(outN[tail]); Iter::Ranges::ToValues outNUV(outNU); for (;outNUV();++outNUV){ aU.push_back(make_pair(tail,outNUV.val())); } SetVarGlbRanges outNL(outN[tail]); Iter::Ranges::ToValues outNLV(outNL); for (;outNLV();++outNLV){ aL.push_back(make_pair(tail,outNLV.val())); } } return boost::make_tuple(nL,nU,aL,aU); } } } /** * \brief Print graph variable view * \relates Gecode::Graph::OutAdjSetsGraphView * defined in the top-level namespace */ std::ostream& operator<<(std::ostream& os, const Gecode::Graph::OutAdjSetsGraphView& g){ os <<"########## Graph #########"<