1

我正在尝试为用户构建一个简单的系统,以生成将向其发送调查的用户列表。列表生成可能取决于各种约束。例如,“我们只想要来自美国和加拿大的人”或“我们只想要拥有 2 级或 3 级会员资格的人”。

这部分非常简单,我已经设置了表格来捕获选择标准。不过,一个额外的标准是,他们可能希望获得每个项目的一定百分比。例如,“给我 70% 的美国用户和 30% 的加拿大用户”。再一次,我认为我可以做到这一点而没有太多麻烦。他们会给出他们想要的用户数量,所以我可以乘以百分比,然后确保数字在四舍五入后仍然相加,我很高兴。

但是,考虑到未来,如果他们想要通过两组标准进行某些百分比细分怎么办。例如,“给我 70% 的美国、30% 的加拿大,同时给我 50% 的 2 级用户和 50% 的 3 级用户。” 由于这不是当前的要求,我不打算让自己为此头疼,但如果有人有一个相当简单的算法(或 SQL 代码)来完成这样的事情,那么我很乐意看到它。

虽然我更喜欢与 DB 无关的解决方案,但我使用的是 MS SQL 2005,因此特定于该 RDBMS 的解决方案也很好。

我目前使用的表结构类似于:

CREATE TABLE Selection_Templates
(
     template_code     VARCHAR(20)     NOT NULL,
     template_name     VARCHAR(100)    NOT NULL,
     CONSTRAINT PK_Selection_Templates PRIMARY KEY CLUSTERED (template_code),
     CONSTRAINT UI_Selection_Templates UNIQUE (template_name)
)
GO
CREATE TABLE Selection_Template_Countries
(
     template_code            VARCHAR(20)       NOT NULL,
     country_code             CHAR(3)           NOT NULL,
     selection_percentage     DECIMAL(2, 2)     NULL,
     CONSTRAINT PK_Selection_Template_Countries PRIMARY KEY CLUSTERED (template_code, country_code),
     CONSTRAINT CK_Selection_Template_Countries_selection_percentage CHECK (selection_percentage > 0),
     CONSTRAINT FK_Selection_Template_Countries_Selection_Template FOREIGN KEY (template_code) REFERENCES Selection_Templates (template_code)
)
GO
CREATE TABLE Selection_Template_User_Levels
(
     template_code            VARCHAR(20)       NOT NULL,
     user_level               SMALLINT          NOT NULL,
     selection_percentage     DECIMAL(2, 2)     NULL,
     CONSTRAINT PK_Selection_Template_User_Levels PRIMARY KEY CLUSTERED (template_code, user_level),
     CONSTRAINT CK_Selection_Template_User_Levels_selection_percentage CHECK (selection_percentage > 0),
     CONSTRAINT FK_Selection_Template_User_Levels_Selection_Template FOREIGN KEY (template_code) REFERENCES Selection_Templates (template_code)
)
4

1 回答 1

2

您可以将问题分解为四组随机用户:

  • 美国用户,2 级,选择所需总样本的 35%
  • 加拿大用户,2 级,选择所需总样本的 15%
  • 美国用户,3 级,选择所需总样本的 35%
  • 加拿大用户,3 级,选择所需总样本的 15%

如果有第三个标准,把问题分成八组。等等。

在美国和加拿大这两组用户准确获得50% 的 2 级和 50% 的 3 级似乎是不自然的。由于它应该是随机的,因此您可能期望它会有更多变化。另外,如果来自加拿大的 3 级用户占总数的 15% 并不多怎么办?

随着标准变得越来越有选择性,您自然会摆脱总样本的随机性。最终,您可能会拥有一长串标准,这样只有一个用户子集可以满足它,然后就完全没有随机性了。


回复您的评论:是的,SQL 并不是每种问题的最佳解决方案。您最好使用迭代算法而不是单个基于集合的 SQL 查询来处理问题。例如:

  1. 随机选择一行。
  2. 如果在之前的迭代中已经选择了该行,则丢弃它。
  3. 如果该行有助于保持选择美国 70%、加拿大 30%、2 级 50%、3 级 50% 的总样本的步伐,请保留它。否则,丢弃它。
  4. 如果达到所需的样本数量,请停止。
  5. 循环回到步骤 1。

当然,如果你选择一个有助于平衡 70/30% 国家比例但不平衡 50/50% 等级比例的行会变得很棘手。你丢弃还是不丢弃?当您只选择前几行时,您可能还想忽略这些比率。

正如@Hogan 评论的那样,这可能是一个无法解决的 NP 完全问题。但是许多此类问题都有一个解决方案,可以为您提供“足够好”的结果,尽管不是可证明的最佳结果。

于 2010-01-13T20:40:17.977 回答