@@ -1327,29 +1327,43 @@ def bfs():
13271327 u = queue .popleft ()
13281328 if dist [u ] < dist [None ]:
13291329 for v in graph .neighbors (u ):
1330- if dist [pair_V [v .name ]] == float ('inf' ):
1331- dist [pair_V [v .name ]] = dist [u ] + 1
1332- queue .append (pair_V [v .name ])
1333- return dist [None ] != float ('inf' )
1330+ if v .name in pair_V :
1331+ alt = pair_V [v .name ]
1332+ if alt is None :
1333+ dist [None ] = dist [u ] + 1
1334+ queue .append (None )
1335+ elif dist .get (alt , float ('inf' )) == float ('inf' ):
1336+ dist [alt ] = dist [u ] + 1
1337+ queue .append (alt )
1338+ return dist .get (None , float ('inf' )) != float ('inf' )
13341339
13351340 def dfs (u ):
1336- if u is not None :
1337- for v in graph .neighbors (u ):
1338- if dist [pair_V [v .name ]] == dist [u ] + 1 :
1339- if dfs (pair_V [v .name ]):
1341+ if u is None :
1342+ return True
1343+ for v in graph .neighbors (u ):
1344+ if v .name in pair_V :
1345+ alt = pair_V [v .name ]
1346+ if alt is None :
1347+ pair_V [v .name ] = u
1348+ pair_U [u ] = v .name
1349+ return True
1350+ elif dist .get (alt , float ('inf' )) == dist .get (u , float ('inf' )) + 1 :
1351+ if dfs (alt ):
13401352 pair_V [v .name ] = u
13411353 pair_U [u ] = v .name
13421354 return True
1343- dist [u ] = float ('inf' )
1344- return False
1345- return True
1355+ dist [u ] = float ('inf' )
1356+ return False
13461357
13471358 matching = set ()
13481359 while bfs ():
13491360 for u in U :
13501361 if pair_U [u ] is None :
1351- if dfs (u ):
1352- matching .add ((u , pair_U [u ]))
1362+ dfs (u )
1363+
1364+ for u in U :
1365+ if pair_U [u ] is not None :
1366+ matching .add ((u , pair_U [u ]))
13531367
13541368 return matching
13551369
@@ -1392,8 +1406,8 @@ def maximum_matching(graph: Graph, algorithm: str, **kwargs) -> set:
13921406 >>> graph.add_edge('v_1', 'v_2')
13931407 >>> graph.add_edge('v_2', 'v_3')
13941408 >>> graph.add_edge('v_4', 'v_1')
1395- >>> maximum_matching(graph, 'hopcroft_karp')
1396- >>> {('v_1 ', 'v_4 '), ('v_3 ', 'v_2 ')}
1409+ >>> maximum_matching(graph, 'hopcroft_karp', make_undirected=True )
1410+ >>> {('v_3 ', 'v_2 '), ('v_1 ', 'v_4 ')}
13971411
13981412 References
13991413 ==========
@@ -1448,22 +1462,33 @@ def bfs():
14481462 u = queue .popleft ()
14491463 if dist [u ] < dist [None ]:
14501464 for v in graph .neighbors (u ):
1451- if dist [pair_V [v .name ]] == float ('inf' ):
1452- dist [pair_V [v .name ]] = dist [u ] + 1
1453- queue .append (pair_V [v .name ])
1454- return dist [None ] != float ('inf' )
1465+ if v .name in pair_V :
1466+ alt = pair_V [v .name ]
1467+ if alt is None :
1468+ dist [None ] = dist [u ] + 1
1469+ queue .append (None )
1470+ elif dist .get (alt , float ('inf' )) == float ('inf' ):
1471+ dist [alt ] = dist [u ] + 1
1472+ queue .append (alt )
1473+ return dist .get (None , float ('inf' )) != float ('inf' )
14551474
14561475 def dfs (u ):
1457- if u is not None :
1458- for v in graph .neighbors (u ):
1459- if dist [pair_V [v .name ]] == dist [u ] + 1 :
1460- if dfs (pair_V [v .name ]):
1476+ if u is None :
1477+ return True
1478+ for v in graph .neighbors (u ):
1479+ if v .name in pair_V :
1480+ alt = pair_V [v .name ]
1481+ if alt is None :
1482+ pair_V [v .name ] = u
1483+ pair_U [u ] = v .name
1484+ return True
1485+ elif dist .get (alt , float ('inf' )) == dist .get (u , float ('inf' )) + 1 :
1486+ if dfs (alt ):
14611487 pair_V [v .name ] = u
14621488 pair_U [u ] = v .name
14631489 return True
1464- dist [u ] = float ('inf' )
1465- return False
1466- return True
1490+ dist [u ] = float ('inf' )
1491+ return False
14671492
14681493 matching = set ()
14691494
@@ -1474,7 +1499,7 @@ def dfs(u):
14741499 results = Executor .map (dfs , unmatched_nodes )
14751500
14761501 for u , success in zip (unmatched_nodes , results ):
1477- if success :
1502+ if success and pair_U [ u ] is not None :
14781503 matching .add ((u , pair_U [u ]))
14791504
14801505 return matching
@@ -1497,6 +1522,8 @@ def maximum_matching_parallel(graph: Graph, algorithm: str, num_threads: int, **
14971522 'hopcroft_karp' -> Hopcroft-Karp algorithm for Bipartite Graphs as given in [1].
14981523 num_threads: int
14991524 The maximum number of threads to be used.
1525+ make_undirected: bool
1526+ If False, the graph should be undirected or unwanted results may be obtained. The graph can be made undirected by setting this to true.
15001527 backend: pydatastructs.Backend
15011528 The backend to be used.
15021529 Optional, by default, the best available
@@ -1520,8 +1547,8 @@ def maximum_matching_parallel(graph: Graph, algorithm: str, num_threads: int, **
15201547 >>> graph.add_bidirectional_edge('v_1', 'v_2')
15211548 >>> graph.add_bidirectional_edge('v_2', 'v_3')
15221549 >>> graph.add_bidirectional_edge('v_4', 'v_1')
1523- >>> maximum_matching_parallel(graph, 'hopcroft_karp', 1)
1524- >>> {('v_1 ', 'v_4 '), ('v_3 ', 'v_2 ')}
1550+ >>> maximum_matching_parallel(graph, 'hopcroft_karp', 1, make_undirected=True )
1551+ >>> {('v_3 ', 'v_2 '), ('v_1 ', 'v_4 ')}
15251552
15261553 References
15271554 ==========
@@ -1531,6 +1558,9 @@ def maximum_matching_parallel(graph: Graph, algorithm: str, num_threads: int, **
15311558
15321559 raise_if_backend_is_not_python (
15331560 maximum_matching_parallel , kwargs .get ('backend' , Backend .PYTHON ))
1561+ make_undirected = kwargs .get ('make_undirected' , False )
1562+ if make_undirected :
1563+ graph = graph .to_undirected_adjacency_list ()
15341564
15351565 import pydatastructs .graphs .algorithms as algorithms
15361566 func = "_maximum_matching_" + algorithm + "_parallel"
0 commit comments