[Tutor] combining tuples in a list [NP complete reduction]
Kirby Urner
urnerk@qwest.net
Fri, 05 Apr 2002 13:45:31 -0800
At 01:43 PM 4/5/2002 -0700, Brad Reisfeld wrote:
>I agree that is seems like a hard problem (although this is
>probably because my brain is a bit muddled), but I don't
>believe that this is a restatement of the traveling salesman
>problem.
>
>The problem seems to be one of enumeration (since the 'splicing'
>dictates the paths), rather than one of optimization (to find
>the paths).
>
>-Brad
I would agree that it's a somewhat different problem.
Here's a stab at a solution. Somewhat complicated, but
uses dictionaries and is fairly fast. If you check this
out on a few examples, and the results conform to your
expectations, then I can elucidate the algorithm more.
If it fails to meet your expectation, show me where it
breaks down (provide example inlist, output) and maybe
I can fix it for ya.
def mkdict(thelist):
"""
File all tuples by first letter, allowing
multiple tuples per key if necessary
"""
tupdict = {}
for t in thelist:
tupdict[t[0]] = tupdict.get(t[0],[]) + [t]
return tupdict
def splice(thelist):
tupledict = {} # keeps all current tuples
for t in thelist:
tupledict[t] = 1
thedict = mkdict(tupledict.keys()) # 1st letter index
for t in thelist:
last = t[-1]
# only process tuple if (a) still current and
# (b) its last letter matches another's first
if tupledict.get(t,0) and thedict.get(last,0):
for t2 in thedict[last]:
newtuple = t + t2[1:] # build new tuple
tupledict[newtuple] = 1 # file in current
del tupledict[t2] # get rid of used tuple
del tupledict[t] # get rid of used tuple
thedict = mkdict(tupledict.keys()) # rebuild index
return tupledict.keys() # list unprocessed + new tuples
>>> inlist
[('c', 'p', 'l'), ('d', 'e', 'f'), ('c', 'h', 'i'),
('f', 'w', 'x'), ('a', 'b', 'c'), ('g', 'h', 'i'), ('r', 'z', 'd')]
>>> splice(inlist)
[('g', 'h', 'i'), ('r', 'z', 'd', 'e', 'f', 'w', 'x'),
('a', 'b', 'c', 'p', 'l'), ('a', 'b', 'c', 'h', 'i')]
Kirby