1

好的,我一直在努力解决这个问题,但我觉得我太累了,无法解决这个问题。

每周我的脚本都会检查一个表格,并将 60 种新产品的状态从停用更改为启用。我想确保这 ​​60 种产品并非全部来自 1 个类别,而是来自具有可激活产品的所有类别。

示例产品表

| productid | category     | status      |
| 1         | iPad 2       | deactivated |
| 2         | iPod Touch 4 | deactivated |

示例数组,您会看到类别名称和可以激活的产品数量。

array(9) {
  ["iPad 2"] => int(2)
  ["iPod Touch 5"] => int(2)
  ["iPod Touch 4"] => int(6)
  ["iPhone 3G/3GS"] => int(94)
  ["iPad 1"] => int(104)
  ["iPad Mini"] => int(150)
  ["iPhone 4/4S"] => int(174)
  ["iPhone 5"] => int(205)
  ["iPad 3/4"] => int(236)
}

现在,我将如何从所有这些类别中激活产品,并很好地划分?

我可以手动粗略计算得到的数组。那将是类别名称和将被激活的产品。共有 60 种产品,很好地划分了各个类别。

array(9) {
  ["iPad 2"] => int(2)
  ["iPod Touch 5"] => int(2)
  ["iPod Touch 4"] => int(6)
  ["iPhone 3G/3GS"] => int(8)
  ["iPad 1"] => int(8)
  ["iPad Mini"] => int(8)
  ["iPhone 4/4S"] => int(8)
  ["iPhone 5"] => int(9)
  ["iPad 3/4"] => int(9)
}

但我缺乏编写这种算法的能力。我希望今天这里有人比我聪明一点?

4

2 回答 2

0

在伪代码中:

EvenlySelect(item_list):
  sorted_items = SortLowestToHighestCount(item_list)
  remaining_num_items = CountTotalNumberOfItems(item_list)
  return_list = Empty()
  while (!Empty(sorted_items)):
    desired_quantity = remaining_num_items / Size(sorted_items))
    if desired_quantity == 0:
      break
    quantity_to_add = 0
    if desired_quantity > sorted_items[0].quantity:
      quantity_to_add = sorted_items[0].quantity
    else:
      quantity_to_add = desired_quantity
    Append(Item(sorted_items[0].category, quantity_to_add), return_list)
    remaining_num_items -= quantity_to_add
    RemoveFirstElement(sorted_items)

  return return_list

这个想法是:从数量最小的类别到数量最大的类别。在每个步骤中,计算出您需要从该类别中获得多少个项目才能保持平衡(鉴于您在前面的步骤中已经选择了哪些项目)。如果该类别有足够的项目,那就拿那么多。否则尽可能多地服用。

于 2013-02-25T16:38:09.450 回答
0
import java.util.Arrays;
import java.util.Random;

public class Selection {
    public static void main(String[] args) {
        //input arrays
        String[] categories = {"iPad 2","iPod Touch 5","iPod Touch 4","iPhone 3G/3GS","iPad 1","iPad Mini","iPhone 4/4S","iPhone 5","iPad 3/4"};
        int[] quantities = {2,2,6,94,104,150,174,205,236};
        //ensure that there's at least one item for each category
        int[] distributions = {1,1,1,1,1,1,1,1,1};
        int[] intervals = new int[9];
        intervals[0] = 2;
        for (int i=1;i<9;i++) {
            intervals[i] = intervals[i-1]+quantities[i];
        }
        Random generator = new Random();
        int range = intervals[intervals.length-1];
        for (int j=0;j<51;j++) { //to fill the remaining 51 slots according roughly to their proportions
            int randomInt = generator.nextInt(range); //generate an integer between 0 and 2+2+6+94+104+150+174+205+236 at random
            if (randomInt < intervals[0]) {
                distributions[0]++;
            } 
            else if (randomInt >= intervals[0] && randomInt < intervals[1]) {
                distributions[1]++;
            }
            else if (randomInt >= intervals[1] && randomInt < intervals[2]) {
                distributions[2]++;
            }
            else if (randomInt >= intervals[2] && randomInt < intervals[3]) {
                distributions[3]++;
            }
            else if (randomInt >= intervals[3] && randomInt < intervals[4]) {
                distributions[4]++;
            }
            else if (randomInt >= intervals[4] && randomInt < intervals[5]) {
                distributions[5]++;
            }
            else if (randomInt >= intervals[5] && randomInt < intervals[6]) {
                distributions[6]++;
            }
            else if (randomInt >= intervals[6] && randomInt < intervals[7]) {
                distributions[7]++;
            }
            else {
                distributions[8]++;
            }
        }
        System.out.println("array(9) {");
        for (int k=0; k< 9; k++) {
            System.out.println("  [\""+categories[k]+"\"] => int("+distributions[k]+")");
        }
        System.out.println("}");
    }
}

我已经测试了上面完整且有效的代码,并希望代码是不言自明的。

这是我刚刚得到的示例输出:

array(9) {
  ["iPad 2"] => int(1)
  ["iPod Touch 5"] => int(1)
  ["iPod Touch 4"] => int(2)
  ["iPhone 3G/3GS"] => int(6)
  ["iPad 1"] => int(7)
  ["iPad Mini"] => int(11)
  ["iPhone 4/4S"] => int(8)
  ["iPhone 5"] => int(13)
  ["iPad 3/4"] => int(11)
}

这个想法很简单:我们首先为每个类别保留一个项目,这会占用 9 个插槽。一个一个地考虑剩下的 51 个插槽,每个插槽都有机会根据其比例进入各自的类别。由于项目的总数不够大,而且我们使用随机函数生成一个整数,所以我们不能保证结果完全符合每个类别的比例。尽管如此,我认为该解决方案足以满足您的目的。

于 2013-02-25T20:05:37.923 回答