Check Transitive Relation on a Set (original) (raw)

Last Updated : 23 Jul, 2025

A relation is a subset of the cartesian product of a set with another set. A relation contains ordered pairs of elements of the set it is defined on. To learn more about **relations refer to the article on "Relation and their types".

What is a Transitive Relation?

A relation R on a set A is called transitive relation if and only if

∀ a, b, c ∈ A, if (a, b) ∈ R and (b, c) ∈ R then (a, c) ∈ R,
where R is a subset of (A x A), i.e. the cartesian product of set A with itself.

This means if an ordered pair of elements ****"a" to "b"** (**aRb) and ****"b" to "c"** (**bRc) is present in relation **R, then an ordered pair of elements ****"a" to "c"** (**aRC) should also be present in the relation R. If any such **aRc is not present for any **aRb & **bRc in R then R is not a transitive relation.

**Example:

Consider set **A = {a, b, c}

R = {(a, b), (b, c), (a, c)} is transitive relation but
R = {(a, b), (b, c)} is not transitive relation

Properties of Transitive Relation

  1. Empty relation on any set is always transitive.
  2. Universal relation on any set is always transitive.

How to verify a Transitive Relation?

To verify transitive relation:

Follow the below illustration for a better understanding

**Illustration:

Consider set **R = {(1, 2), (1, 3), (2, 3), (3, 4)}

For the pairs ****(1, 2) and (2, 3)**:
=> The relation (1, 3) exists
=> This **satisfies the condition.

For the pairs ****(1, 3) and (3, 4)**:
=> The relation (1, 4) does not exist
=> This **does not satisfy the condition.

So the relation is **not transitive.

Below is the code implementation of the idea:

