Exemple #1
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];
}
Exemple #2
0
//=================================================================
static void dfsAux(Graph *sG, node n, MutableContainer<int> &dfsPre, MutableContainer<int> &dfsPos,
                   list<edge> &dfsEdges, unsigned int &preCount, unsigned int &postCount) {
  dfsPre.set(n.id, ++preCount);
  for (auto e : sG->getOutEdges(n)) {
    node target = sG->target(e);

    if (dfsPre.get(target.id) == 0) {
      dfsEdges.push_back(e);
      dfsAux(sG, target, dfsPre, dfsPos, dfsEdges, preCount, postCount);
    }
  }

  dfsPos.set(n.id, ++postCount);
}
Exemple #3
0
void makeBiconnectedDFS(Graph *graph, node from,
                        MutableContainer<int> &low,
                        MutableContainer<int> &depth,
                        MutableContainer<node> &supergraph,
                        unsigned int &currentDepth,
                        vector<edge> &addedEdges) {
  node u;
  depth.set(from.id, currentDepth++);
  low.set(from.id, depth.get(from.id));

  //for every node connected to this one, call this function so it runs on every node.
  StableIterator<node> itN(graph->getInOutNodes(from));

  while (itN.hasNext()) {
    node to = itN.next();

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

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

    //if the destination node has not been visited, visit it
    if (depth.get(to.id) == -1) {
      supergraph.set(to.id, from);
      makeBiconnectedDFS(graph, to, low, depth, supergraph, currentDepth, addedEdges);

      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)));
    }
    else {
      low.set(from.id, std::min(low.get(from.id), depth.get(to.id)));
    }
  }
}
void dfsAux(Graph *sG, node n,
            MutableContainer<int>& dfsPre,
            MutableContainer<int>& dfsPos,
            list<edge>& dfsEdges) {
  dfsPre.set(n.id, preCount++);
  StableIterator<edge> it(sG->getOutEdges(n));

  while (it.hasNext()) {
    edge e = it.next();
    node target = sG->target(e);

    if (dfsPre.get(target.id) == 0) {
      dfsEdges.push_back(e);
      dfsAux(sG, target, dfsPre, dfsPos, dfsEdges);
    }
  }

  dfsPos.set(n.id, postCount++);
}
Exemple #5
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
//====================================================
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);
  }
}
Exemple #7
0
//=================================================================
bool biconnectedTest(const Graph *graph, node v,
                     MutableContainer<bool> &mark,
                     MutableContainer<unsigned int> &low,
                     MutableContainer<unsigned int> &dfsNumber,
                     MutableContainer<node> &supergraph,
                     unsigned int &count) {
  mark.set(v.id,true);
  dfsNumber.set(v.id,count);
  low.set(v.id,count);
  ++count;
  Iterator<node> *it=graph->getInOutNodes(v);

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

    if (!mark.get(w.id)) {
      if (dfsNumber.get(v.id)==1) {
        if (count != 2) {
          delete it;
          return false;
        }
      }

      supergraph.set(w.id,v);

      if (!biconnectedTest(graph,w,mark,low,dfsNumber,supergraph,count)) {
        delete it;
        return false;
      }

      if (dfsNumber.get(v.id)!=1) {
        if (low.get(w.id)>=dfsNumber.get(v.id)) {
          delete it;
          return false;
        }
        else
          low.set(v.id, std::min(low.get(v.id), low.get(w.id)));
      }
    }
    else if (supergraph.get(v.id)!=w) {
      low.set(v.id, std::min(low.get(v.id), dfsNumber.get(w.id)));
    }
  }

  delete it;
  return true;
}
    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;
    }
/*
 * 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;
}
Exemple #10
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;
    }
}
Exemple #11
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();
  }
}
Exemple #12
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;
}