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