What is an efficient algorithm for retrieving bags from pairs lists?

I have a list of pairs of objects. Objects can appear in pairs in any order. What is the most efficient algorithm (and implementation?) To find all the bags (i.e. allowed with duplicates) pairs between the same objects. For my purpose, object references can be considered pointers or names, or some similar convenient, short, useful representation. Individual pairs are identified. There are no pairs that have the same object in both parts of the pair.

So, a list of pairs is given (Oid - a link to an object, Pid - a pair of links)

O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8

should return:

P1;P4;P5 and P3;P6
+3
source share
3 answers

"" ? , .

1) , "". , .

2) min ( .left, pair.right), max ( .left, pair.right). .

+3

, .

  • . ( , , pair.first <= pair.second )
  • , . pair1 < pair2 pair1.first < pair2.first pair1.first == pair2.first && pair1.second < pair2.second.

:

O1-P1-O2
O1-P4-O2
O1-P5-O2
O1-P3-O5
O1-P6-O5
O3-P2-O4
O7-P7-O8

"" . .

.

+5

@ Nikita Rybak's solution in Python using itertools.groupby () :

#!/usr/bin/env python
from itertools import groupby

pairs = """
O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8
""".split()

def lex_order(pair):
    """'O2-P5-O1' -> ['01', '02']"""
    return sorted(pair.split('-')[::2])

data = sorted(pairs, key=lex_order)
for key, group in groupby(data, key=lex_order):
    print "key=%(key)s, pairs=%(pairs)s" % dict(key=key, pairs=list(group))

Conclusion:

key=['O1', 'O2'], pairs=['O1-P1-O2', 'O1-P4-O2', 'O2-P5-O1']
key=['O1', 'O5'], pairs=['O5-P3-O1', 'O1-P6-O5']
key=['O3', 'O4'], pairs=['O3-P2-O4']
key=['O7', 'O8'], pairs=['O7-P7-O8']

@mbeckish solution in Python:

#!/usr/bin/env python
from collections import defaultdict

pairs = """
O1-P1-O2
O3-P2-O4
O5-P3-O1
O1-P4-O2
O2-P5-O1
O1-P6-O5
O7-P7-O8
""".split()

bags = defaultdict(list)
for pair in pairs:
    i, _, j = pair.split('-') # 'O2-P5-O1' -> ['02', 'P5', '01']
    bags[min(i,j), max(i,j)].append(pair)

import pprint;
pprint.pprint(dict(bags))

Conclusion:

{('O1', 'O2'): ['O1-P1-O2', 'O1-P4-O2', 'O2-P5-O1'],
 ('O1', 'O5'): ['O5-P3-O1', 'O1-P6-O5'],
 ('O3', 'O4'): ['O3-P2-O4'],
 ('O7', 'O8'): ['O7-P7-O8']}
+1
source

Source: https://habr.com/ru/post/1770788/


All Articles