// read a graph from the given file, return success bool t_dir_graph::read_format1(istream& input, const string first_line){ string arcs; vector<t_vertex> vert_vec; vector<t_vertex> arc_vec; input >> arcs; tokenize(first_line, vert_vec, ","); tokenize(arcs, arc_vec, "),("); for(uint i=0; i < vert_vec.size(); i++) insert_vertex(vert_vec[i]); size_t arrow_pos = 0; for(uint i=0; i < arc_vec.size(); i++){ if((arrow_pos = arc_vec[i].find("->")) != string::npos){ dbgcout << "arc: " << arc_vec[i].substr(0,arrow_pos) << "," << arc_vec[i].substr(arrow_pos+2) << "\n"; insert_arc(t_arc(arc_vec[i].substr(0,arrow_pos),arc_vec[i].substr(arrow_pos+2))); } else { i++; if(i < arc_vec.size()){ dbgcout << "arc: " << arc_vec[i-1] << "," << arc_vec[i] << "\n"; insert_arc(t_arc(arc_vec[i-1],arc_vec[i])); } } } return true; }
// return all p3 in p3_set with (*,v,*) set<t_3path> t_dir_graph::get_p3_by_middle(const t_vertex& v) const{ set<t_vertex> succ, pred; set<t_3path> result; succ = get_successors(v); pred = get_predecessors(v); for(set<t_vertex>::const_iterator u = pred.begin(); u!= pred.end(); u++) for(set<t_vertex>::const_iterator w = succ.begin(); w!= succ.end(); w++) if(p3_set.find(t_3path(t_arc(*u,v),t_arc(v,*w))) != p3_set.end()) result.insert(t_3path(t_arc(*u,v),t_arc(v,*w))); return result; }
// return all p3 in p3_set with (*,*,v) set<t_3path> t_dir_graph::get_p3_by_third(const t_vertex& v) const{ set<t_vertex> pred, predpred; set<t_3path> result; pred = get_predecessors(v); for(set<t_vertex>::const_iterator u = pred.begin(); u!= pred.end(); u++){ predpred = get_predecessors(*u); for(set<t_vertex>::const_iterator w = predpred.begin(); w!= predpred.end(); w++) if(p3_set.find(t_3path(t_arc(*w,*u),t_arc(*u,v))) != p3_set.end()) result.insert(t_3path(t_arc(*w,*u),t_arc(*u,v))); } return result; }
// return all p3 in p3_set with (v,*,*) set<t_3path> t_dir_graph::get_p3_by_first(const t_vertex& v) const{ set<t_vertex> succ, succsucc; set<t_3path> result; succ = get_successors(v); for(set<t_vertex>::const_iterator u = succ.begin(); u!= succ.end(); u++){ succsucc = get_successors(*u); for(set<t_vertex>::const_iterator w = succsucc.begin(); w!= succsucc.end(); w++) if(p3_set.find(t_3path(t_arc(v,*u),t_arc(*u,*w))) != p3_set.end()) result.insert(t_3path(t_arc(v,*u),t_arc(*u,*w))); } return result; }
void cap_k(t_dir_graph* d, const uint max_k){ t_arc a; set<t_vertex> vertices = d->get_vertices(); uint r; set<t_vertex>::iterator j; t_vertex v; transitive_closure(d); srand(time(NULL)); for(uint i = 0; i < max_k; i++){ do{ // get a random arc r = (uint)floor((((rand()+1)*(double)vertices.size()))/(double)RAND_MAX); j = vertices.begin(); while(r){ r--; j++; } v = *j; r = (uint)floor((((rand()+1)*(double)vertices.size()))/(double)RAND_MAX); j = vertices.begin(); while(r){ r--; j++; } } while(v == *j); a = t_arc(v,*j); if(d->contains_arc(a)) d->delete_arc(a); else d->insert_arc(a); } }
bool t_dir_graph::read_format2(istream& input, const string first_line){ vector<t_vertex> verts; int adj; t_vertex v; uint datas = atoi(first_line.c_str()); while(input.peek() == '\n') input.ignore(1); // read the '\n' // read vertices for(uint i = 0; i < datas; i++){ input >> v; verts.push_back(v); while(input.peek() == '\n') input.ignore(1); // read the '\n' } for(uint i=0; i < verts.size(); i++) insert_vertex(verts[i]); // read adjacency matrix for(uint i=0; i < verts.size(); i++){ for(uint j=0; j < verts.size(); j++){ input >> adj; if(adj > 0) insert_arc(t_arc(verts[i], verts[j])); while(input.peek() == ' ') input.ignore(1); // read the ' ' while(input.peek() == '\n') input.ignore(1); // read the '\n' } } return true; }
// get all arcs set<t_arc> t_dir_graph::get_arcs() const{ set<t_arc> result; for(t_adjtable::const_iterator i = successors.begin(); i != successors.end(); i++) for(t_adjlist::const_iterator j = i->second.begin(); j != i->second.end(); j++) result.insert(t_arc(i->first,*j)); return result; }
void handle::reset() { if(!m_inputMapper)return; //needs an if statement for input types here if(m_inputMapper->getType() == "arcInput") { shared_ptr<arcInput> t_arc(static_pointer_cast <arcInput>(m_inputMapper)); //downcast it ofVec2f p; p.set(m_hook->getPosC()); t_arc->setPosO(m_posC); t_arc->setBoundsDegrees(-90,90); //could be set in a variety of ways (a data structure will be needed) t_arc->setPivot(p); t_arc->reset(); } if(m_inputMapper->getType() == "vecInput") { shared_ptr<vecInput> t_vec(static_pointer_cast <vecInput>(m_inputMapper)); vector<ofVec2f> t_bounds; ofVec2f t_dir(m_posC - m_hook->getPosC()); if(t_dir.length() > 0) { t_vec->setDirGlobal(t_dir.getNormalized()); if(t_dir.length() < 100) { //this can become a parameter later t_bounds.push_back(m_hook->getPosC()); } else { t_bounds.push_back(m_posC - t_vec->getDirGlobal() * 100); } t_bounds.push_back(m_posC + t_vec->getDirGlobal() * 100); } else { t_bounds.push_back(m_posC); t_bounds.push_back(m_posC + t_vec->getDirGlobal() * 100); } t_vec->setBounds(t_bounds[0], t_bounds[1]); t_vec->setPosO(m_posC); t_vec->reset(); } if(m_inputMapper->getType() == "holdInput") { shared_ptr<holdInput> t_hold(static_pointer_cast <holdInput>(m_inputMapper)); //downcast it t_hold->setTime(5.0); t_hold->setIsPingPong(true); t_hold->setBounds(-1, 0.05); } }
// insert an arc // O(n log n) bool t_dir_graph::insert_arc(const t_arc& a, const bool permanent){ if(successors.find(a.second) == successors.end()) return false; // dont insert edges that are not in VxV if(predecessors.find(a.first) == predecessors.end()) return false; // dont insert edges that are not in VxV if(forbidden_arcs.find(a) != forbidden_arcs.end()) return false; // dont insert if the arc is forbidden t_adjtable::iterator i = successors.find(a.first); t_adjtable::iterator j = predecessors.find(a.second); if((i != successors.end()) && (j != predecessors.end())) if(i->second.insert(a.second).second) if(j->second.insert(a.first).second){ if(permanent) mark_arc(a, MRK_PERMANENT); // update p3_set and diamond_set // first, remove all p3 destroyed by a set<t_vertex> belt = set_intersect(i->second,j->second); for(set<t_vertex>::const_iterator u = belt.begin(); u != belt.end(); u++) p3_set.erase(t_3path(t_arc(a.first, *u),t_arc(*u, a.second))); diamond_set.erase(t_diamond(a.first, a.second)); // second, add new P3 and diamonds // u -> a.first -> a.second set<t_vertex> pred = set_substract(get_predecessors(a.first), j->second); pred.erase(a.second); for(set<t_vertex>::const_iterator u = pred.begin(); u != pred.end(); u++){ increase_diamond(t_diamond(*u, a.second)); p3_set.insert(t_3path(t_arc(*u,a.first),a)); } // a.first -> a.second -> u set<t_vertex> succ = set_substract(get_successors(a.second), i->second); succ.erase(a.first); for(set<t_vertex>::const_iterator u = succ.begin(); u != succ.end(); u++){ increase_diamond(t_diamond(a.first, *u)); p3_set.insert(t_3path(a,t_arc(a.second, *u))); } return true; } else {// avoid inconsistency i->second.erase(a.second); return false; } else return false; else return false; }
// print the digraph to a stream void t_dir_graph::print(ostream& output) const{ set<t_vertex> v; set<t_arc> a; for(t_adjtable::const_iterator i = successors.begin(); i != successors.end(); i++){ v.insert(i->first); for(t_adjlist::const_iterator j = i->second.begin(); j != i->second.end(); j++){ a.insert(t_arc(i->first,*j)); } } // print vertex set output << "("; for(set<t_vertex>::const_iterator i = v.begin(); i != v.end(); i++) output << *i << ","; output << "\b)\n"; // print arcs for(set<t_arc>::const_iterator i = a.begin(); i != a.end(); i++) output << *i << ((permanent_arcs.find(*i) == permanent_arcs.end())?",":"!,"); output << "\b"; }
// delete an arc // O(n log n) bool t_dir_graph::delete_arc(const t_arc& a, const bool forbidden){ if(permanent_arcs.find(a) != permanent_arcs.end()) return false; // dont delete if the arc is permanent t_adjtable::iterator i = successors.find(a.first); t_adjtable::iterator j = predecessors.find(a.second); if((i != successors.end()) && (j != predecessors.end())) if(i->second.erase(a.second)) if(j->second.erase(a.first)){ if(forbidden) mark_arc(a, MRK_FORBIDDEN); // update p3_set and diamond_set // first, remove all p3 destroyed by a // u -> a.first -> a.second set<t_vertex> pred = set_substract(get_predecessors(a.first), j->second); pred.erase(a.second); for(set<t_vertex>::const_iterator u = pred.begin(); u != pred.end(); u++){ decrease_diamond(t_diamond(*u,a.second)); p3_set.erase(t_3path(t_arc(*u,a.first),t_arc(a.first, a.second))); } // a.first -> a.second -> u set<t_vertex> succ = set_substract(get_successors(a.second), i->second); succ.erase(a.first); for(set<t_vertex>::const_iterator u = succ.begin(); u != succ.end(); u++){ decrease_diamond(t_diamond(a.first, *u)); p3_set.erase(t_3path(t_arc(a.first, a.second),t_arc(a.second, *u))); } // second, add new P3 and diamonds set<t_vertex> belt = set_intersect(i->second,j->second); for(set<t_vertex>::const_iterator u = belt.begin(); u != belt.end(); u++) p3_set.insert(t_3path(t_arc(a.first, *u),t_arc(*u, a.second))); if(belt.size()>1) diamond_set.insert( pair<t_diamond,uint>(t_diamond(a.first,a.second),belt.size()) ); return true; } else return false; else return false; else return false; }
// mark an arc forbidden/permanent, // note that, if adjacent arcs are also forbidden/permanent, this mark may cascade bool t_dir_graph::mark_arc(const t_arc& a, const uint mark){ if(successors.find(a.first) == successors.end()) return false; // dont mark edges that are not in VxV if(successors.find(a.second) == successors.end()) return false; // dont mark edges that are not in VxV dbgcout << "marking " << a << (mark==MRK_NONE?"none":(mark==MRK_FORBIDDEN?"forbidden":"permanent")) << "\n"; bool result = true; switch(mark){ case MRK_NONE: return (forbidden_arcs.erase(a) || permanent_arcs.erase(a)); break; case MRK_FORBIDDEN: if((!contains_arc(a)) && (forbidden_arcs.find(a) == forbidden_arcs.end()) && forbidden_arcs.insert(a).second) { set<t_vertex> belt = set_intersect(get_successors(a.first), get_predecessors(a.second)); for(set<t_vertex>::iterator u = belt.begin(); u != belt.end(); u++){ if(permanent_arcs.find(t_arc(a.first, *u)) != permanent_arcs.end()) result &= mark_arc(t_arc(*u, a.second), MRK_FORBIDDEN); if(permanent_arcs.find(t_arc(*u, a.second)) != permanent_arcs.end()) result &= mark_arc(t_arc(a.first, *u), MRK_FORBIDDEN); } return result; } else return false; break; case MRK_PERMANENT: if(contains_arc(a) && (permanent_arcs.find(a) == permanent_arcs.end()) && permanent_arcs.insert(a).second) { set<t_vertex> pred = get_predecessors(a.first); for(set<t_vertex>::iterator u = pred.begin(); u != pred.end(); u++){ if(permanent_arcs.find(t_arc(*u, a.first)) != permanent_arcs.end()) result &= mark_arc(t_arc(*u, a.second), MRK_PERMANENT); } pred = set_substract(get_vertices(), get_predecessors(a.second)); for(set<t_vertex>::iterator u = pred.begin(); u != pred.end(); u++){ if(forbidden_arcs.find(t_arc(*u, a.second)) != forbidden_arcs.end()) result &= mark_arc(t_arc(*u, a.second), MRK_FORBIDDEN); } set<t_vertex> succ = get_successors(a.second); for(set<t_vertex>::iterator u = succ.begin(); u != succ.end(); u++){ if(permanent_arcs.find(t_arc(a.second, *u)) != permanent_arcs.end()) result &= mark_arc(t_arc(a.first, *u), MRK_PERMANENT); } succ = set_substract(get_vertices(), get_successors(a.first)); for(set<t_vertex>::iterator u = succ.begin(); u != succ.end(); u++){ if(forbidden_arcs.find(t_arc(a.first, *u)) != forbidden_arcs.end()) result &= mark_arc(t_arc(a.second, *u), MRK_FORBIDDEN); } return result; } else return false; break; default: return false; } }