Пример #1
0
//=================================================================
bool BiconnectedTest::compute(const tlp::Graph* graph) {
  if(graph->numberOfNodes() == 0) {
    return true;
  }

  if (resultsBuffer.find(graph)!=resultsBuffer.end())
    return resultsBuffer[graph];

  MutableContainer<bool> mark;
  mark.setAll(false);
  MutableContainer<unsigned int> low;
  MutableContainer<unsigned int> dfsNumber;
  MutableContainer<node> supergraph;
  unsigned int count = 1;
  bool result = false;
  Iterator<node> *it=graph->getNodes();

  if (it->hasNext())
    result=(biconnectedTest(graph,it->next(),mark,low,dfsNumber,supergraph,count));

  delete it;

  if (count!=graph->numberOfNodes()+1) {
    result=false;
  } //connected test

  resultsBuffer[graph]=result;
  graph->addListener(this);
  return result;
}
Пример #2
0
unsigned int getDist(Graph *g, node n1, node n2) {
  vector<node> nextNodes;
  TLP_HASH_MAP<node, unsigned int> nodeDepth;
  MutableContainer<bool> alreadyTreated;
  bool found = false;
  alreadyTreated.setAll(false);
  nextNodes.push_back(n1);
  nodeDepth[n1] = 0;
  alreadyTreated.set(n1.id, true);

  for (unsigned int i = 0; !found && i < nextNodes.size(); ++i) {
    node current = nextNodes[i];

    for (auto v : g->getInOutNodes(current)) {

      if (alreadyTreated.get(v.id))
        continue;

      alreadyTreated.set(v.id, true);
      nextNodes.push_back(v);
      nodeDepth[v] = nodeDepth[current] + 1;

      if (v == n2) {
        found = true;
        break;
      }
    }
  }

  return nodeDepth[n2];
}
Пример #3
0
//=================================================================
list<edge> posDFS(Graph *sG, MutableContainer<int> &dfsPos) {
  list<edge> dfsEdges;
  MutableContainer<int> dfsPre;
  dfsPre.setAll(0);
  unsigned int preCount = 0;
  unsigned int postCount = 0;
  for (auto n : sG->nodes()) {
    if (dfsPre.get(n.id) == 0)
      dfsAux(sG, n, dfsPre, dfsPos, dfsEdges, preCount, postCount);
  }

  return dfsEdges;
}
Пример #4
0
// Determines if the given graph is topologically a tree
bool TreeTest::isFreeTree(const Graph *graph, node curRoot) {
  // do a dfs traversal from curRoot;
  MutableContainer<bool> visited;
  visited.setAll(false);
  stack<dfsFreeTreeStruct> dfsLevels;
  dfsFreeTreeStruct curParams(curRoot, curRoot, graph->getInOutNodes(curRoot));
  dfsLevels.push(curParams);

  while (!dfsLevels.empty()) {
    curParams = dfsLevels.top();
    curRoot = curParams.curRoot;
    node cameFrom = curParams.cameFrom;
    Iterator<node> *neighbours = curParams.neighbours;
    // set neighbours member to nullptr
    // to avoid twice deletion on exit
    curParams.neighbours = nullptr;

    if (!neighbours->hasNext()) {
      dfsLevels.pop();
    } else {
      visited.set(curRoot.id, true);

      // loop on remaining neighbours
      while (neighbours->hasNext()) {
        node curNode = neighbours->next();

        // check self loop
        if (curNode == curRoot) {
          return false;
        }

        if (curNode != cameFrom) {
          if (visited.get(curNode.id)) {
            return false;
          }

          // go deeper in the dfs exploration
          curParams.curRoot = curNode;
          curParams.cameFrom = curRoot;
          curParams.neighbours = graph->getInOutNodes(curNode);
          dfsLevels.push(curParams);
          break;
        }
      }
    }
  }

  return true;
} // end isFreeTree
Пример #5
0
//====================================================
void EdgeExtremityGlyphManager::initGlyphList(Graph **graph,
    GlGraphInputData* glGraphInputData, MutableContainer<
    EdgeExtremityGlyph *>& glyphs) {
  GlyphContext gc = GlyphContext(graph,
                                 glGraphInputData);
  glyphs.setAll(0);


  static std::list<std::string> plugins = PluginLister::instance()->availablePlugins<EdgeExtremityGlyph>();

  for(std::list<std::string>::const_iterator it = plugins.begin(); it != plugins.end(); ++it) {
    string glyphName = *it;
    EdgeExtremityGlyph *newGlyph = PluginLister::instance()->getPluginObject<EdgeExtremityGlyph>(glyphName, &gc);
    glyphs.set(PluginLister::pluginInformation(glyphName).id(), newGlyph);
  }
}
Пример #6
0
//=================================================================
list<edge> posDFS(Graph *sG,
                  MutableContainer<int> &dfsPos) {
  list<edge> dfsEdges;
  MutableContainer<int> dfsPre;
  dfsPre.setAll(0);
  preCount = postCount = 1;
  StableIterator<node> it(sG->getNodes());

  while (it.hasNext()) {
    node n = it.next();

    if (dfsPre.get(n.id) == 0)
      dfsAux(sG, n, dfsPre, dfsPos, dfsEdges);
  }

  return dfsEdges;
}
Пример #7
0
/**
 *  \brief Set the ordering of edges around n according to their order in v.
 */
