Question

Je suis en train de mettre en place un système simple pour un utilisateur de générer une liste d'utilisateurs à qui les enquêtes seront envoyés. La génération de liste peut dépendre de diverses contraintes. Par exemple, « nous voulons que les gens de américains et canadiens » ou « nous voulons que les personnes qui ont un niveau 2 ou 3 membres. »

Cette partie est assez facile et je l'ai mis en place les tables pour saisir les critères de sélection. Un critère supplémentaire cependant, est qu'ils peuvent vouloir obtenir un certain pourcentage de chaque élément. Par exemple, "me donner 70% des utilisateurs américains et 30% des utilisateurs du Canada." Encore une fois, je pense que je peux le faire sans trop de difficultés. Ils donneront le nombre d'utilisateurs qu'ils veulent, donc je ne peux que plusieurs par les pourcentages puis assurez-vous que les chiffres ajoutent encore après arrondi et je suis bon pour aller.

Penser à l'avenir si, s'ils voulaient certaines pannes de pourcentage par deux séries de critères. Par exemple, « Donne-moi 70% États-Unis, 30% au Canada et en même temps, 50% niveau 2 utilisateurs et 50% de niveau 3 utilisateurs. » Étant donné que ce n'est pas une exigence actuelle, je ne suis pas l'intention de me donner un mal de tête au-dessus, mais si quelqu'un a ce alors je algorithme assez simple (ou code SQL) pour accomplir quelque chose comme heureux de le voir.

Bien que je préférerais une solution DB-agnostique, je suis sur MS SQL 2005, si des solutions spécifiques à ce SGBDR sont bien aussi.

La structure de la table que je suis actuellement en utilisant est similaire à ceci:

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)
)
Était-ce utile?

La solution

Vous pouvez décomposer le problème en quatre groupes d'utilisateurs au hasard:

  • les utilisateurs des États-Unis, le niveau 2, choisissez 35% de l'échantillon total souhaité
  • utilisateurs au Canada, niveau 2, choisissez 15% de l'échantillon total souhaité
  • les utilisateurs des États-Unis, le niveau 3, choisissez 35% de l'échantillon total souhaité
  • utilisateurs au Canada, niveau 3, choisissez 15% de l'échantillon total souhaité

S'il y a un troisième critère, diviser le problème en huit ensembles. Et ainsi de suite.

Il peut sembler artificielle pour obtenir exactement niveau 50% 2 et 50% de niveau 3 dans à la fois groupes d'utilisateurs, des États-Unis et au Canada. Comme il est censé être aléatoire, vous pouvez vous attendre à varier un peu plus. De plus s'il n'y a pas beaucoup de niveau 3 utilisateurs du Canada pour compenser 15% du total?

Comme les critères deviennent de plus en plus sélectifs, vous prenez naturellement loin de l'aspect aléatoire de l'échantillon total. Finalement, vous pourriez avoir une longue liste de critères tels que seul un sous-ensemble de vos utilisateurs pourrait le satisfaire, et il n'y aurait pas du tout hasard.


Re votre commentaire: droit, SQL est pas la meilleure solution pour chaque type de problème. Vous pouvez être mieux traiter le problème avec un itérative algorithme au lieu d'un seul basé sur un ensemble requête SQL. Par exemple:

  1. Choisir une rangée aléatoire.
  2. Si la ligne a été choisie déjà dans une itération précédente, mettre au rebut.
  3. Si la ligne aide à garder le rythme de choisir un échantillon total qui est de 70% des États-Unis, 30% au Canada, le niveau de 50% 2, le niveau de 50% 3, le garder. Sinon, jetez-le.
  4. Si vous atteignez le nombre désiré d'échantillons, arrêter.
  5. Boucle de retour à l'étape 1.

Bien sûr, il devient délicat si vous choisissez une ligne qui aide à équilibrer le rapport 70/30% du pays, mais les déséquilibres du rapport 50/50% du niveau. Avez-vous défaussez ou non? Et aussi, vous pouvez ignorer les rapports lorsque vous avez seulement choisi les premières lignes.

@Hogan a commenté, cela pourrait être un problème sans solution NP-complet. Mais beaucoup de ces problèmes ont une solution qui vous donne un résultat « assez bon », mais pas un résultat optimal prouvable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top