如何连续找到空位?

时间:2012-01-11 09:35:24

标签: combinatorics

我想将一组人(在运行时给出)放入二维数组的点中,随机地连续组合(找出所有可能的位置并随机选择一个)

首先,我想首先尝试数组

如果我有一个大小为10的点阵列,如下所示

spots[occupied,open,open,occupied,occupied,occupied,open,open,open,open]

放两个人

是否有特定的算法来解决这类问题? 谢谢你的帮助!

3 个答案:

答案 0 :(得分:1)

在python中:

seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]

def empty(seats,index,count):
  if count == 0:
     return True
  else:
     return (seats[index] == "open") & empty(seats,index+1,count-1)

def findEmpty(seats,count):
  result = []
  for (i=0;i<seats.size-count+1,i++)
    if empty(seats,i,count):
      result.append(<list of consecutive numbers from i to i+count>)
  return result


print findEmpty(seats,2)  

>>>[[1, 2], [6, 7], [7, 8], [8, 9]]

这是另一种方法,它的效率更高一些:

seats = ["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
//counts the number of consecutive free seats starting at position index
def countEmpty(seats,index):
    if index >= len(seats) or seats[index] == "occupied":
        return 0
    return 1 + countEmpty(seats,index+1)

def findEmpty(seats,count):
    result = []
    i = 0
    while i < len(seats)-count+1:
       c = countEmpty(seats,i)
          if c>=count:
             for (j=i;j<i+c-count+1;j++):
                result.append(<list of consecutive numbers from j to j+count>)
       i += 1 + c
    return result

print findEmpty(seats,2)
>>>[[1, 2], [6, 7], [7, 8], [8, 9]]

最后,如果你选择使用python,你可以在一行中完成:

seats =["occupied","open","open","occupied","occupied","occupied","open","open","open","open"]
count = 2    
print [range(i,i+count) for i in range(len(seats)-count+1) if all([seats[j]=="open" for j in range(i,i+count)]) ]
>>> [[1, 2], [6, 7], [7, 8], [8, 9]]

答案 1 :(得分:0)

伪代码:

//Create 2 lists of blocks, both empty: tmp and final
List tmp=new List;
List final=new List;

//Cycle the seats
for (int i=0;i<length(seats);i++) {
    //If the seat is occupied, start over
    if (seats[i]==occupied) tmp.empty();
    else {
        //Cycle existing block candidates, add free seat
        foreach (ref block in tmp) {
            block.add(seats[i])
            if (length(block)>=people_count) {
                //HEUREKA, got a fitting block: Move it to the final list
                tmp.remove(block)
                final.add(block)
            }
        }
        //Start a new block with this seat
        tmp.add(new block(seats[i]));
        //Read below for this edge case
    }
}

final现在有了块。

如果允许people_num的边缘大小为1,则必须在伪代码中指示的位置检查完整的块

答案 2 :(得分:0)

我将使用 Mathematica 代码但我相信你可以遵循逻辑。

从:

开始
dat = spots[occupied, open, open, occupied, occupied, occupied, open, open, open, open];
fill = {"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"};

首先找到列表fill的随机排列(很容易在StackOverflow上找到算法):

randomfill = RandomSample @ fill
  

{“Delta”,“Echo”,“Alpha”,“Bravo”,“Charlie”,“Foxtrot”}

然后将函数“映射”到spots列表的每个元素上,如果元素为open,则返回randomfill列表中的下一个值,否则返回元素不变:

i = 1;
If[# === open, randomfill[[i++]], #] & /@ dat
  

斑点[占领,“三角洲”,“回声”,占用,占用,占领,“阿尔法”,“布拉沃”,“查理”,“狐步舞”]