@@ -305,6 +305,56 @@ def order_filter(self, elements):
305305 [3, 7, 8, 9, 10, 11, 12, 13, 14, 15]
306306 """
307307
308+ def generate_upsets (U , Y , Poset ):
309+ r"""
310+ Enumerates the ideals (upsets) of a given poset.
311+
312+ ALGORITHM:
313+
314+ The algorithm is based on [Sq2002]_.
315+ Current algorithms for genertating ideals require an amortized
316+ time of `O(n)` per ideal in the worst case, where `n` is the number
317+ of elements in the poset. This algorithm generates ideals in an
318+ amortized time of `O(log n)` per ideal.
319+
320+ The function recursively generates all possible upsets (subsets) of
321+ a given set `Y` based on a partially ordered set (Poset), ensuring that
322+ if `Xi < Xm < Xj`, then Xi must also be less than `Xj`. It iterates through
323+ `Y`, partitioning it into two subsets based on the relationship between
324+ elements and yields the resulting upsets.
325+
326+ INPUT:
327+
328+ - ``U`` -- a list of the current upset being constructed.
329+ - ``Y`` -- a list of remaining elements to be considered for inclusion.
330+ - ``Poset`` -- a dictionary representing the partial order.
331+
332+ OUTPUT:
333+
334+ - A subset of Y that satisfies the upset condition.
335+
336+ EXAMPLES::
337+
338+ """
339+ if not Y :
340+ yield U
341+ else :
342+ Xm = Y [len (Y ) // 2 ]
343+ Y1 = []
344+ Y2 = []
345+ for Xi in Y :
346+ if Poset [(Xi , Xm )] == 1 :
347+ U [Y .index (Xi )] = 0
348+ else :
349+ Y1 .append (Xi )
350+ yield from Posets .generate_upsets (U .copy (), Y1 , Poset )
351+ for Xj in Y :
352+ if Poset [(Xm , Xj )] == 1 :
353+ U [Y .index (Xj )] = 1
354+ else :
355+ Y2 .append (Xj )
356+ yield from Posets .generate_upsets (U .copy (), Y2 , Poset )
357+
308358 def directed_subset (self , elements , direction ):
309359 r"""
310360 Return the order filter or the order ideal generated by a
0 commit comments