void GraphStorage::setEdgeOrder(const node n, const std::vector<edge> &v ) {
  if (v.empty()) return;

  MutableContainer<int> isEle;
  isEle.setAll(0);

  for (std::vector<edge>::const_iterator it=v.begin(); it!=v.end(); ++it) {
    isEle.add(it->id, 1);
  }

  std::vector<edge>::const_iterator it2=v.begin();
  EdgeVector& currentOrder = nodes[n.id].edges;

  for (unsigned int i=0; i<currentOrder.size(); ++i) {
    if ( isEle.get(currentOrder[i].id)>0 ) {
      isEle.add(currentOrder[i].id, -1);
      currentOrder[i] = *it2;
      ++it2;
    }
  }
}
    bool run() {
        result->setAllNodeValue(0.0);
        result->setAllEdgeValue(0.0);
        bool directed = false;
        bool norm = false;

        if ( dataSet!=NULL ) {
            dataSet->get("directed",directed);
            dataSet->get("norm", norm);
        }

        //Metric is 0 in this case
        if(graph->numberOfNodes()<=2) return true;

        Iterator<node> *it = graph->getNodes();
        unsigned int count = 0;

        while(it->hasNext()) {
            if (pluginProgress->progress(count++,graph->numberOfNodes())!=TLP_CONTINUE) break;

            node s = it->next();
            stack<node> S;
            TLP_HASH_MAP<node, list<node> > P;
            MutableContainer<int> sigma;
            sigma.setAll(0);
            sigma.set(s.id,1);
            MutableContainer<int> d;
            d.setAll(-1);
            d.set(s.id, 0);
            queue<node> Q;
            Q.push(s);

            while(!Q.empty()) {
                node v = Q.front();
                Q.pop();
                S.push(v);
                Iterator<node> *it2;

                if (directed)
                    it2 = graph->getOutNodes(v);
                else
                    it2 = graph->getInOutNodes(v);

                while (it2->hasNext()) {
                    node w = it2->next();

                    if (d.get(w.id)<0) {
                        Q.push(w);
                        d.set(w.id, d.get(v.id)+1);
                    }

                    if (d.get(w.id) == d.get(v.id)+1) {
                        sigma.add(w.id, sigma.get(v.id));
                        P[w].push_back(v);
                    }
                }

                delete it2;
            }

            MutableContainer<double> delta;
            delta.setAll(0.0);

            while(!S.empty()) {
                node w = S.top();
                S.pop();
                list<node>::const_iterator itn = P[w].begin();

                for (; itn!=P[w].end(); ++itn) {
                    node v = *itn;
                    delta.add(v.id, (double(sigma.get(v.id)) / double(sigma.get(w.id)) * (1.0 + delta.get(w.id))));
                    edge e  = graph->existEdge(v,w,directed);

                    if(e.isValid())
                        result->setEdgeValue(e, result->getEdgeValue(e) + double(sigma.get(v.id)) / double(sigma.get(w.id)) * (1.0 + delta.get(w.id)));
                }

                if (w != s) result->setNodeValue(w, result->getNodeValue(w) + delta.get(w.id));
            }
        }

        delete it;

        //Normalization
        if(norm || !directed) {
            double n = graph->numberOfNodes();
            it = graph->getNodes();

            while(it->hasNext()) {
                node s = it->next();

                //In the undirected case, the metric must be divided by two, then
                if(norm)
                    result->setNodeValue(s,result->getNodeValue(s)/((n-1.0)*(n-2.0)));

                if(!directed)
                    result->setNodeValue(s,result->getNodeValue(s)/2.0);
            }

            delete it;

            Iterator<edge> *itE = graph->getEdges();

            while(itE->hasNext()) {
                edge e = itE->next();

                if(norm)
                    result->setEdgeValue(e,4.0*result->getEdgeValue(e)/(n*n));

                if(!directed)
                    result->setEdgeValue(e,result->getEdgeValue(e)/(2.0));
            }

            delete itE;
        }


        return pluginProgress->state()!=TLP_CANCEL;
    }
