Open In App

Transitive Relation on a Set

Improve
Improve
Like Article
Like
Save
Share
Report

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:

  • Firstly, find the tuples of form aRb & bRc in the relation.
  • For every such pair check if aRc is also present in R.
  • If any of the tuples does not exist then the relation is not transitive else it is transitive.

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<pair> R)
    {
      // Property 1
      if (R.size() == 0) {
        return true;
      }
      // Create a hashmap to store tuple as key value
      // pair
      HashMap<Integer, Set<Integer> > 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<pair> 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.


Python3




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<pair> R)
    {
      // Property 1
      if (R.Count == 0) {
        return true;
      }
      // Create a hashmap to store tuple as key value
      // pair
      Dictionary<int, HashSet<int> > tup
        = new Dictionary<int, HashSet<int> >();
 
      // 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)



Last Updated : 02 Jan, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads