可能的产品组合

时间:2015-07-03 07:04:17

标签: algorithm

我有一个产品,有多种房间可供选择和定制。例如:

  • 1人房间
  • 带2张特大号床的客房
  • 2人的房间,有两张独立的床
  • 3人房间

当客户订购产品(旅行)时,他会给我们一些参与者(例如:2名成人和2名儿童......)

我必须让顾客能够选择各种房间的组合。在我们的例子中,我们应该:

  • 1个人的4个房间
  • 1人1个房间,3人1个房间
  • 1间可容纳2人的特大号床+ 1间可供2人使用的独立床
  • 2间带特大号床的客房
  • 2间客房,2人,独立床

此时,我不知道该怎么做!

1 个答案:

答案 0 :(得分:3)

这是subset sum问题的变体(包括2个尺寸,成人和儿童),其中您的总和是人数和儿童数,而元素是房间。

看起来,你的问题相当小(你不会拥有数百种房型,只有少数房间类型,而且每位旅行者都会为少数人订房),所以展现所有可能性的蛮力是一种解决问题的可能性。

我们的想法是以递归的方式生成所有这样的房间,并在向客户展示可能性之前 - 检查它是否符合要求。
递归算法将首先猜测"如果你想使用当前的房间类型,并且对于这两个选项都可以 - 针对较小的问题进行递归。

类似Java的伪代码:

private boolean matches(List<Room> rooms, int adults, int children) { 
    //check if the current list of rooms satisfies the demands
}
private int numPersons(List<Room> rooms) { 
    int res = 0;
    for (Room r : rooms) { 
        res += r.adults;
        res += r.children;
    }
    return res;
}

//wrapper function
public void generateAllPossibilities(List<Room> roomTypes, int adults, int children) { 
          generateAllPossibilities(roomTypes, adults, children, new ArrayList<>(), 0);
}

private void generateAllPossibilities(List<Room> roomTypes, int adults, int children, List<Room> soFar, int i) { 
    //check stop clauses, a "good" match, or out of bound:
    if (matches(soFar,adults,children)) {
         showOption(soFar); //succesful stop clause
         return;
    }
    if (i == roomTypes.size() || numPersons(rooms) > adults + children) {  
         return; //failing stop clause
    }
    //"guess" to add the current room type:
    soFar.add(roomTypes.get(i));
    //recurse with that guess:
    generateAllPossibilities(roomTypes, adults, children, soFar, i);
    //"guess" not to add the current room type
    soFar.remove(soFar.size()-1));
    generateAllPossibilities(roomTypes, adults, children, soFar, i+1);
}