@@ -483,6 +483,7 @@ Graph* Graph::MakeGraphCopy(GraphCopyType type, const std::function<Graph*()> &
483483 case GTC_INVERSE: res = MakeGraphInverse (createFunction); break ;
484484 case GTC_REMOVE_SELF_LOOP: res = MakeGraphRemoveSelfLoop (createFunction); break ;
485485 case GTC_REMOVE_NEGATIVE: res = MakeGraphRemoveNegative (createFunction); break ;
486+ case GTC_COMPLEMENT: res = MakeGraphComplement (createFunction); break ;
486487 }
487488
488489 if (res)
@@ -737,6 +738,55 @@ Graph* Graph::MakeGraphRemoveNegative(const std::function<Graph*()> & createFunc
737738}
738739
739740
741+ /* *
742+ * It adds all edges (<source, target> pairs) that did not occur in the original graph
743+ * Sets all weights to zero
744+ * All edges of the new graph are directed
745+ */
746+ Graph* Graph::MakeGraphComplement (const std::function<Graph*()> & createFunction) const
747+ {
748+ Graph* res = createFunction ? createFunction () : CreateGraph ();
749+
750+ CopyPropertiesTo (res);
751+
752+ res->m_weightType = m_weightType;
753+
754+ // Create all nodes.
755+ for (NodePtr node : m_nodes)
756+ {
757+ res->m_nodes .push_back (NodePtr (new Node (node->id , node->privateId , node->fake , node->index )));
758+ res->m_idToNode [node->privateId ] = res->m_nodes .back ();
759+ }
760+
761+ // Add all edges that do not exist in the original graph
762+
763+ for (NodePtr source : res->m_nodes ) {
764+ for (NodePtr target : res->m_nodes ) {
765+
766+ // no self loop is permitted
767+ if (source->privateId == target->privateId ) continue ;
768+
769+ // if the original graph does not contain the edge - add it to the copy graph
770+ // pass false to IsEgdeExists to handle undirected edges correctly
771+ if (!this ->IsEgdeExists (source->privateId , target->privateId , false )) {
772+ auto indexId = res->GetNextId ();
773+
774+ res->AddEdge (String ().FromInt (indexId),
775+ source->privateId ,
776+ target->privateId ,
777+ true ,
778+ 0 ,
779+ indexId);
780+ }
781+
782+ }
783+ }
784+
785+ return res;
786+ }
787+
788+
789+
740790void Graph::RemoveEdge (ObjectId source, ObjectId target)
741791{
742792 EdgePtr edge = FindEdge (source, target);
@@ -905,7 +955,7 @@ const char* Graph::PrintGraph() const
905955 report += " Edges:\n " ;
906956 for (auto edge : m_edges)
907957 {
908- report += std::string (" Public id: " ) + edge->id .Locale ().Data () + " " + " private id: " + std::to_string (edge->privateId ) + " \n " ;
958+ report += std::string (" Public id: " ) + edge->id .Locale ().Data () + " " + " private id: " + std::to_string (edge->privateId ) + " source: " + edge-> source -> id . Locale (). Data () + " target: " + edge-> target -> id . Locale (). Data () + " directed: " + std::to_string (edge-> direct ) + " \n " ;
909959 }
910960
911961 return report.c_str ();
0 commit comments