Php 所以,最后,你会得到: 这就产生了解决方案:这些数字序列(绿色区域)是两个可能的矩形3x5的自由座位的上边缘 该算法可以很容易地增强,例如,获得所有具有最大面积的矩形。或者,它可以用来找到N个座位的任何连续区域(不仅仅是矩形区域)——只是在第二遍中,寻找
Php 所以,最后,你会得到: 这就产生了解决方案:这些数字序列(绿色区域)是两个可能的矩形3x5的自由座位的上边缘 该算法可以很容易地增强,例如,获得所有具有最大面积的矩形。或者,它可以用来找到N个座位的任何连续区域(不仅仅是矩形区域)——只是在第二遍中,寻找,php,mysql,algorithm,ticket-system,Php,Mysql,Algorithm,Ticket System,所以,最后,你会得到: 这就产生了解决方案:这些数字序列(绿色区域)是两个可能的矩形3x5的自由座位的上边缘 该算法可以很容易地增强,例如,获得所有具有最大面积的矩形。或者,它可以用来找到N个座位的任何连续区域(不仅仅是矩形区域)——只是在第二遍中,寻找至少等于N的连续数字序列。我来这里是为了寻找Python解决方案。这是我的,它返回所有位置: import numpy s = '''0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 0 0
所以,最后,你会得到:
这就产生了解决方案:这些数字序列(绿色区域)是两个可能的矩形3x5的自由座位的上边缘
该算法可以很容易地增强,例如,获得所有具有最大面积的矩形。或者,它可以用来找到N个座位的任何连续区域(不仅仅是矩形区域)——只是在第二遍中,寻找至少等于N的连续数字序列。
我来这里是为了寻找Python解决方案。这是我的,它返回所有位置:
import numpy
s = '''0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 1 0 1 0 1
0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0'''
area = 15
nrows = 6
ncols = 11
skip = 1
a = numpy.fromstring(s, dtype=int, sep=' ').reshape(nrows, ncols)
w = numpy.zeros(dtype=int, shape=a.shape)
h = numpy.zeros(dtype=int, shape=a.shape)
for r in range(nrows):
for c in range(ncols):
if a[r][c] == skip:
continue
if r == 0:
h[r][c] = 1
else:
h[r][c] = h[r-1][c]+1
if c == 0:
w[r][c] = 1
else:
w[r][c] = w[r][c-1]+1
minw = w[r][c]
for dh in range(h[r][c]):
minw = min(minw, w[r-dh][c])
if (dh+1)*minw == area:
print(
'area', area, 'row', r, 'col', c,
'height', dh+1, 'width', minw)
输出:
area 15 row 4 col 8 height 3 width 5
area 15 row 5 col 10 height 3 width 5
为此干杯。。。伟大的信息调查,因为你可以理解的复杂性(和非常繁忙),它可能需要一些时间来验证结果!同时我也投了赞成票,我不认为在DB这样做是个好主意。场地小到可以更快、更高效地将其加载到内存中并在那里执行操作,而不是执行磁盘操作。所有这些都过于复杂。在O(N)中有一个非常简单的解决方案,见我的帖子。顺便说一句,只是一个“草稿”,但是你得到了这样的想法。你已经写过类似这样的东西了-积木可能是弯曲的或梯形的,前面的座位比后面的座位要少,这对于概念验证来说是很好的,但是如果你处理了100或1000次预订请求,这是不可行的:)我不确定我是否知道你在尝试做什么以及情况如何。。。但是,应用一排可用席位的掩码(如IP子网掩码)怎么样?e、 g.
0001111000
,所有的1都可用。布赖恩,你想找到所有的矩形块3x5的免费座位吗?这是正确的吗?我发布了一个答案-这是你想要的吗?你可以修改得很好,因为简单的解决方案(尝试每个边界框)至少是O(nm),其中m是块的大小。不过,你怎么才能找到一排7人的座位呢?@Nick,非常简单——在第二遍中,只需寻找至少7人的数字序列即可。例如,您可以添加“不超过两行”这样的条件,因此在这种情况下,每个大于2的数字将仅计为2。项目已被合并。。。但这将是一个优雅的解决方案。
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
$nr_tickets = 15; // or whatever
// build an array of different configurations:
// since you always want people as close to eachother as possible this is a suggestion:
$configurations = array();
for($columns=1; $columns<=$nr_tickets; $columns++)
{
$BLOCK = array();
$remainder = $nr_tickets % $columns;
// $nr_tickets - $remainder = greatest number divisible exactly by $i (columns) which is the number of rows you want.
$rows = (($nr_ticket-$odd) / $i);
//$configurations[$columns] = $rows // make a rectangle configuration or $columns x $rows with $remainder tickets left.
$BLOCK[] = array_fill(0, $columns, array_fill(0, $rows, X); // multidimensional array
for($a=0; $a<$odd; $a++)
{
// each of the remainder seats need to be 'stuck on to the block/rectangle of seats you already have, this can be done in
// ($rows + $columns * 2) - $a ways for each of the consecutive non-assigned tickets
/*
lets say you have a block of 2x7 (s) with 1 (N) possible ticket left
N N N N N N N
N s s s s s s s N
N s s s s s s s N
N N N N N N N
*/
// so basically we can add a ticket to each of the rows and for each of those configurations we need to add $a more
// this may be simpler with a recursive function call that adds $a more for each 1 ticket you add here to a row or a column.
}
}
// now you can go select all different permutations of settings from the database and select one you like :)
CREATE TABLE Seat {
SeatID int,
Status int,
...
NorthID int,
NorthWestID int,
WestID int,
...
NorthEastID int
}
SELECT * FROM Seat x
INNER JOIN Seat n ON x.NorthID = n.SeatID
INNER JOIN Seat nw ON x.NorthWestID = n.SeatID
...
SELECT row, col,
(select sum(taken) from seat as s2
where s2.row >= s1.row and s2.row < s1.row + 2
and s2.col >= s1.col and s2.col < s1.col + 2) as count
FROM seat as s1
import numpy
s = '''0 0 0 0 1 0 0 0 1 0 0
0 0 0 0 0 0 1 0 1 0 1
0 1 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0
0 0 1 1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0 0 0'''
area = 15
nrows = 6
ncols = 11
skip = 1
a = numpy.fromstring(s, dtype=int, sep=' ').reshape(nrows, ncols)
w = numpy.zeros(dtype=int, shape=a.shape)
h = numpy.zeros(dtype=int, shape=a.shape)
for r in range(nrows):
for c in range(ncols):
if a[r][c] == skip:
continue
if r == 0:
h[r][c] = 1
else:
h[r][c] = h[r-1][c]+1
if c == 0:
w[r][c] = 1
else:
w[r][c] = w[r][c-1]+1
minw = w[r][c]
for dh in range(h[r][c]):
minw = min(minw, w[r-dh][c])
if (dh+1)*minw == area:
print(
'area', area, 'row', r, 'col', c,
'height', dh+1, 'width', minw)
area 15 row 4 col 8 height 3 width 5
area 15 row 5 col 10 height 3 width 5