Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7082847
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T07:06:19+00:00 2026-05-28T07:06:19+00:00

Here is my problem: I have a sequence S of (nonempty but possibly not

  • 0

Here is my problem: I have a sequence S of (nonempty but possibly not distinct) sets s_i, and for each s_i need to know how many sets s_j in S (i ≠ j) are subsets of s_i.

I also need incremental performance: once I have all my counts, I may replace one set s_i by some subset of s_i and update the counts incrementally.

Performing all this using purely functional code would be a huge plus (I code in Scala).

As set inclusion is a partial ordering, I thought the best way to solve my problem would be to build a DAG that would represent the Hasse diagram of the sets, with edges representing inclusion, and join an integer value to each node representing the size of the sub-dag below the node plus 1. However, I have been stuck for several days trying to develop the algorithm that builds the Hasse diagram from the partial ordering (let’s not talk about incrementality!), even though I thought it would be some standard undergraduate material.

Here is my data structure :

case class HNode[A] (
  val v: A,
  val child: List[HNode[A]]) {
  val rank = 1 + child.map(_.rank).sum
}

My DAG is defined by a list of roots and some partial ordering:

class Hasse[A](val po: PartialOrdering[A], val roots: List[HNode[A]]) {
  def +(v: A): Hasse[A] = new Hasse[A](po, add(v, roots))

  private def collect(v: A, roots: List[HNode[A]], collected: List[HNode[A]]): List[HNode[A]] =
    if (roots == Nil) collected
    else {
      val (subsets, remaining) = roots.partition(r => po.lteq(r.v, v))
      collect(v, remaining.map(_.child).flatten, subsets.filter(r => !collected.exists(c => po.lteq(r.v, c.v))) ::: collected)
    }
}

I am pretty stuck here. The last I came up to add a new value v to the DAG is:

  1. find all “root subsets” rs_i of v in the DAG, i.e., subsets of v such that no superset of rs_i is a subset of v. This can be done quite easily by performing a search (BFS or DFS) on the graph (collect function, possibly non-optimal or even flawed).
  2. build the new node n_v, the children of which are the previously found rs_i.
  3. Now, let’s find out where n_v should be attached: for a given list of roots, find out supersets of v. If none are found, add n_v to the roots and remove subsets of n_v from the roots. Else, perform step 3 recursively on the supersets’s children.

I have not yet implemented fully this algorithm, but it seems uncessarily circonvoluted and nonoptimal for my apparently simple problem. Is there some simpler algorithm available (Google was clueless on this)?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T07:06:20+00:00Added an answer on May 28, 2026 at 7:06 am

    After some work, I finally ended up solving my problem, following my initial intuition. The collect method and rank evaluation were flawed, I rewrote them with tail-recursion as a bonus. Here is the code I obtained:

    final case class HNode[A](
      val v: A,
      val child: List[HNode[A]]) {
      val rank: Int = 1 + count(child, Set.empty)
    
      @tailrec
      private def count(stack: List[HNode[A]], c: Set[HNode[A]]): Int =
        if (stack == Nil) c.size
        else {
          val head :: rem = stack
          if (c(head)) count(rem, c)
          else count(head.child ::: rem, c + head)
        }
    }
    
    // ...
    
      private def add(v: A, roots: List[HNode[A]]): List[HNode[A]] = {
        val newNode = HNode(v, collect(v, roots, Nil))
        attach(newNode, roots)
      }
    
      private def attach(n: HNode[A], roots: List[HNode[A]]): List[HNode[A]] =
        if (roots.contains(n)) roots
        else {
          val (supersets, remaining) = roots.partition { r =>
            // Strict superset to avoid creating cycles in case of equal elements
            po.tryCompare(n.v, r.v) == Some(-1)
          }
          if (supersets.isEmpty) n :: remaining.filter(r => !po.lteq(r.v, n.v))
          else {
            supersets.map(s => HNode(s.v, attach(n, s.child))) ::: remaining
          }
        }
    
      @tailrec
      private def collect(v: A, stack: List[HNode[A]], collected: List[HNode[A]]): List[HNode[A]] =
        if (stack == Nil) collected
        else {
          val head :: tail = stack
    
          if (collected.exists(c => po.lteq(head.v, c.v))) collect(v, tail, collected)
          else if (po.lteq(head.v, v)) collect(v, tail, head :: (collected.filter(c => !po.lteq(c.v, head.v))))
          else collect(v, head.child ::: tail, collected)
        }
    

    I now must check some optimization:
    – cut off branches with totally distinct sets when collecting subsets (as Rex Kerr suggested)
    – see if sorting the sets by size improves the process (as mitchus suggested)

    The following problem is to work the (worst case) complexity of the add() operation out.
    With n the number of sets, and d the size of the largest set, the complexity will probably be O(n²d), but I hope it can be refined. Here is my reasoning: if all sets are distinct, the DAG will be reduced to a sequence of roots/leaves. Thus, every time I try to add a node to the data structure, I still have to check for inclusion with each node already present (both in collect and attach procedures). This leads to 1 + 2 + … + n = n(n+1)/2 ∈ O(n²) inclusion checks.

    Each set inclusion test is O(d), hence the result.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Here is the problem: We have all of our development under subversion, but our
I have some problem with sequence generator. I have a file where each line
Here is the problem I have: I have a lot (tens of thousands) of
Here's my problem - I have some code like this: <mx:Canvas width=300 height=300> <mx:Button
Here's my problem: I have a virtual method defined in a .h file that
Here is the problem: we have lots of Javascripts and lots of CSS files,
Here's my problem: I have to call a web service with a secure header
Here's my problem.I have 2 xmlfiles with identical structure, with the second xml containing
Here's my problem: I have do create a menu/list of actions (which would be
Here's the problem: I have couple of pages which gets its content from a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.