La selección aleatoria tiempo que se disipa en función del porcentaje sobre múltiples grupos de

StackOverflow https://stackoverflow.com/questions/2060008

Pregunta

Estoy tratando de armar un sistema sencillo para un usuario para generar una lista de usuarios a los que las encuestas será enviado. La generación de la lista puede depender de diversas limitaciones. Por ejemplo, "sólo queremos gente de los EE.UU. y Canadá" o "sólo queremos gente que tiene una membresía de nivel 2 o nivel 3."

Esta parte es bastante fácil y he configurado las tablas para capturar los criterios de selección. Uno de los criterios adicionales embargo, es que es posible que quieran obtener un determinado porcentaje de cada elemento. Por ejemplo, "dame un 70% los usuarios de Estados Unidos y Canadá el 30% de usuarios." Una vez más, creo que puedo hacerlo sin demasiados problemas. Ellos le darán el número de usuarios que quieren, por lo que sólo puede múltiple por los porcentajes a continuación, asegúrese de que los números todavía se suman después de redondear y estoy listo para salir.

Pensando en el futuro, sin embargo, lo que si querían ciertas averías porcentuales por dos conjuntos de criterios. Por ejemplo, "Dame 70% EE.UU., el 30% de Canadá y, al mismo tiempo, el 50% de nivel 2 usuarios y 50% de nivel 3 a los usuarios." Ya que no es un requisito actual no pienso darme un dolor de cabeza sobre ella, pero si alguien tiene un algoritmo bastante simple (o código SQL) para llevar a cabo algo como esto entonces yo estaría feliz de verlo.

A pesar de que yo preferiría una solución agnóstica DB-, estoy en MS SQL 2005, por lo que las soluciones específicas para RDBMS están muy bien también.

La estructura de la tabla, que actualmente estoy usando es similar a esto:

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)
)
¿Fue útil?

Solución

Se puede descomponer el problema en cuatro grupos de usuarios al azar:

  • usuarios de Estados Unidos, nivel 2, elija 35% de la muestra total deseada
  • los usuarios de Canadá, el nivel 2, elija el 15% del total de la muestra deseada
  • usuarios de Estados Unidos, el nivel 3, elija 35% de la muestra total deseada
  • usuarios Canadá, nivel 3, elija 15% de la muestra total deseada

Si hay un tercer criterio, dividir el problema en ocho juegos. Y así sucesivamente.

Puede parecer artificial para obtener exactamente 50% de nivel 2 y nivel 3 al 50% en ambos grupos de usuarios, los Estados Unidos y Canadá. Dado que se supone que debe ser al azar, se podría esperar que varíe un poco más. Además, ¿y si no son muchos los usuarios de nivel 3 desde Canadá a constituyen el 15% del total?

A medida que los criterios se vuelven más y más selectivo, que está naturalmente quitar de la aleatoriedad de la muestra total. Con el tiempo usted podría tener una larga lista de criterios tales que sólo un subconjunto de los usuarios podría satisfacer, y entonces no habría ninguna aleatoriedad en absoluto.


Re tu comentario: Derecha, SQL no es la mejor solución para cada tipo de problema. Usted puede ser mejor de manejar el problema con un interactivo algoritmo en lugar de una sola consulta SQL basada en el conjunto. Por ejemplo:

  1. Pick una fila aleatoria.
  2. Si la fila se ha elegido ya en una iteración anterior, desprenderse de ella.
  3. Si la fila ayuda a mantener el ritmo de la elección de una muestra total que es el 70% de Estados Unidos, Canadá 30%, 50% de nivel 2, el 50% de nivel 3, mantenerlo. De lo contrario, desprenderse de ella.
  4. Si alcanza el número deseado de muestras, para.
  5. Loop volver al paso 1.

Por supuesto, la cosa se complica si tienes que elegir una fila que ayuda a equilibrar la proporción de 70/30% de las naciones, pero los desequilibrios de la proporción de 50/50% de los niveles. Cómo se descarta o no? Y también es posible que desee hacer caso omiso de las relaciones cuando sólo haya recogido las primeras filas.

Como se comentó @Hogan, esto podría ser un problema NP-completo sin solución. Sin embargo, muchos de estos problemas tienen una solución que le da un "suficientemente bueno" número, aunque no es un resultado demostrable óptima.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top