抽奖骗局代码实现

在mooc看概率统计教学视频的时候看到了一个课后思考题:抽奖骗局,总觉得这个能行,于是把它用代码实现了出来。
在这里插入图片描述

一开始我准备使用cuda在设备端上并行模拟抽奖来快速实现这个题目,但可惜设备端上不能使用随机函数,于是我只能放弃,后面如果我能实现并行的话会在后面更新的。

目前实现代码的思路:在这里插入图片描述

实现后的代码:

#include <windows.h>
#include <stdio.h>
#include<stdlib.h>
#define size 10000//抽奖的次数
#define A 10
#define B 5

int main() {
    int b[11][2] = { {50,0},{55,0},{60,0},{65,0},{70,0},{75,0},{80,0},{85,0},{90,0},{95,0},{100,0}};
    int a[size][21];
    DWORD seed = GetTickCount64();
    srand(seed);
    for (int i = 0; i < size; i++) {

        
        int A_num = 10;
        int B_num = 10;
        for (int j = 0; j < 20; j++) {
            if (rand(seed) % 2 == 0)
            {
                A_num--;
                if(A_num>=0)
                    a[i][j] = A;
                else
                {
                    a[i][j] = B;
                }
            }
            else
            {
                B_num--;
                if (B_num >= 0)
                    a[i][j] = B;
                else
                {
                    a[i][j] = A;
                }
            
            }
            a[i][20] = 0;
        }
    }


    //for (int i = 0; i < size; i++) {
    //    for (int j = 0; j < 20; j++) {
    //        printf("%d ",a[i][j]);
    //    }
    //    printf("\n");
    //}
    DWORD seed2 = GetTickCount64();
    srand(seed2);
    for (int i = 0; i < size; i++) {
        int flag = 20;
        for (int j = 0; j < 10; j++) {
            int n=(rand() % flag);//随机出来的数.
           // printf("%d ", n);
            a[i][20] += a[i][n];
            flag--;
            for (int x = n; x < 20; x++) {
                a[i][x] = a[i][x + 1];
            }
        }
        //printf("%d \n", a[i][20]);
        for (int j = 0; j < 10; j++) {
            if (a[i][20] == b[j][0])
            {
                b[j][1]++;
            }
        }
    }
    for (int j = 0; j < 10; j++) {
        printf("抽奖结果是%d的次数是:%d\n", b[j][0], b[j][1]);
    }


    return 0;
}

用10000次模拟抽奖的结果如下:在这里插入图片描述

脸特别黑,模拟了好几十次只抽中过一次50分的情况,所以是天上不会掉馅饼滴!

3月9日 更新了并行化的计算结果,并行优化效果并不明显,而且计算结果和串行比较起来明显是错误的

#include <windows.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include<stdlib.h>
#include <stdio.h>
#include<time.h>
//guesss what am I doing now,is any sense of it?
//*cought
//this game living is will be much fun to me:)
#define A 10
#define B 5
#define size 12000