Пример #9
0
/*
 * Algebric criteria to check the plane map...
 */
bool PlanarityTestImpl::isPlanarEmbedding(Graph *sG) {
  int n = sG->numberOfNodes();

  if (n == 1)
    return true;

  int m = sG->numberOfEdges();
  unsigned int count = 0;
  MutableContainer<char> considered;
  MutableContainer<bool> sens;
  considered.setAll(0);
  sens.setAll(false);
  int fc = 0;

  //  displayMap(sG);
  for (int k=0; k<2; ++k) {
    Iterator<edge> *it = sG->getEdges();

    while (it->hasNext()) {
      edge e = it->next();

      if (considered.get(e.id)<2) {
        count = 0;
        //      cerr << "Face : " << fc << " start edge:" << e.id << endl;
        edge e1 = e;
        node n, n_tmp;

        if (sens.get(e.id))
          n = sG->target(e1);
        else
          n = sG->source(e1);

        //      cerr << "-(" << e1.id << ")->" << n.id << flush;
        n_tmp = n;

        do {
          considered.add(e1.id, 1);
          EdgeMapIterator it(sG, e1, n);
          e1 = it.next();
          n = sG->opposite(e1,n);

          if (sG->source(e1) == n)
            sens.set(e1.id,true);

          //  cerr << "-(" << e1.id << ")->" << n.id << flush;
          ++count;

          if (count > sG->numberOfEdges() +1) break;
        }
        while ((e1 != e)||(n != n_tmp));

        fc++;
        //  cerr << endl;
      }
    }

    delete it;
  }

  if (fc != m - n + 2) {
    //cerr << __PRETTY_FUNCTION__ << " : not ok :( nb faces :" << fc << "!=" << m - n +2 << endl;
    return false;
  }

  return true;
}
Пример #10
0
//#include <tulip/GraphImpl.h>
int PlanarityTestImpl::sortBackEdgesByDfs(Graph *sG,
    node,
    node repr,
    list<edge>& listBackEdges,
    vector<edge>& backEdge) {
  // constructs a DFS tree of T_v^* to sort back-edges to embed;
  //  cerr << __PRETTY_FUNCTION__ << endl;
  Graph *D = tlp::newGraph();

  list<node> listNodes, listCNodes;
  //map<node, node> nodeInD, nodeInG;
  map<node,node> nodeInD, nodeInG;

  nodeInD[repr] = D->addNode();
  nodeInG[nodeInD[repr]] = repr;

  // forall(e, listBackEdges)
  for (list<edge>::iterator it = listBackEdges.begin(); it != listBackEdges.end(); it++) {
    edge e = *it;
    node u = sG->source(e);
    node predU = NULL_NODE;

    while (state.get(u.id) == NOT_VISITED) {
      if (isCNode(u)) {
        u = activeCNodeOf(false, u);

        if (state.get(u.id) == NOT_VISITED)
          listCNodes.push_back(u);
      }

      if (state.get(u.id) == NOT_VISITED) {
        state.set(u.id, VISITED);
        listNodes.push_back(u);
        nodeInD[u] = D->addNode();
        nodeInG[nodeInD[u]] = u;
      }

      if (predU != NULL_NODE)
        D->addEdge(nodeInD[u], nodeInD[predU]);

      predU = u;
      u = parent.get(u.id);
    }

    if (predU != NULL_NODE)
      D->addEdge(nodeInD[u], nodeInD[predU]);
  }

  //forall(v, listNodes)
  for (list<node>::iterator it = listNodes.begin() ; it != listNodes.end() ; it++)
    state.set((*it).id, NOT_VISITED);

  // creates  edges from c-nodes;
  map<node, bool> isInD;

  //forall(v, listCNodes)
  for (list<node>::iterator it = listCNodes.begin(); it != listCNodes.end(); it++) {
    node v = *it;
    //    node u;
    BmdListIt<node> bmItn(RBC[v]);

    while(bmItn.hasNext())
      isInD[bmItn.next()] = false;

    list<edge> el;
    StableIterator<edge> stableEdgeIt(D->getOutEdges(nodeInD[v]));

    while (stableEdgeIt.hasNext()) {
      edge e = stableEdgeIt.next();
      isInD[nodeInG[D->target(e)]] = true;
      el.push_back(e);
    }

    //D.del_edges(el);
    for (list<edge>::iterator edgeIt = el.begin() ; edgeIt != el.end() ; ++edgeIt)
      D->delEdge(*edgeIt);

    BmdListRevIt<node> itR(RBC[v]);

    while (itR.hasNext()) {
      node u = itR.next();

      if(isInD[u])
        D->addEdge(nodeInD[v], nodeInD[u]);
    }
  }

  // orders back-edges by DFS number;
  //node_array<int> dfspos(D, 0);
  MutableContainer<int> dfsPos;
  dfsPos.setAll(0);

  posDFS(D, dfsPos);
  int tot = D->numberOfNodes();
  backEdge.resize(tot + 1); //Warning
  backEdge[0] = NULL_EDGE;

  for (int i = 1 ; i <= tot ; i++)
    backEdge[i] = NULL_EDGE;

  //forall(e, listBackEdges)
  for (list<edge>::iterator it = listBackEdges.begin() ; it != listBackEdges.end() ; ++it) {
    edge e = *it;
    node v = sG->source(e);
//     cout << v.id << endl;
//     cout << "nodeInD[v].id = " << nodeInD.get(v.id).id << endl;
//     cout << "dfsPos.get(nodeInD[v].id) = " << dfsPos.get(nodeInD.get(v.id).id) << endl;
    backEdge[dfsPos.get(nodeInD[v].id)] = e;
  }

  delete D;
  return tot;
}
Пример #11
0
/**
 * update is_selectable_visited and is_selectable
 */
