给定尺寸的所有矩形的搜索矩阵(选择座位块)
总之,
我一直在尝试弄清楚如何在一个座位区中选择 15 张门票。
编辑:问题是 - 如何找到给定尺寸(例如 3x5)的所有矩形空闲座位?
下面是我的表格,查询选择 4 个连续座位(或 15 个或其他),这很好...
但我想做的是选择 15 个座位,这些座位可能会分成多排,即 3 x 5,但我希望它们被挡在一起,即
row 9 ..(some seats)..[5 seats]..(some seats)..
row 8 ..(some seats)..[5 seats]..(some seats)..
row 7 ..(some seats)..[5 seats]..(some seats)..
它们将是 3 排都在彼此前面。第 9 排座位 10 到 25 个,第 8 排座位 10 到 25 个,第 7 排座位 10 到 25 个。
还可能需要考虑一组座位是否有不同数量的座位,即角座可能呈弧形,后面的座位数多于后面的座位数。前面。
任何以增强 SQL 或某些算法或某些 PHP 代码的形式提供的指导。这周的大部分时间我都在绞尽脑汁。
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;
我迄今为止的查询 - 返回 X 个座位块的组合。
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
预先感谢,需要更多信息,请询问!
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?
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
这个问题在 mysql 之外用另一种语言可以更好地解决。换句话说,您有一个座位矩阵,其中一些已被占用(灰色座位):
和您想要找到给定尺寸的所有矩形,例如 3x5。您可以通过两次线性
O(n)
时间算法(n是座位数)非常有效地完成此操作:第一次通过1),按列从下到上,对于每个座位,表示到此为止可用的连续座位数:
重复,直到:
2) 在第二遍中,逐行查找,并查找至少 5 个连续数字大于或等于 3:
所以,最后,您得到:
<图片src="https://i.sstatic.net/pddAx.gif" alt="在此处输入图像描述">
得出解决方案:这些数字序列(绿色区域)是 2 个可能的 3x5 空闲座位矩形的顶部边缘。
该算法可以很容易地增强,例如获得具有最大面积的所有矩形。或者,它可以用于查找 N 个座位的任何连续区域(不仅是矩形) - 只需在第二遍期间查找总和至少为 N 的连续数字序列。
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):
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:
repeat, until:
2) in a second pass, go by rows, and look for at least 5 consecutive numbers greater or equal to 3:
so, finally, you get:
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.
根据您的描述,这不是数据库问题,而是算法问题。我建议使用平铺模式,可能是四叉树或空间填充曲线。也许 MySQL 中的空间索引也能帮助您解决问题。 si 将 2d 平面细分为 4 个图块。
From your description this isn't a database problem but an algorithmic problem. I suggest a tiling schema maybe a quadtree or a space-filling-curve. Perhaps a spatial-index in MySQL would help you solve your problem, too. A si subdivide the 2d plane into 4 tiles.
我来这里是为了寻找 Python 解决方案。这是我的,它返回所有位置:
输出:
I came here looking for a Python solution. Here is mine, which returns all positions:
Output:
如果您可以以编程方式创建查询,我只需为每一行编写一个查询并使用
UNION
组合它,然后只需使用相同的查询 X 次,只需继续将它们附加到UNION
代码>.来自 mysql 手册
I would just write a query for each row and combine it using
UNION
if you can programmatically create your query, then just use the same query X number of times just keep appending them withUNION
.From the mysql manual
这是一个简单的方法。它可能不够快,无法满足您的需求,但它是一个起点。
让我们简化问题并考虑一个名为
seat
的表,其中包含row
、col
和taken
列。前两个是整数,另一个是布尔值。我们希望找到限制在特定大小矩形内的row
和col
值,其中taken
普遍为 false。我们将尝试一个查询,该查询移动一个矩形并记录其中所取值的总和。我们想要的矩形的总和为零。假设我们正在寻找 2x2 块的开放座位。这是查询。
只需过滤此查询的输出,其中
count = 0
。row
和col
将指定开放块的左上角。最后一个怪癖是,您需要过滤掉太靠近座位右侧或底部边缘的左上角,因为这会人为地减少它们的总和(测试的矩形被裁剪在座位的边缘上)。在 2x2 块的情况下,这意味着row < max(row) 和
col <最大(列)
。现在,在查找 15 个相邻座位的情况下,您正在寻找 15x1、1x15、3x5 和 5x3 的矩形。您可以将上述查询放入一个采用矩形宽度和高度参数的存储过程中,然后使用这些尺寸调用它,直到找到匹配项。
Here is a straightforward approach. It may not be fast enough for your needs, but it is a place to start.
Let's simplify the problem and consider a table called
seat
having columnsrow
,col
, andtaken
. The first two are integers, the other is a boolean. We want to find values ofrow
andcol
constrained to certain sized rectangles whereintaken
is universally false. We'll try a query which moves a rectangle around and records the sum of thetaken
values within. The rectangles we want will have a sum of zero.Let's just say we're looking for 2x2 blocks of open seats. Here's the query.
Just filter the output of this query where
count = 0
. Therow
andcol
will designate the upper left corner of the open block. One final quirk is that you will want to filter out upper left corners that cut too close to the right or bottom edges of the seating, because that will artificially decrease their sum (the tested rectangle is clipped against the edges of the seating). In the case of 2x2 blocks, this meansrow < max(row)
andcol < max(col)
.Now in the case of finding 15 adjacent seats, you are looking for 15x1, 1x15, 3x5 and 5x3 rectangles. You could make the above query into a stored procedure that takes rectangle width and height parameters, and then call it with those sizes until you find a match.
首先,我假设大多数场地都可以映射(即使是近似的)到方形网格,即。座位的设置并不奇怪,也没有奇怪的偏移。因此,每个座位周围最多可以有八个座位。
本质上,我将能够创建一个“座位图”并根据查询的需要遍历它。然后,您可以创建查询来获取某些形状或块。
3x3 网格将包括选择一个开放座位,其中所有方向上直接链接的座位也都是开放的。是的,这将是八个 JOINS,但请尝试一下并稍后优化。
1x15 块将是一个查询,用于选择一个开放座位,您可以沿着 EastID 或 WestID 加入 14 个深度。
您也许可以以编程方式概括和生成查询。
PS:根据您使用的引擎,您可能具有内置的空间功能。
祝你好运。
First, I'm going to assume that most venues can be mapped (even if approximated) to a square grid, ie. where the seats aren't strangely setup or weirdly offset. As such, each seat may have up to eight seats around it.
Essentially, I will be able to create a "seat graph" and walk it according to needs in querying. Then, you can create queries to get certain shapes or blocks.
A 3x3 grid would consist of selecting an open seat where the immediate linked seats in all directions are also open. Yes, it would be eight JOINS, but try it out and optimize later.
A 1x15 block would be a query to select an open seat where you join 14 deep along the EastID or WestID.
You can probably generalize and generate the queries programatically.
PS: Depending on which engine you are using, you may have built-in spatial capabilities.
Good luck.