Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit 4a7f5c8

Browse files
author
Nadia Lafrenière
committed
Use of bisect for columns in longest_increasing_subsequences
1 parent 62b9a39 commit 4a7f5c8

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

src/sage/combinat/permutation.py

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2213,51 +2213,54 @@ def longest_increasing_subsequences(self):
22132213
p-tableau each value of the permutation is entered into, creates a
22142214
digraph to record all increasing subsequences, and reads the paths
22152215
from a source to a sink; these are the longest increasing subsequences.
2216-
22172216
22182217
EXAMPLES::
22192218
22202219
sage: Permutation([2,3,4,1]).longest_increasing_subsequences()
22212220
[[2, 3, 4]]
22222221
sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences()
22232222
[[1, 2, 6], [1, 2, 4], [1, 2, 3]]
2223+
2224+
.. NOTE::
2225+
This algorithm could be made faster using a balanced search tree
2226+
for each column instead of sorted lists. See discussion on
2227+
:trac:`31451`.
22242228
"""
22252229
n = self.size()
22262230
if n == 0:
22272231
return([[]])
22282232

2233+
from bisect import insort, bisect
2234+
22292235
# getting the column in which each element is inserted
22302236
first_row_p_tableau = []
2231-
columns = [[] for _ in range(self.longest_increasing_subsequence_length())]
2237+
columns = []
22322238
D = DiGraph(n+2)
2233-
for i in range(n):
2234-
inserted = False
2235-
j = 0 # j is j-th column of p-tableau
2236-
while j < len(first_row_p_tableau) and not inserted:
2237-
if first_row_p_tableau[j] > self[i]:
2238-
first_row_p_tableau[j] = self[i]
2239-
columns[j].append(self[i])
2239+
for x in self:
2240+
j = bisect(first_row_p_tableau, x)
2241+
if j == len(first_row_p_tableau):
2242+
if columns:
2243+
for k in columns[-1]:
2244+
if k >= x:
2245+
break
2246+
D.add_edge(k, x)
2247+
first_row_p_tableau.append(x)
2248+
columns.append([x])
2249+
else:
2250+
first_row_p_tableau[j] = x
2251+
insort(columns[j], x)
2252+
if j:
22402253
for k in columns[j-1]:
2241-
if k < self[i]:
2242-
D.add_edge(k, self[i])
2243-
inserted = True
2244-
j += 1
2245-
if not inserted:
2246-
first_row_p_tableau.append(self[i])
2247-
columns[j].append(self[i])
2248-
for k in columns[j-1]:
2249-
if k < self[i]:
2250-
D.add_edge(k, self[i])
2254+
if k > x:
2255+
break
2256+
D.add_edge(k, x)
22512257

22522258
for i in columns[0]:
22532259
D.add_edge(0, i) # 0 is source
22542260
for i in columns[-1]:
22552261
D.add_edge(i, n+1) # n+1 is sink
22562262

2257-
increasing_subsequences = [p[1:-1] for p in D.all_paths(0, n+1)]
2258-
increasing_subsequences.sort(reverse=True)
2259-
2260-
return increasing_subsequences
2263+
return sorted([p[1:-1] for p in D.all_paths(0, n+1)], reverse=True)
22612264

22622265

22632266
def cycle_type(self):

0 commit comments

Comments
 (0)