void Ordering::updateNewSelectableNodes(node node_f, node no_tmp2 ,edge, node node_last, vector<Face> v_faces, bool one_face,bool was_visited, bool selection_face) {
  MutableContainer<bool> tried;
  tried.setAll(false);
  node n = node_f;
  node tmp = no_tmp2;
  node tmp2 = node() ;
  unsigned int lim = v_faces.size();

  while(n != node_last) {
    tmp2 = n;

    if(Gp->deg(n) > 2 && isSelectable(n)) {
      if(visitedNodes.get(n.id))
        is_selectable_visited.set(n.id,true);
      else
        is_selectable.set(n.id,true);
    }
    else {
      is_selectable_visited.set(n.id,false);
      is_selectable.set(n.id,false);
    }

    tried.set(n.id,true);
    n = tmp;
    tmp = right.get(n.id);
  }

  if(Gp->deg(n) > 2 && isSelectable(n))
    is_selectable_visited.set(n.id,true);
  else {
    is_selectable_visited.set(n.id,false);
    is_selectable.set(n.id,false);
  }

  if(one_face) {
    if(tmp2 == node())
      tmp2 = node_f;

    Iterator<node> * it_no = Gp->getFaceNodes(Gp->getFaceContaining(tmp2,node_last));

    while(it_no->hasNext()) {
      node no_tmp = it_no->next();

      if(!tried.get(no_tmp.id)) {
        bool on_c = contour.get(no_tmp.id);

        if(on_c) {
          bool sel = isSelectable(no_tmp);

          if(sel)
            if(visitedNodes.get(no_tmp.id))
              is_selectable_visited.set(no_tmp.id,true);
            else
              is_selectable.set(no_tmp.id, true);
          else {
            is_selectable_visited.set(no_tmp.id,false);
            is_selectable_visited.set(no_tmp.id,false);
          }
        }

        tried.set(no_tmp.id,true);
      }
    }

    delete it_no;
    lim--;
  }

  if((selection_face && was_visited) || !selection_face)
    for(unsigned int i = 0; i < lim; ++i) {
      bool face_sel = false;
      Face  f_tmp = v_faces[i];

      if(is_selectable_face.get(f_tmp.id) || is_selectable_visited_face.get(f_tmp.id))
        face_sel = true;

      Iterator<node> * itn = Gp->getFaceNodes(f_tmp);

      if(face_sel)
        while(itn->hasNext()) {
          node no_tmp = itn->next();
          is_selectable.set(no_tmp.id,false);
          is_selectable_visited.set(no_tmp.id,false);
          tried.set(no_tmp.id,true);
        }
      else {
        while(itn->hasNext()) {
          node no_tmp = itn->next();

          if(!tried.get(no_tmp.id) && (is_selectable_visited.get(no_tmp.id) || is_selectable.get(no_tmp.id))) {
            if(!isSelectable(no_tmp)) {
              is_selectable_visited.set(no_tmp.id,false);
              is_selectable.set(no_tmp.id,false);
            }
          }

          tried.set(no_tmp.id,true);
        }
      }

      delete itn;
    }
}
Пример #12
0
static void makeBiconnectedDFS(Graph *graph, vector<edge> &addedEdges) {
  // the graph is already connected
  // so get any node to begin
  node from = graph->getOneNode();

  if (!from.isValid())
    return;

  MutableContainer<int> low;
  MutableContainer<int> depth;
  depth.setAll(-1);
  MutableContainer<node> supergraph;
  supergraph.setAll(node());

  // dfs loop
  stack<dfsBiconnectStruct> dfsLevels;
  dfsBiconnectStruct dfsParams(graph, from);
  dfsLevels.push(dfsParams);
  depth.set(from.id, 0);
  low.set(from.id, 0);

  while(!dfsLevels.empty()) {
    dfsParams = dfsLevels.top();
    from = dfsParams.from;
    node u = dfsParams.first;

    //for every node connected to from
    Iterator<node>* itN = dfsParams.inOutNodes;

    while (itN->hasNext()) {
      node to = itN->next();

      //if there is a loop, ignore it
      if (from == to) {
        continue;
      }

      if (!u.isValid()) {
        dfsLevels.top().first = u = to;
      }

      //if the destination node has not been visited, visit it
      if (depth.get(to.id) == -1) {
        supergraph.set(to.id, from);
        dfsParams.from = to;
        dfsParams.first = node();
        dfsParams.u = u;
        unsigned int currentDepth = dfsParams.depth + 1;
        dfsParams.depth = currentDepth;
        depth.set(to.id, currentDepth);
        low.set(to.id, currentDepth);
        dfsParams.inOutNodes = new StableIterator<node>(graph->getInOutNodes(to));
        break;
      }
      else {
        low.set(from.id, std::min(low.get(from.id), depth.get(to.id)));
      }
    }

    if (from != dfsParams.from) {
      dfsLevels.push(dfsParams);
      continue;
    }

    delete itN;

    // pop the current dfsParams
    node to = dfsParams.from;
    from = supergraph.get(to.id);
    u = dfsParams.u;

    if (low.get(to.id) == depth.get(from.id)) {
      if (to == u && supergraph.get(from.id).isValid())
        addedEdges.push_back(graph->addEdge(to, supergraph.get(from.id)));

      if (to != u)
        addedEdges.push_back(graph->addEdge(u, to));
    }

    low.set(from.id, std::min(low.get(from.id), low.get(to.id)));

    dfsLevels.pop();
  }
}
Пример #13
0
//**********************************************************************
bool AcyclicTest::acyclicTest(const Graph *graph, vector<edge> *obstructionEdges) {
  MutableContainer<bool> visited;
  MutableContainer<bool> finished;
  visited.setAll(false);
  finished.setAll(false);
  bool result = true;
  // do a dfs traversal
  Iterator<node> *it = graph->getNodes();

  while (it->hasNext()) {
    node curNode = it->next();

    if (!visited.get(curNode.id)) {
      stack<node> nodesToVisit;
      nodesToVisit.push(curNode);
      stack<Iterator<edge>*> neighboursToVisit;
      neighboursToVisit.push(graph->getOutEdges(curNode));

      while(!nodesToVisit.empty()) {
        curNode = nodesToVisit.top();
        Iterator<edge> *ite = neighboursToVisit.top();

        // check if dfs traversal of curNode neighbours is finished
        if (!ite->hasNext()) {
          // unstack curNode
          nodesToVisit.pop();
          // delete & unstack neightbours iterator
          delete neighboursToVisit.top();
          neighboursToVisit.pop();
          // mark curNode as to be skipped
          // during further exploration
          finished.set(curNode.id, true);
        }
        else {
          visited.set(curNode.id, true);

          // loop on remaining neighbours
          while (ite->hasNext()) {
            edge tmp = ite->next();
            node neighbour = graph->target(tmp);

            // check if we are already in the exploration
            // of the neighbours of neighbour
            if (visited.get(neighbour.id)) {
              if (!finished.get(neighbour.id)) {
                // found a cycle
                result = false;

                if (obstructionEdges != NULL)
                  obstructionEdges->push_back(tmp);
                else {
                  // it is finished if we don't need
                  // to collect obstruction edges
                  break;
                }
              }
            }
            else {
              // found a new neighbour to explore
              // go deeper in our dfs traversal
              nodesToVisit.push(neighbour);
              neighboursToVisit.push(graph->getOutEdges(neighbour));
              break;
            }
          }

          // it may be finished if we don't need
          // to collect obstruction edges
          if ((!result) && (obstructionEdges == NULL))
            break;
        }
      }

      // it may be finished if we don't need
      // to collect obstruction edges
      if ((!result) && (obstructionEdges == NULL)) {
        // don't froget to delete remaining iterators
        while(!neighboursToVisit.empty()) {
          delete neighboursToVisit.top();
          neighboursToVisit.pop();
        }

        break;
      }
    }
  }

  delete it;
  return result;
}