Source code for pyrigi.graph._flexibility.nac.check
"""The module checks if the given coloring is a NAC-coloring.The algorithm is based on :prf:ref:`lem-color-components`."""fromtypingimportCollection,Iterableimportnetworkxasnxfrompyrigi.graph._flexibility.nac.coreimport(IntEdge,NACColoring,can_have_NAC_coloring,)def_check_for_almost_red_cycles(adj:list[list[int]],red_edges:Iterable[IntEdge],blue_edges:Iterable[IntEdge],)->bool:""" Check if there is an almost cycle in the graph with the given coloring. `True` is returned if the coloring has no almost red cycles with a single blue edge. It is not checked whether the coloring is surjective. Parameters ---------- adj: Pre-allocated adjacency list of length n (number of vertices, indexed 0..n-1). Cleared and rebuilt in-place from ``red_edges`` on each call. red_edges: Edges in the red color - used to create components. blue_edges: Edges in the blue color - used to check for almost cycles. """n=len(adj)forlstinadj:lst.clear()foru,vinred_edges:adj[u].append(v)adj[v].append(u)comp=[-1]*ncid=0stack=[]foriinrange(n):ifcomp[i]!=-1:continuecomp[i]=cidstack.append(i)whilestack:u=stack.pop()forvinadj[u]:ifcomp[v]==-1:comp[v]=cidstack.append(v)cid+=1fore1,e2inblue_edges:ifcomp[e1]==comp[e2]:returnFalsereturnTruedef_is_NAC_coloring_impl(graph:nx.Graph,coloring:NACColoring,)->bool:""" Check if the coloring given is a :prf:ref:`NAC-coloring <def-nac>` by using algorithm described in :prf:ref:`lem-color-components`. The algorithm checks if all the edges are in the same component. This is an internal implementation, so some properties like injectivity are not checked for performance reasons - we only search for the cycles. Parameters ---------- graph: coloring: The coloring to check if it is a NAC coloring. """red,blue=coloringnodes=list(graph.nodes)n=len(nodes)index={v:ifori,vinenumerate(nodes)}red_i=[(index[u],index[v])foru,vinred]blue_i=[(index[u],index[v])foru,vinblue]adj:list[list[int]]=[[]for_inrange(n)]return_check_for_almost_red_cycles(adj,red_i,blue_i)and_check_for_almost_red_cycles(adj,blue_i,red_i)# public facing interface
[docs]defis_NAC_coloring(graph:nx.Graph,coloring:NACColoring|dict[str,Collection[IntEdge]],)->bool:""" Check if the coloring given is a :prf:ref:`NAC-coloring <def-nac>` by using algorithm described in :prf:ref:`lem-color-components`. The algorithm checks if all the edges are in the same component. This is an internal implementation, so some properties like injectivity are not checked for performance reasons - we only search for the cycles. Parameters ---------- graph: coloring: The coloring to check if it is a NAC coloring. """red:Collection[IntEdge]blue:Collection[IntEdge]ifisinstance(coloring,dict):red,blue=coloring["red"],coloring["blue"]else:red,blue=coloringifnotcan_have_NAC_coloring(graph):returnFalse# Both colors have to be usediflen(red)==0orlen(blue)==0:# this is faster than *returnFalseiflen(red)+len(blue)!=len(graph.edges):returnFalseifisinstance(red,set)andlen(red.intersection(blue))!=0:returnFalseelse:# Yes, this is slower - in case you care, use setsforeinred:ifeinblue:returnFalsereturn_is_NAC_coloring_impl(graph,(red,blue))