@@ -2213,51 +2213,54 @@ def longest_increasing_subsequences(self):
2213
2213
p-tableau each value of the permutation is entered into, creates a
2214
2214
digraph to record all increasing subsequences, and reads the paths
2215
2215
from a source to a sink; these are the longest increasing subsequences.
2216
-
2217
2216
2218
2217
EXAMPLES::
2219
2218
2220
2219
sage: Permutation([2,3,4,1]).longest_increasing_subsequences()
2221
2220
[[2, 3, 4]]
2222
2221
sage: Permutation([5, 7, 1, 2, 6, 4, 3]).longest_increasing_subsequences()
2223
2222
[[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`.
2224
2228
"""
2225
2229
n = self .size ()
2226
2230
if n == 0 :
2227
2231
return ([[]])
2228
2232
2233
+ from bisect import insort , bisect
2234
+
2229
2235
# getting the column in which each element is inserted
2230
2236
first_row_p_tableau = []
2231
- columns = [[] for _ in range ( self . longest_increasing_subsequence_length ())]
2237
+ columns = []
2232
2238
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 :
2240
2253
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 )
2251
2257
2252
2258
for i in columns [0 ]:
2253
2259
D .add_edge (0 , i ) # 0 is source
2254
2260
for i in columns [- 1 ]:
2255
2261
D .add_edge (i , n + 1 ) # n+1 is sink
2256
2262
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 )
2261
2264
2262
2265
2263
2266
def cycle_type (self ):
0 commit comments