找到复杂物品的最佳组合?

时间:2017-07-03 08:58:52

标签: java algorithm object combinations

我有以下对象:

enum Slot
{
   HANDS, LEGS, CHEST, HEAD, FEET;
}

class Clothing
{
   // The slot this piece of clothing is worn on.
   Slot s;
   // The color of the clothing, used for `gradeOutfit`
   Color c;
}

class Person
{
   Map<Slot, Clothing> body;

   // look through his outfit and give a score
   // for how well he looks
   int gradeOutfit()
   {
      return ...
   }
}

我有一个Person对象和一个Clothing的集合。此集合包含每个Clothing的许多Slot个对象。例如,它可能如下所示:

MyCloset = { GREEN_HAT, RED_VEST, BLACK_VEST, 
BLUE_JEANS, BROWN_PANTS, RED_SHOES, BLACK_HAT, BLUE_GLOVES, PURPLE_VEST }

在我的程序的现实中,除了这些之外还有很多项目,但这只是一个简化的例子。

问题:

我需要找到这些衣服的组合,这些衣服的得分最高gradeOutfit。这意味着我的Person必须确保他在每个Clothing项目上尝试每个Clothing项目(在限制范围内,例如,不可能戴上两顶帽子)因为两者都适用于HEAD Slot)。 Person只有在gradeOutfit Clothing佩戴Slot项目时才能Person p = new Person(); for (Clothing i : MyCloset) { for (Clothing h : MyCloset) { if (i == h) continue; if (!p.isWearing(h.slot()) { p.wear(h); } } int score = p.gradeOutfit(); } 被调用。

我认为递归是最好的方法,但是我认为如果我有相当数量的项目,我会很快得到堆栈溢出。我尝试迭代地进行,但我似乎无法找到一个很好的简单方法来遍历所有内容。我的程序基本上看起来像

{{1}}

但我知道这只是一种可怕的方法。为了确保每个服装项目都与其他服装项目配对,我需要更多的循环逻辑而不仅仅是这个。无论我尝试什么,它都会变成意大利面条代码。我还需要避免在同一套服装上进行两次循环,并确保没有任何装备组合被遗忘。

接近这样的事情的最佳方式是什么?

3 个答案:

答案 0 :(得分:1)

这是mathematical optimization问题的一个例子。您似乎已经具有目标函数(计算gradeOutfit得分的函数 - 作为输入五个衣物,每个槽一个)并且您需要一些约束(例如,5个组合中的每个衣服属于不同的槽)。您需要一个Java解算器库来执行此操作。如果你的目标函数是线性的,那么线性求解器就可以了。由于我只有商业解算器的经验,我不能推荐一个开源的,可以找到一个选项列表here

一种更简单(但不是非常优雅)的方式,没有求解器:

  1. 创建5组服装对象,每个插槽一个(您可以使用Java HashSet for this)。
  2. 迭代所有组合,每次从5组中的每一组中取出一个项目。您需要n1 x n2 x n3 x n4 x n5个组合,其中ni是每个插槽的服装实例数。
  3. 在我看来,gradeOutfit函数不应该是Person类的一部分 - 因为它实际上是一个装备的属性,而不是一个人(即两个具有相同装备的人具有完全相同的分数)。我更喜欢有一个Outfit课程并把它放在那里。

答案 1 :(得分:0)

您创建的数据结构非常糟糕。

enum Slot
{
   HANDS, LEGS, CHEST, HEAD, FEET;
   numbers = new int[values.length()]
}

enum COLOR
{
   RED,BLUE,...;
}
enum Clothing {
    GREEN_HAT(HEAD,GREEN), ...; 

    Slot slot;
    Color color;
    public static Clothing (Slot slot, Color color){...}
}
class Outfit extends Map <Slot, Clothing> {
    countScore(){};
    public static Outfit(){
        //foreach slot this.put(slot, Clothing.values().get(0));
    }
}
... 
int n=slot.values.length()-1;
Outfit currentOutfit = new Outfit();
Outfit bestOutfit = new Outfit();
int currentActiveSlot = 0;
// make a cycle for combination of all Outfits

答案 2 :(得分:-2)

对于枚举,你必须使用方法&#34; values()&#34;循环它:

 For (clothe c: clothes.values())