houzz室内设计app,wordpress仿seowhy基础指南模板,产品展示型网站,如何的找网站建设公司目录原理保守组检测非保守组检测二次重复测试自适应二次重复测试四种测试方法的核心代码保守群组测试非保守群组测试二次重复测试与自适应二次重复测试测试代码参考文献原理
假设该病在人群中的患病率#xff08;先验概率#xff09;为p#xff0c;我们想用群体检验法检验N…
目录原理保守组检测非保守组检测二次重复测试自适应二次重复测试四种测试方法的核心代码保守群组测试非保守群组测试二次重复测试与自适应二次重复测试测试代码参考文献原理
假设该病在人群中的患病率先验概率为p我们想用群体检验法检验N个独立样本组大小n即样本数量。 单个试验的诊断方法的FNR用fN表示FPR可忽略不计。 用G表示一组样本G0表示G中的所有样本均未感染。相反G1意味着G是一个阳性组即它至少有一个感染标本。通过观察不同方法的分组试验结果我们将一个组分为感染组和未感染组分别用Gˆ1和Gˆ0表示。
保守组检测 非保守组检测 步骤如下 每个Group由三个sample人的血液组成。 这样能保证每个Group能被测试两次也代表着每个sample人的血液能够被测试两次fN表示单个试验的FNR(false negative rate)这样就能保证Sg群体水平敏感度 1 - fN^2; 总的来说Gi、Gi1为阳性则Mi,i1也为阳性。 这样图1中的M2,3和M3,4都是正的很可能是因为G31。尽管在G21和G41的情况下也会出现这些阳性结果但缺少M1,21和M4,11使得G2和G4都不太可能等于1。在这种方法中例如如果G2为真阳性M1,20为假阴性结果我们将忽略G21从而导致灵敏度降低。
在非保守组检测中有以下规则:
二次重复测试
简单来说就是对分组之后检测的所有组都检测两遍只要有一次为阳则说明这个组中有阳性。
自适应二次重复测试
第二次测试将第一次测试中为阴性的进行测试。
四种测试方法的核心代码 【0】保守群组测试 【1】非保守群组测试 【2】二次重复测试 【3】二次自适应重复测试 保守群组测试
//非保守测试
//输入splited_group 、 分组混合血液 、 假阴率 fnr
//输出检测出来的阳性样本数、总检测次数
int No_Conservative_Group_Detection(vectorvectorint splited_group,vectorint result, float fnr, vectorint Positive_Group, vectorint PositiveSamples)
{//将Gi、Gi1混合到一起为Mi//如果相邻两个MMj,Mj1检测结果是阳性则认定是Gj1是阳性。//如果只有单独的Mj检测结果是阳性则将Gj与Gj1都检测一遍。int All_Test_Times 0;//【step1】将G血液结果两两混合到M中vectorint Mixed_Group_Result;for (int i 0; i result.size() - 1; i){if (result[i] 1 || result[i 1] 1)Mixed_Group_Result.emplace_back(1);else Mixed_Group_Result.emplace_back(0);}//第一个样本与最后一个样本混合if(result[0] 1 || result[result.size()-1] 1) Mixed_Group_Result.emplace_back(1);else Mixed_Group_Result.emplace_back(0);//【step2】对M结果进行检测,需要考虑到假阴性影响,得到阳性G序号vectorint Blured_Mixed_Group_Result;Test_Synthetic_Blood(Mixed_Group_Result, Blured_Mixed_Group_Result, fnr);All_Test_Times Mixed_Group_Result.size();//寻找检测结果为阳性的Mfor (int j 0; j Blured_Mixed_Group_Result.size() - 1; j){//如果是两个连在一起的为阳性取交集的Gif (Blured_Mixed_Group_Result[j] 1 Blured_Mixed_Group_Result[j 1] 1){Positive_Group.emplace_back(j1);}else if(Blured_Mixed_Group_Result[j] 1 Blured_Mixed_Group_Result[j 1] 0){//如果Gj已经被送入结果那么只需要再送入Gj1if (!Positive_Group.empty() Positive_Group.back() j){Positive_Group.emplace_back(j 1);}//否则将两个都送入else{Positive_Group.emplace_back(j);Positive_Group.emplace_back(j 1);}}}cout 非保守测试可能为阳性的Group个数 Positive_Group.size() endl;//对每个可能阳性的Group进行核酸检测for (int i 0; i Positive_Group.size(); i){int pos_index Positive_Group[i];//对可能阳性Group中每个样本都进行检测要考虑到假阴性的影响得到阳性的样本的序号。vectorint Blured_Splited_GroupResult;Test_Synthetic_Blood(splited_group[pos_index], Blured_Splited_GroupResult, fnr);//对检测结果进行记录记录下在原序列中的坐标for (int j 0; j Blured_Splited_GroupResult.size(); j){if (Blured_Splited_GroupResult[j] 1){PositiveSamples.emplace_back(pos_index* splited_group[0].size() j);} }}All_Test_Times Positive_Group.size() * splited_group[0].size();return All_Test_Times;}非保守群组测试
//保守测试
//输入splited_group 、 分组混合血液 、 假阴率 fnr
//输出检测出来的阳性样本数、总检测次数
int Conservative_Group_Detection(vectorvectorint splited_group, vectorint result, float fnr, vectorint Positive_Group, vectorint PositiveSamples)
{//将Gi、Gi1混合到一起为Mi//如果M检测结果是阳性则认定是Gj,Gj1是阳性。int All_Test_Times 0;//【step1】将G血液结果两两混合到M中vectorint Mixed_Group_Result;for (int i 0; i result.size() - 1; i){if (result[i] 1 || result[i 1] 1)Mixed_Group_Result.emplace_back(1);elseMixed_Group_Result.emplace_back(0);}//第一个样本与最后一个样本混合if (result[0] 1 || result[result.size() - 1] 1) Mixed_Group_Result.emplace_back(1);else Mixed_Group_Result.emplace_back(0);//【step2】对M结果进行检测,需要考虑到假阴性影响,得到阳性G序号vectorint Blured_Mixed_Group_Result;Test_Synthetic_Blood(Mixed_Group_Result, Blured_Mixed_Group_Result, fnr);All_Test_Times Mixed_Group_Result.size();//寻找检测结果为阳性的Mfor (int j 0; j Blured_Mixed_Group_Result.size() - 1; j){if (Blured_Mixed_Group_Result[j] 1){if (!Positive_Group.empty() Positive_Group.back() j){Positive_Group.emplace_back(j 1);}else{Positive_Group.emplace_back(j);Positive_Group.emplace_back(j 1);}}}//对每个可能阳性的Group进行核酸检测cout 保守测试可能为阳性的Group个数 Positive_Group.size() endl;for (int i 0; i Positive_Group.size(); i){int pos_index Positive_Group[i];//对可能阳性Group中每个样本都进行检测要考虑到假阴性的影响得到阳性的样本的序号。vectorint Blured_Splited_GroupResult;Test_Synthetic_Blood(splited_group[pos_index], Blured_Splited_GroupResult, fnr);//对检测结果进行记录记录下在原序列中的坐标for (int j 0; j Blured_Splited_GroupResult.size(); j){if (Blured_Splited_GroupResult[j] 1){PositiveSamples.emplace_back(pos_index * splited_group[0].size() j);}}}All_Test_Times Positive_Group.size() * splited_group[0].size();return All_Test_Times;}二次重复测试与自适应二次重复测试
/*
* 重复二次测量
* 输入result实际感染情况blured_result第一次检测情况rep_blured_result第二次检测情况
* 输出
*/
void Replicate_Test(vectorint result, vectorint blured_result, vectorint rep_blured_result, float fnr)
{rep_blured_result.clear();srand((unsigned)time(NULL));int fnr_100 fnr * 100;for (int i 0; i result.size(); i) //第二次全覆盖测试{//对每个阳性样本进行混淆处理if (result[i] 1){int num rand() % 100;// r % 概率检测为阴性if (num fnr_100){rep_blured_result.emplace_back(0);}//1-fnr%概率检测为阳性else{rep_blured_result.emplace_back(1);}}//由于covid-19不存在假阳性这里对阴性样本不做处理else{rep_blured_result.emplace_back(0);}}for (int i 0; i result.size(); i) { //将第一第二次的检测结果合并if (blured_result[i] 1) {rep_blured_result[i] 1;}}return;
}
/*
* 自适应重复二次测量对象为第一次测量中为阴性的组
* 输入result实际感染情况blured_result第一次检测情况rep_blured_result第二次检测情况
* 输出二次测量的测量数
*/
int Adt_Replicate_Test(vectorint result, vectorint blured_result, vectorint rep_blured_result, float fnr) {rep_blured_result.clear();srand((unsigned)time(NULL));int fnr_100 fnr * 100;int Test_Times 0;for (int i 0; i blured_result.size(); i){//对第一次检测结果再进行挑选检测if (blured_result[i] 1) //第一次检测为阳性跳过检测{rep_blured_result.emplace_back(1);}else //第一次检测为阴性再次检测{Test_Times;if (result[i] 1) {int num rand() % 100;// r % 概率检测为阴性if (num fnr_100){rep_blured_result.emplace_back(0);}//1-fnr%概率检测为阳性else{rep_blured_result.emplace_back(1);}}else rep_blured_result.emplace_back(0);}}return Test_Times;
}/*
* 重复二次测量
* 输入splited_group分组result实际感染情况fnr假阴率Positive_Group二次测量后的阳性组PositiveSamples二次测量后的阳性样本Mode方法模式0为重复二次测量1为自适应重复二次测量
* 输出
*/
int Replicate_TestDetection(vectorvectorint splited_group, vectorint result, float fnr, vectorint Positive_Group, vectorint PositiveSamples,int Mode)
{//将Gi、Gi1混合到一起为Mi//如果M检测结果是阳性则认定是Gj,Gj1是阳性。int All_Test_Times 0;//【step1】将G血液结果两两混合到M中vectorint Mixed_Group_Result;for (int i 0; i result.size() - 1; i){if (result[i] 1 || result[i 1] 1)Mixed_Group_Result.emplace_back(1);elseMixed_Group_Result.emplace_back(0);}//第一个样本与最后一个样本混合if (result[0] 1 || result[result.size() - 1] 1) Mixed_Group_Result.emplace_back(1);else Mixed_Group_Result.emplace_back(0);vectorint Blured_Mixed_Group_Result;//第一次检测Test_Synthetic_Blood(Mixed_Group_Result, Blured_Mixed_Group_Result, fnr);All_Test_Times Mixed_Group_Result.size();vectorint Sec_Blured_Mixed_Group_Result;if (Mode 0){//第二次检测采用重复二次测量Replicate_Test(result, Blured_Mixed_Group_Result, Sec_Blured_Mixed_Group_Result, fnr);All_Test_Times Blured_Mixed_Group_Result.size();}else{//第二次检测采用自适应重复二次测量对象为第一次测量中为阴性的组int Sec_Test_Times Adt_Replicate_Test(result, Blured_Mixed_Group_Result, Sec_Blured_Mixed_Group_Result, fnr);All_Test_Times Sec_Test_Times;}//记录二次结果后的阳性组for (int i 0; i Sec_Blured_Mixed_Group_Result.size(); i){if (Sec_Blured_Mixed_Group_Result[i] 1) Positive_Group.emplace_back(i);}//对每个可能阳性的Group进行核酸检测cout 二次重复测试可能为阳性的Group个数 Positive_Group.size() endl;for (int i 0; i Positive_Group.size(); i){int pos_index Positive_Group[i];//对可能阳性Group中每个样本都进行检测要考虑到假阴性的影响得到阳性的样本的序号。vectorint Blured_Splited_GroupResult;Test_Synthetic_Blood(splited_group[pos_index], Blured_Splited_GroupResult, fnr);//对检测结果进行记录记录下在原序列中的坐标for (int j 0; j Blured_Splited_GroupResult.size(); j){if (Blured_Splited_GroupResult[j] 1){PositiveSamples.emplace_back(pos_index * splited_group[0].size() j);}}}All_Test_Times Positive_Group.size() * splited_group[0].size();return All_Test_Times;
}测试代码 //检测总人数int sample_nums 175000;//流行率设定double p 0.04;//分组设定int sec_group_sample_nums 2;//假阴率设定float FNR 0.2;int positive_sample_nums p * sample_nums;if (sample_nums 0){cout error1 endl;return 0;}sec_group_sample_nums pow(2, i 1);vectorint Group(sample_nums, 0);//混合血液后的真实结果vectorint Result;//受到假阴性影响后的混合血液测试结果vectorint Blured_Result;vectorvectorint Splited_Group;//【1】初始化样本序列Initial_Group(Group, positive_sample_nums);//Pirnt_Group(Group);cout endl;//【2】Pooling操作Split_Group(Group, Splited_Group, sec_group_sample_nums);//Pirnt_Split_Group(Splited_Group);cout endl;//【3】混合血液Synthetic_Blood(Splited_Group, Result);vectorint Positive_Group;vectorint PositiveSamples;int All_Test_Times 0;int Methods 3;//【4】使用不同的测试方法switch (Methods){//【0】保守群组测试case 0:{All_Test_Times Conservative_Group_Detection(Splited_Group, Result, FNR, Positive_Group, PositiveSamples);cout 重复性测试总检测次数 All_Test_Times endl;if (positive_sample_nums ! 0)cout 检测出的阳性样本个数为 PositiveSamples.size() 准确率 PositiveSamples.size() * 1.0f / positive_sample_nums endl;elsecout error2 endl;}break;//【1】非保守群组测试case 1:{All_Test_Times No_Conservative_Group_Detection(Splited_Group, Result, FNR, Positive_Group, PositiveSamples);cout 非重复性测试总检测次数 All_Test_Times endl;if (positive_sample_nums ! 0)cout 检测出的阳性样本个数为 PositiveSamples.size() 准确率 PositiveSamples.size() * 1.0f / positive_sample_nums endl;elsecout error2 endl;}break;//【2】二次重复测试case 2:{All_Test_Times Replicate_TestDetection(Splited_Group, Result, FNR, Positive_Group, PositiveSamples, 0);cout 重复性测试总检测次数 All_Test_Times endl;cout 阳性样本组数 Positive_Group.size() endl;if (positive_sample_nums ! 0)cout 检测出的阳性样本个数为 PositiveSamples.size() 准确率 PositiveSamples.size() * 1.0f / positive_sample_nums endl;elsecout error2 endl;}break;//【3】二次自适应重复测试case 3:{All_Test_Times Replicate_TestDetection(Splited_Group, Result, FNR, Positive_Group, PositiveSamples, 1);cout 重复性测试总检测次数 All_Test_Times endl;if (positive_sample_nums ! 0)cout 检测出的阳性样本个数为 PositiveSamples.size() 准确率 PositiveSamples.size() * 1.0f / positive_sample_nums endl;elsecout error2 endl;}break;default:break;}//根据仿真得出一个测试实际社会成本即找出最后为阴性的组数/总组数*每组多少人*每个人的闲置成本int Neg_Groups Splited_Group.size() - Positive_Group.size();double Neg_rate Neg_Groups * 1.0f / Splited_Group.size();cout Neg_rate Neg_rate endl;cout 总样本个数 Splited_Group.size() endl;参考文献
https://www.medrxiv.org/content/10.1101/2020.07.31.20154070v1