This is a [tag:gaps-and-islands] problem. Assuming there are no gaps or duplicates in the same `id_set` set:

    WITH partitioned AS (
      SELECT
        *,
        number - ROW_NUMBER() OVER (PARTITION BY id_set) AS grp
      FROM atable
      WHERE status = 'FREE'
    ),
    counted AS (
      SELECT
        *,
        COUNT(*) OVER (PARTITION BY id_set, grp) AS cnt
      FROM partitioned
    )
    SELECT
      id_set,
      number
    FROM counted
    WHERE cnt >= 3
    ;

Here's a SQL Fiddle demo link for this query: http://sqlfiddle.com/#!12/59db6/1.

  [2]: http://sqlfiddle.com/#!12/b1b39/5