You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

计算机病毒传播模拟:如何让每次试验输出随机化?

病毒传播模拟代码问题排查与修复

问题根源分析

所有试验输出完全相同的问题,核心来自三类逻辑错误:

  • 清除时间固定为2天:t++被放在while循环外部,无论循环执行多少次,最终t只会是初始值1+1=2;感染数更新逻辑错误,直接用新增感染数覆盖原有感染数,完全不符合传播规律;清除操作只是单纯减数字,没有实际跟踪感染状态,随机性无效。
  • 后两个结果无随机性:原代码调用的calculateProbAnyComputerInfected和calculateExpectedInfectedComputers是计算固定理论值的函数,输入参数不变,返回结果自然一致,和当前试验的随机过程无关。

修正后的代码

import java.util.Arrays;
import java.util.Random;

public class VirusSpreadSimulation {

    public static void main(String[] args) {
        int numTrials = 5;
        int numComputers = 20;
        double pSpread = 0.1;
        int numInitialInfected = 1;
        int numToRemove = 5;

        int[] timesToRemoveVirus = new int[numTrials];
        double[] probAnyComputerInfected = new double[numTrials];
        int[] actualInfectedCounts = new int[numTrials];

        for (int trial = 0; trial < numTrials; trial++) {
            Random random = new Random();
            // 跟踪每台计算机是否曾被感染过
            boolean[] everInfected = new boolean[numComputers];
            // 跟踪当前处于感染状态的计算机
            boolean[] currentlyInfected = new boolean[numComputers];
            // 初始化:随机选一台计算机作为初始感染源
            int initialIdx = random.nextInt(numComputers);
            currentlyInfected[initialIdx] = true;
            everInfected[initialIdx] = true;
            int numInfected = numInitialInfected;
            int t = 0;

            while (numInfected > 0) {
                t++; // 每循环一次代表过去一天,先更新天数
                int newInfections = 0;

                // 模拟病毒传播:当前感染的计算机尝试向未感染的机器传播
                for (int i = 0; i < numComputers; i++) {
                    if (currentlyInfected[i]) {
                        // 遍历所有未被感染的计算机
                        for (int j = 0; j < numComputers; j++) {
                            if (!currentlyInfected[j] && !everInfected[j]) {
                                if (random.nextDouble() < pSpread) {
                                    currentlyInfected[j] = true;
                                    everInfected[j] = true;
                                    newInfections++;
                                }
                            }
                        }
                    }
                }
                numInfected += newInfections;

                // 模拟清除操作:随机清除最多numToRemove台当前感染的计算机
                int removed = 0;
                while (removed < numToRemove && numInfected > 0) {
                    int randomIdx = random.nextInt(numComputers);
                    if (currentlyInfected[randomIdx]) {
                        currentlyInfected[randomIdx] = false;
                        numInfected--;
                        removed++;
                    }
                }
            }

            // 记录当前试验的实际结果
            timesToRemoveVirus[trial] = t;
            int everInfectedCount = (int) Arrays.stream(everInfected).filter(b -> b).count();
            probAnyComputerInfected[trial] = (double) everInfectedCount / numComputers;
            actualInfectedCounts[trial] = everInfectedCount;

            // 输出单试验结果
            System.out.println("第" + (trial + 1) + "次试验: ");
            System.out.println("清除病毒所需时间: " + timesToRemoveVirus[trial] + " 天");
            System.out.println("单台计算机至少被感染一次的概率: " + probAnyComputerInfected[trial]);
            System.out.println("实际感染过的计算机数量: " + actualInfectedCounts[trial]);
            System.out.println();
        }

        // 计算并输出所有试验的平均值
        double averageTime = Arrays.stream(timesToRemoveVirus).average().orElse(0);
        double averageProb = Arrays.stream(probAnyComputerInfected).average().orElse(0);
        double averageInfectedCount = Arrays.stream(actualInfectedCounts).average().orElse(0);

        System.out.println("试验次数: " + numTrials);
        System.out.println("平均清除时间: " + averageTime + " 天");
        System.out.println("平均单台感染概率: " + averageProb);
        System.out.println("平均感染计算机数量: " + averageInfectedCount);
    }
}

关键修改点说明

  1. 修复时间统计:把t++移到while循环内部,每次循环代表一天,正确统计清除病毒的实际天数。
  2. 精准跟踪感染状态:用currentlyInfected和everInfected两个数组分别记录当前感染和曾被感染的计算机,解决原代码中感染数更新逻辑混乱的问题。
  3. 真实模拟传播过程:遍历所有当前感染的计算机,每台尝试向未感染的机器传播,符合病毒传播的实际逻辑。
  4. 有效模拟清除操作:随机选择当前感染的计算机进行清除,直到达到清除数量上限或无感染机器,保证清除操作的随机性。
  5. 统计试验实际数据:不再依赖固定公式计算理论值,而是从当前试验的感染状态数组中统计实际结果,确保每次试验输出的随机性。

内容的提问来源于stack exchange,提问作者Amir Goziyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 17:44:51