struct Balls {
    int score[20];//球上面的分值
    int result;
    int number[20];//在host端计算好10个随机数,在设备端直接使用
                    //为了保证概率,随机数每次最大值为20,19,18……;
};
__global__ void draw(Balls* p, int* b) {

    int tid = threadIdx.x + blockDim.x * blockIdx.x;
  //  printf("blockDim.x=%d blockIdx.x=%d threadIdx.x=%d\n", blockDim.x, blockIdx.x, threadIdx.x);

    for (int i = 0; i < 10; i++) {
        p[tid].result += p[tid].score[p[tid].number[i]];
        for (int x = p[tid].number[i]; x < 20; x++) {
            p[i].score[x] = p[i].score[x + 1];
        }
    }
   //  printf("%d ", p[tid].result);
    for (int j = 0; j < 11; j++)
    {
        if (b[j] == p[tid].result)
            atomicAdd(&b[j + 11], 1);

    }

}
int chuanxing() {

    int b[11][2] = { {50,0},{55,0},{60,0},{65,0},{70,0},{75,0},{80,0},{85,0},{90,0},{95,0},{100,0} };
    int a[size][21];
    DWORD seed = GetTickCount64();
    srand(seed);
    for (int i = 0; i < size; i++) {


        int A_num = 10;
        int B_num = 10;
        for (int j = 0; j < 20; j++) {
            if (rand() % 2 == 0)
            {
                A_num--;
                if (A_num >= 0)
                    a[i][j] = A;
                else
                {
                    a[i][j] = B;
                }
            }
            else
            {
                B_num--;
                if (B_num >= 0)
                    a[i][j] = B;
                else
                {
                    a[i][j] = A;
                }

            }
            a[i][20] = 0;
        }
    }


    //for (int i = 0; i < size; i++) {
    //    for (int j = 0; j < 20; j++) {
    //        printf("%d ",a[i][j]);
    //    }
    //    printf("\n");
    //}
    DWORD seed2 = GetTickCount64();
    srand(seed2);
    for (int i = 0; i < size; i++) {
        int flag = 20;
        for (int j = 0; j < 10; j++) {
            int n = (rand() % flag);//随机出来的数.
           // printf("%d ", n);
           // printf("%d \n", a[i][n]);
            a[i][20] += a[i][n];
            flag--;
            for (int x = n; x < 20; x++) {
                a[i][x] = a[i][x + 1];
            }
        }
        //printf("%d \n", a[i][20]);
        for (int j = 0; j < 10; j++) {
            if (a[i][20] == b[j][0])
            {
                b[j][1]++;
            }
        }
    }
    for (int j = 0; j < 10; j++) {
        printf("抽奖结果是%d的次数是:%d\n", b[j][0], b[j][1]);
    }


    return 0;
}
int bingxing() {
    cudaEvent_t stop, start;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    float elapsedTime = 0;
    cudaEventRecord(start, 0);

    Balls* p = (Balls*)malloc(sizeof(Balls) * size);
    //格式:
    //p[0].score[0] = 0;

    DWORD seed = GetTickCount64();
    srand(seed);
    for (int i = 0; i < size; i++) {


        int A_num = 10;
        int B_num = 10;
        int flag = 20;
        for (int j = 0; j < 20; j++) {
            int n = (rand() % flag);//随机出来的数.
        //    printf("%d ", n);
            flag--;
            p[i].number[j] = n;
            if (rand() % 2 == 0)
            {
                A_num--;
                if (A_num >= 0)
                    p[i].score[j] = A;
                else
                {
                    p[i].score[j] = B;
                }
            }
            else
            {
                B_num--;
                if (B_num >= 0)
                    p[i].score[j] = B;
                else
                {
                    p[i].score[j] = A;
                }

            }

        }
        p[i].result = 0;

        //   printf("\n");
    }
    int  block_num = 1024;
    int grid_num =  (size + block_num - 1) / block_num;
   // printf("%d", grid_num);
    int* b;
    b = (int*)malloc(sizeof(int) * 25);
    for (int i = 0; i < 11; i++) {
        b[i] = 50 + i * 5;
        b[i + 11] = 0;
    }
    Balls* d_p;
    int* d_b;
    cudaMalloc((void**)&d_b, sizeof(int) * 25);
    cudaMemcpy(d_b, b, sizeof(int) * 25, cudaMemcpyHostToDevice);
    cudaMalloc((Balls**)&d_p, sizeof(Balls) * size);
    cudaMemcpy(d_p, p, sizeof(Balls) * size, cudaMemcpyHostToDevice);


    //grid_num必须要大于block!!!
    draw << <grid_num, block_num,0 >> > (d_p, d_b);

    cudaDeviceSynchronize();
    cudaMemcpy(p, d_p, sizeof(Balls) * size, cudaMemcpyDeviceToHost);
    cudaMemcpy(b, d_b, sizeof(int) * 25, cudaMemcpyDeviceToHost);
    for (int j = 0; j < 11; j++) {
        printf("抽奖结果是%d的次数是:%d\n", b[j], b[j + 11]);
    }
    cudaFree(d_b);
    cudaFree(d_p);



    cudaEventRecord(stop, 0);
    cudaEventSynchronize(stop);
    cudaEventElapsedTime(&elapsedTime, start, stop);
   // printf("串行使用的时间是:%lf\n", elapsedTime);
    return 0;
}



void main() {
    time_t t_start, t_end;
    t_start = time(NULL);
    chuanxing();
    t_end = time(NULL);
    printf("串行时间是: %.0f s\n", difftime(t_end, t_start));

    time_t t_start2, t_end2;
    t_start2 = time(NULL);
    bingxing();
    t_end2 = time(NULL);
    printf("并行时间是: %.0f s\n", difftime(t_end2, t_start2));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值