Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
376 views
in Technique[技术] by (71.8m points)

php - Search matrix for all rectangles of given dimensions (select blocks of seats)

All,

I have been trying to work out how to select say 15 tickets within a single block of seats.

EDIT: the problem is - how to find all rectangles of given dimensions (say 3x5 for example) of free seats?

enter image description here

The below is my table, and the query selects 4 consecutive seats (or 15 or whatever) which is fine...

But what I want to do is select say 15 seats, these may be split over multiple rows, i.e. 3 x 5, but I would want them to be blocked together i.e.

row 9 ..(some seats)..[5 seats]..(some seats)..
row 8 ..(some seats)..[5 seats]..(some seats)..
row 7 ..(some seats)..[5 seats]..(some seats)..

I.e. they would be 3 rows all in front of each other. row9 seats 10 to 25, row8 seats 10 to 25, row7 seats 10 to 25.

Also may need to consider if a block of seats have varying number of seats i.e. a corner block may be in an arc to has more seats at the back than the front.

Any guidance in form of ehnaceing the SQL or some algorithm or some PHP code. I have been wracking my brain for most of the week now.

CREATE TABLE `seats` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `event_id` int(11) DEFAULT NULL,
  `performance` int(11) DEFAULT NULL,
  `block` int(11) DEFAULT NULL,
  `row` int(11) DEFAULT NULL,
  `seat` int(11) DEFAULT NULL,
  `status` int(10) DEFAULT 1,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

My query to-date - which returns combinations of blocks of X seats.

SELECT    a.event_id, a.performance, a.block,
          a.row, a.seat AS start_seat,
          a.seat + (4 - 1) AS end_seat,
          4 AS requested_seats,
          a.id AS start_allocation_id
FROM      seats a
          LEFT JOIN seats b ON
              a.event_id = b.event_id AND
              a.performance = b.performance AND
              a.block = b.block AND
              a.row = b.row AND
              a.seat < b.seat AND
              b.seat < a.seat + 4 AND
              b.status = 1
WHERE     a.status = 1 AND
          a.event_id = 1
GROUP BY  a.seat
HAVING COUNT(b.seat) + 1 = 4
ORDER BY performance

Thanks in advance, need more info please just ask!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This problem is much better solved outside mysql, in another language. In other words, you have a matrix of seats, some of which are occupied (grey ones):

enter image description here

and you want to find all rectangles of given dimensions, say 3x5. You can do this very efficiently by two pass linear O(n) time algorithm (n being number of seats):

1) in a first pass, go by columns, from bottom to top, and for each seat, denote the number of consecutive seats available up to this one:

enter image description here

repeat, until:

enter image description here

2) in a second pass, go by rows, and look for at least 5 consecutive numbers greater or equal to 3:

enter image description here

so, finally, you get:

enter image description here

which yields the solution: these number sequences (green areas) are top edges of the 2 possible rectangles 3x5 of free seats.

The algorithm could be easily enhanced to e.g. get all rectangles with maximum area. Or, it could be used to find any continuous regions (not only rectangle-shaped) of N seats - just, during the second pass, look for continuous sequence of numbers which sums up to at least N.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...