C++ `

#include <bits/stdc++.h> using namespace std;

class Relation { public: bool checkTransitive(set<pair<int, int> > R) { // Property 1 if (R.size() == 0) { return true; }

    // Create a dictionary to store tuple as key value
    // pair
    map<int, set<int> > tup;

    // Creating dictionary of relation where (a) is key
    // and (b) is value
    for (auto i = R.begin(); i != R.end(); i++) {
        if (tup.find(i->first) == tup.end()) {
            set<int> temp;
            temp.insert(i->second);
            tup.insert(
                pair<int, set<int> >(i->first, temp));
        }
        else {
            tup.at(i->first).insert(i->second);
        }
    }

    for (auto a = tup.begin(); a != tup.end(); a++) {

        // Set of all b's related with a
        set<int> all_b_in_aRb = tup.at(a->first);

        // Taking all c's from each b one by one
        for (int b : all_b_in_aRb) {
            if (tup.find(b) != tup.end()
                && a->first != b) {

                // Set of all c's related with b
                set<int> all_c_in_bRc = tup.at(b);

                // All c's related with each b must be
                // subset of all b's related with a
                for (int c : all_c_in_bRc) {
                    if (all_b_in_aRb.find(c)
                        == all_b_in_aRb.end()) {
                        return false;
                    }
                }
            }
        }
    }

    // For all aRb and bRc there exist aRc in relation R
    return true;
}

};

int main() { set<pair<int, int> > R;

// Inserting tuples in relation R
R.insert(make_pair(1, 1));
R.insert(make_pair(1, 2));
R.insert(make_pair(2, 1));
R.insert(make_pair(2, 2));
R.insert(make_pair(1, 3));
R.insert(make_pair(2, 3));
R.insert(make_pair(3, 4));
R.insert(make_pair(1, 4));

Relation obj;

// R is not transitive as (2, 4) tuple is not present
if (obj.checkTransitive(R)) {
    cout << "Transitive Relation" << endl;
}
else {
    cout << "Not a Transitive Relation" << endl;
}

return 0;

}

Java

// Java code to implement the approach import java.io.; import java.util.;

class pair { int first, second; pair(int first, int second) { this.first = first; this.second = second; } }

class GFG {

static class Relation { boolean checkTransitive(Set R) { // Property 1 if (R.size() == 0) { return true; } // Create a hashmap to store tuple as key value // pair HashMap<Integer, Set > tup = new HashMap<>();

  // Creating hashmap of relation where (a) is key
  // and (b) is value
  for (pair i : R) {
    if (!tup.containsKey(i.first)) {
      Set<Integer> temp = new HashSet<>();
      temp.add(i.second);
      tup.put(i.first, temp);
    }
    else {
      Set<Integer> temp = new HashSet<>();
      temp = tup.get(i.first);
      temp.add(i.second);
      tup.put(i.first, temp);
    }
  }

  for (Integer a : tup.keySet()) {
    // Set of all b's related with a
    Set<Integer> all_b_in_aRb = tup.get(a);

    // Taking all c's from each b one by one
    for (int b : all_b_in_aRb) {
      if (tup.containsKey(b) && a != b) {
        // Set of all c's related with b
        Set<Integer> all_c_in_bRc
          = tup.get(b);

        // All c's related with each b must
        // be subset of all b's related with
        // a
        for (Integer c : all_c_in_bRc) {
          if (all_b_in_aRb.contains(c)) {
            return false;
          }
        }
      }
    }
  }

  // For all aRb and bRc there exist aRc in
  // relation R
  return true;
}

}

public static void main(String[] args) { // Creating relation R Set R = new HashSet<>();

// Inserting tuples in relation R
R.add(new pair(1, 1));
R.add(new pair(1, 2));
R.add(new pair(2, 1));
R.add(new pair(2, 2));
R.add(new pair(1, 3));
R.add(new pair(2, 3));
R.add(new pair(3, 4));
R.add(new pair(1, 4));

Relation obj = new Relation();

// R is not transitive as (2, 4) tuple is not
// present
if (obj.checkTransitive(R)) {
  System.out.println("Transitive Relation");
}
else {
  System.out.println("Not a Transitive Relation");
}

} }

// This code is contributed by lokeshmvs21.

Python

class Relation: def checkTransitive(self, R): # Property 1 if len(R) == 0: return True

    # Create a dictionary to store tuple as key value pair
    tup = dict()

    # Creating dictionary of relation where (a) is key and (b) is value
    for i in R:
        if tup.get(i[0]) is None:
            tup[i[0]] = {i[1]}
        else:
            tup[i[0]].add(i[1])

    for a in tup.keys():

        # Set of all b's related with a
        all_b_in_aRb = tup.get(a)
        if all_b_in_aRb is not None:

            # Taking all c's from each b one by one
            for b in all_b_in_aRb:

                # Set of all c's related with b
                all_c_in_bRc = tup.get(b)
                if a != b and all_c_in_bRc is not None:
                    if not all_c_in_bRc.issubset(all_b_in_aRb):

                        # All c's related with each b must be
                        # subset of all b's related with a
                        return False

    # For all aRb and bRc there exist aRc in relation R
    return True

Driver code

if name == 'main':

# Creating relation R
R = {(1, 1), (1, 2), (2, 1), (2, 2), (1, 3), (2, 3), (3, 4), (1, 4)}

obj = Relation()

# R is not transitive as (2, 4) tuple is not present
if obj.checkTransitive(R):
    print("Transitive Relation")
else:
    print("Not a Transitive Relation")

C#

// C# code to implement the approach using System; using System.Collections.Generic;

class pair { public int first, second; public pair(int first, int second) { this.first = first; this.second = second; } }

public class GFG {

class Relation { public bool checkTransitive(HashSet R) { // Property 1 if (R.Count == 0) { return true; } // Create a hashmap to store tuple as key value // pair Dictionary<int, HashSet > tup = new Dictionary<int, HashSet >();

  // Creating hashmap of relation where (a) is key
  // and (b) is value
  foreach(pair i in R)
  {
    if (!tup.ContainsKey(i.first)) {
      HashSet<int> temp = new HashSet<int>();
      temp.Add(i.second);
      tup[i.first] = temp;
    }
    else {
      HashSet<int> temp = new HashSet<int>();
      temp = tup[i.first];
      temp.Add(i.second);
      tup[i.first] = temp;
    }
  }

  foreach(var a in tup)
  {
    // Set of all b's related with a
    HashSet<int> all_b_in_aRb = tup[a.Key];

    // Taking all c's from each b one by one
    foreach(int b in all_b_in_aRb)
    {
      if (tup.ContainsKey(b) && a.Key != b) {
        // Set of all c's related with b
        HashSet<int> all_c_in_bRc = tup[b];

        // All c's related with each b must
        // be subset of all b's related with
        // a
        foreach(int c in all_c_in_bRc)
        {
          if (all_b_in_aRb.Contains(c)) {
            return false;
          }
        }
      }
    }
  }

  // For all aRb and bRc there exist aRc in
  // relation R
  return true;
}

}

static public void Main() {

// Code
// Creating relation R
HashSet<pair> R = new HashSet<pair>();

// Inserting tuples in relation R
R.Add(new pair(1, 1));
R.Add(new pair(1, 2));
R.Add(new pair(2, 1));
R.Add(new pair(2, 2));
R.Add(new pair(1, 3));
R.Add(new pair(2, 3));
R.Add(new pair(3, 4));
R.Add(new pair(1, 4));

Relation obj = new Relation();

// R is not transitive as (2, 4) tuple is not
// present
if (obj.checkTransitive(R)) {
  Console.WriteLine("Transitive Relation");
}
else {
  Console.WriteLine("Not a Transitive Relation");
}

} }

// This code is contributed by lokesh

JavaScript

class Relation { constructor() {}

checkTransitive(R) { // Property 1 if (R.size === 0) { return true; }

// Create a dictionary to store tuple as key value
// pair
const tup = new Map();

// Creating dictionary of relation where (a) is key
// and (b) is value
for (const i of R) {
  if (!tup.has(i[0])) {
    const temp = new Set();
    temp.add(i[1]);
    tup.set(i[0], temp);
  } else {
    tup.get(i[0]).add(i[1]);
  }
}

for (const a of tup) {
  // Set of all b's related with a
  const all_b_in_aRb = tup.get(a[0]);

  // Taking all c's from each b one by one
  for (const b of all_b_in_aRb) {
    if (tup.has(b) && a[0] !== b) {
      // Set of all c's related with b
      const all_c_in_bRc = tup.get(b);

      // All c's related with each b must be
      // subset of all b's related with a
      for (const c of all_c_in_bRc) {
        if (!all_b_in_aRb.has(c)) {
          return false;
        }
      }
    }
  }
}

// For all aRb and bRc there exist aRc in relation R
return true;

} }

function main() { const R = new Set();

// Inserting tuples in relation R R.add([1, 1]); R.add([1, 2]); R.add([2, 1]); R.add([2, 2]); R.add([1, 3]); R.add([2, 3]); R.add([3, 4]); R.add([1, 4]);

const obj = new Relation();

// R is not transitive as (2, 4) tuple is not present if (obj.checkTransitive(R)) { console.log("Transitive Relation"); } else { console.log("Not a Transitive Relation"); } }

main();

// This code is contributed by akashish__.

`

Output

Not a Transitive Relation

**Time Complexity: O(N * K * log N) where N is the number of tuples in relation and K is the maximum number of tuples (a, b) for which **a are same
**Auxiliary Space: O(N)