Beispiel #1
0
Graph* Graph::Shrink()
{
  root_ = source_vertices_[0];

  MarkArticulationPoints();

  // Clean all the articulation points on the paths between every pair of source
  // vertices to ensure that all the source vertices will not be merged into
  // pseudo vertices.
  for (auto source_vertex : source_vertices_) {
    if (source_vertex != root_) {
      Vertex* vertex = source_vertex;
      while (vertex != root_) {
        assert(vertex != nullptr);

        vertex->SetIsArticulate(false);
        vertex = vertex->GetParent();
      }
    }
  }

  // Clean all the articulation points connecting to a resident directly to
  // avoid making useless pseudo vertices each containing just a single
  // resident.
  for (auto pair : vertices_) {
    Vertex* vertex = pair.second;

    for (int i = 0; i < vertex->GetIncidentEdgesNum(); ++i) {
      Vertex* neighbor = vertex->GetIncidentEdge(i)->GetNeighbor(vertex);

      if (neighbor->GetType() == Vertex::Type::RESIDENT) {
        vertex->SetIsArticulate(false);
        break;
      }
    }
  }

  Graph* tmp = ShrinkByArticulationPoints();

  Graph* shrinked_graph = tmp->ShrinkBySwitches();

  delete tmp;

  //shrinked_graph->Print();

  return shrinked_graph;
}
Beispiel #2
0
Graph* Graph::ShrinkByArticulationPoints()
{
  Graph* shrinked_graph = new Graph(grid_);

  const string pseudo_vertex_prefix("PAV");
  int pseudo_vertex_counter = 0;

  ResetVerticesMarks();

  map<Vertex*, PseudoVertex*> pseudo_vertices;

  queue<Vertex*> bfs_queue;
  root_->SetIsVisted();
  bfs_queue.push(root_);
  while (!bfs_queue.empty()) {
    Vertex* front = bfs_queue.front();
    bfs_queue.pop();

    shrinked_graph->AddVertex(front);

    for (int i = 0; i < front->GetIncidentEdgesNum(); ++i) {
      Edge* incident_edge = front->GetIncidentEdge(i);
      Vertex* child = incident_edge->GetNeighbor(front);

      if (child != front->GetParent()) {
        if (!child->GetIsVisited()) {
          child->SetIsVisted();

          front->AddChild(child);
          child->SetParent(front);

          if (child->GetIsArticulate()) {
            const string pseudo_vertex_name(pseudo_vertex_prefix + to_string(pseudo_vertex_counter++));

            Node* new_node = new Node(pseudo_vertex_name);

            grid_->GetSmartGrid()->AddEquipment(new_node);

            PseudoVertex* pseudo_vertex = new PseudoVertex(new_node);

            Edge* new_edge = new Edge(incident_edge->GetRaw());

            pseudo_vertex->AddBoundaryVertex(new_edge, child);

            pseudo_vertex->AddIncidentEdge(new_edge);

            new_edge->AddIncidentVertex(front);
            new_edge->AddIncidentVertex(pseudo_vertex);

            front->SetIncidentEdge(i, new_edge);

            shrinked_graph->AddVertex(pseudo_vertex);
            shrinked_graph->AddEdge(new_edge);

            pseudo_vertices.insert(make_pair(child, pseudo_vertex));
          } else {
            bfs_queue.push(child);

            shrinked_graph->AddVertex(child);
            shrinked_graph->AddEdge(incident_edge);
          }
        } else {
          if (child->GetIsArticulate()) {
            assert(pseudo_vertices.count(child) == 1);

            PseudoVertex* pseudo_vertex = pseudo_vertices.find(child)->second;

            Edge* new_edge = new Edge(incident_edge->GetRaw());

            pseudo_vertex->AddBoundaryVertex(new_edge, child);

            pseudo_vertex->AddIncidentEdge(new_edge);

            new_edge->AddIncidentVertex(front);
            new_edge->AddIncidentVertex(pseudo_vertex);

            front->SetIncidentEdge(i, new_edge);

            shrinked_graph->AddEdge(new_edge);
          } else {
            shrinked_graph->AddEdge(incident_edge);
          }
        }
      }
    }
  }

  for (auto pair : pseudo_vertices) {
    pair.second->MergeDescendants(pair.first);
  }

  return shrinked_graph;
}