流行病毒传染模拟仿真实验

编程入门 行业动态 更新时间:2024-10-10 10:27:19

流行病毒传染模拟仿真实验

流行病毒传染模拟仿真实验

流行病毒传染模拟仿真实验

共有三个java文件,请根据注释提醒,补充程序并完成仿真实验。

Epidemic.java(主类)

/*** Main class for simulating an epidemic. The simulation consists of a "world"* (a square matrix of cells, or ints). Each cell can be empty or contains an* individual. The state of a cell is denoted by its integer value in the array.* The value {@code Config.EMPTY} (which is 0) indicates an empty cell.* Each individual can be in one of the following states:* <ul>*   <li><b>Uninfected</b>. This individual has never been infected with the*     disease. This is indicated by the value {@code Config.UNINFECTED},*     which is -1.*   <li><b>Recovered</b>. This individual was infected with the disease but is*     no longer infected. This is indicated by the value*     {@code Config.RECOVERED}, which is. Once recovered, an individual can*     never again become infected.*   <li><b>Infected</b>. This individual currently has the disease. This is*     indicated by an integer value greater than 1. The higher this value,*     the longer the period will be before this individual switches to the*     RECOVERED state. If the value is less than or equal to*     {@code Config.CONTAGIOUS}, the individual is contagious and can*     spread their disease to others.* </ul>* * <p><b>Remember to use the constants from the {@code Config} class* directly. DO NOT hard-code constant values from the Config class.</b> You* will lose points if you do this.*/
public class Epidemic {//// A NOTE ON USING THIS SKELETON.// We have provided many comments below to outline how your program// should work. We do not, however, provide a comment describing// every piece of code you will have to write. You may find that you// need to add additional code to fully support the functionality// required by the comments.///*** Application entry point. Runs an epidemic simulation to completion,* displaying the results after each step using a {@code WorldViewer}* object. Each step in the simulation consists of the following sub-steps:* <ol>*   <li>Move individuals around in the world.*   <li>Decrement infected individuals to represent the passage of time.*   <li>Spread disease from contagious to uninfected individuals.* </ol>* * <p>At the end of each simulation step (that is, after each spread-disease* substep), you should display the current simulation state by calling* {@code Config.VIEWER.showWorld()} and passing the correct arguments.* This will update the picture displayed on the window.* * <p>The simulation is complete once there are no more infected* individuals.* * @param args Command-line arguments (ignored).*/public static void main(String[] args) {// TODO// Create a world as a 2-D array of ints. Use Config.WORLD_SIZE as// the width and height of the world. The cells in the array will// default to 0, which equals Config.EMPTY.// Call the populateWorld method to populate the world with individuals.// You may want to declare some variables to keep track of the// simulation state. This will help you determine when the simulation is// complete.// Loop until there are no more infected individuals in the world.// Call the move method to move individuals around in the world.// Call the decrement method to advance the state of all infected// individuals in the world.// Call the spreadDisease method to spread disease from contagious// to uninfected individuals.// Update the viewer by calling Config.VIEWER.showWorld() and// passing the appropriate information as arguments.}/*** Populates the given world with uninfected and infected individuals, as* specified by {@code Config.INITIAL_UNINFECTED_COUNT} and* {@code Config.INITIAL_INFECTED_COUNT}.* * @param world World to populate.*/public static void populateWorld(int[][] world) {//world = new int [89][89]; //INITIAL_UNINFECTED_COUNT {@code Config.INITIAL_UNINFECTED_COUNT}//{@code Config.INITIAL_INFECTED_COUNT}// TODO// Populate the world with the correct number// (Config.INITIAL_UNINFECTED_COUNT) of uninfected individuals. Use// a loop to call the addIndividual method repeatedly to do this. The// addIndividual method should be used to add each individual to the// world.// Populate world with the correct number// (Config.INITIAL_INFECTED_COUNT) of infected individuals. Again,// use a loop to repeatedly call the addInviddual method.}/*** Adds an individual to the simulation world. This should be done by* randomly selecting an EMPTY cell in the world. That cell's value should* then be changed to the specified {@code newIndividual} value.* * @param world World to add an individual to.* @param newIndividual The new value to put into the randomly selected*        cell.*/public static void addIndividual(int[][] world, int newIndividual) {// TODO}/*** Randomly moves individuals around in the world. This should be done by* randomly selecting pairs of adjacent cells in the array. Each such pair* should then have their values swapped. The number of pairs swapped should* equal half the number of cells in the world.* * @param world The world array.*/public static void move(int[][] world) {// TODO// Repeatedly call the swapRandomIndividuals method. The number of times// you call it should be equal to half (round down) of the total number// of cells in the world.}/*** Randomly swaps two adjacent individuals.* * @param world The world array.*/public static void swapRandomIndividuals(int[][] world) {// TODO// Pick a random cell in the world.// Randomly pick one of the eight cells adjacent to this one. That is,// if X was the cell picked earlier, randomly pick one of the A's from// the diagram below://     A A A//     A X A//     A A A// Swap the values contained by the two selected cells.}/*** Advances the disease state of all infected individuals. If an individual* is infected, his or her state should be decremented by 1 to show the* advancement of the disease towards the RECOVERED state. Individuals who* are not infected should not be affected by the decrement method.* * @param world The world array.*/public static void decrement(int[][] world) {// TODO}/*** Spreads disease from contagious individuals to adjacent UNINFECTED* individuals. For each pair of adjacent individuals, if one of them is* contagious and the other is UNINFECTED, then there is a fixed chance* ({@code Config.INFECTION_PROBABILITY}) that the UNINFECTED individual* will become contagious.* * @param world The world array.*/public static void spreadDisease(int[][] world) {// TODO// Loop over all the cells in the world.// If the cell does not contain a contagious individual (note// that it could be EMPTY), do nothing.// If the cell does contain a contagious individual, loop over// all eight cells that are adjacent to this contagious// individual. In this loop, you should check each adjacent cell// to see if it is UNINFECTED. If it is, that cell should have a// change (Config.INFECTION_PROBABILITY) of becoming// infected right now. To mark the cell as infected, set its// value to Config.INFECTED.}/*** Wraps a world coordinate around. Using this on all coordinates means that* our world has no boundaries--individuals and infections simply wrap* around from top to bottom and from left to right. This is sometimes* called a "toroidal world". See* <a href="">Wikipedia</a>.* * <p>You should call this method on any index <b>before</b> you use it to* index into the world array. That way, even cells on the edges of the* array will be considered to have eight adjacent cells. For example,* consider the cell marked "X" below:* <pre>*     A * A A*     A * A X*     A * A A*     * * * *</pre>* The cell "X" is adjacent to the eight cells marked "A" because the world* wraps around at the edges.* * @param size Size of the world.* @param coord Coordinate to be wrapped.* @return The wrapped version of the coordinate.*/public static int wrap(int size, int coord) {// What you want to do here is take an input coord that is potentially// outside the bounds of the world array and wrap it around so it falls// within the bounds of the array. There are two ways that the coord can// be outside the bounds of the world array://   (1) it can be greater than or equal to size//   (2) it can be less than or equal to -1// In the first case, we want to subtract the size from the coord to// bring it within the legal range. In the second case, we want to add// the size to the coord to bring it within the legal range. You can do// this with loops and if statements, or you can do it much more// elegantly using the modulus operator (%), which takes the remainder// of its first argument after integer division by its second argument.return 0; // TODO}}

2. WorldViewer.java

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.Arrays;
import java.util.concurrent.locks.*;import javax.swing.*;/*** Provides a graphical user interface (GUI) for displaying a world in the* epidemic simulation. The world is displayed* as a grid of cells. Empty cells will show up as empty (black) in the grid.* Uninfected individuals appear as small blue dots, infected individuals appear* as large red dots, and recovered individuals appear as small pink dots.* The viewer does not distinguish between contagious and non-contagious* infected individuals; that is, it displays all infected individuals as large* red dots.* * <p>The viewer also shows the integer values passed to its {@link #showWorld}* method:* <ol>* <li>The number of simulation steps executed so far.* <li>The current count of uninfected individuals.* <li>The current count of infected individuals.* <li>The current count of recovered individuals.* </ol></p>* * <p><b>DO NOT EDIT THIS FILE.</b> You should put all your code for this* assighnment in Epidemic.java.</p>* * @author pollen*/
public class WorldViewer {private Snapshot current, previous, next;private final JFrame frame;private final JButton stepForwardButton;private final JButton stepBackButton;private final JLabel stepsLabel;private final JLabel uninfectedLabel;private final JLabel infectedLabel;private final JLabel recoveredLabel;/** Number of milliseconds to pause after each showWorld call. */private final int frameDuration;private final boolean enable;private final Lock lock = new ReentrantLock();private final Condition cond = lock.newCondition();/*** Creates a new WorldViewer for use in students' code. The window will not* be shown until the showWorld method is called at least once.*/public WorldViewer() {this(40, true);}/*** Creates a new WorldViewer. The window will not be shown until the* showWorld method is called at least once.* * <p><b>Students' code should not call this constructor. It is for testing* purposes only.</b>* * @param frameDuration Number of milliseconds to pause after showing each* frame.*/public WorldViewer(int frameDuration, boolean enable) {this.frameDuration = frameDuration;this.enable = enable;frame = new JFrame();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setTitle("Epidemic Simulation");frame.setSize(800, 600);frame.setLocation(100, 100);JPanel pane = new JPanel();pane.setLayout(new BorderLayout());frame.setContentPane(pane);pane.add(new WorldPane(), BorderLayout.CENTER);JPanel status = new JPanel();status.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));status.setLayout(new GridLayout(1, 6));pane.add(status, BorderLayout.SOUTH);stepBackButton = new JButton("<< Step");stepBackButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {stepBack();}});stepBackButton.setEnabled(false);status.add(stepBackButton);stepForwardButton = new JButton("Step >>");stepForwardButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent arg0) {stepForward();}});stepForwardButton.setEnabled(false);status.add(stepForwardButton);stepsLabel = new JLabel();status.add(stepsLabel);uninfectedLabel = new JLabel();status.add(uninfectedLabel);infectedLabel = new JLabel();status.add(infectedLabel);recoveredLabel = new JLabel();status.add(recoveredLabel);}private void stepForward() {if (next != null) {showWorld(next, true, true);} else {runSimulation();}}private void stepBack() {showWorld(previous, true, false);}/** Wakens the sleeping simulation to run another step. */private void runSimulation() {lock.lock();try {cond.signalAll();} finally {lock.unlock();}}/** Pauses the simulation. */private void pauseSimulation(boolean await) {if (await) {lock.lock();try {cond.await();} catch (InterruptedException e) {// Empty.} finally {lock.unlock();}} else {try {Thread.sleep(frameDuration);} catch (InterruptedException e) {// Empty.}}}/*** Displays the current state of the simulated world on the GUI window.* * @param world Matrix of tiles that make up the world.* @param stepsTaken Number of steps that have been taken so far in this*        simulation.* @param numUninfected Current number of uninfected individuals in the*        simulation.* @param numInfected Current number of infected individuals in the*        simulation.* @param numRecovered Current number of recovered individuals in the*        simulation.* @param pause True to pause the simulation until the user hits the "Step"*        button. False to keep running without requiring the user to hit*        the "Step" button. Feel free to pass either {@code true} or {@code*        false} here. The <a href=*        ".html">*        example video</a> was generated with {@code pause} set to {@code*        false}.*/public void showWorld(int[][] world,int stepsTaken,int numUninfected,int numInfected,int numRecovered,boolean pause) {showWorld(new Snapshot(world,stepsTaken,numUninfected,numInfected,numRecovered),pause, true);pauseSimulation(pause);}private void showWorld(Snapshot newSnapshot,boolean await,boolean forward) {if (forward) {previous = current;next = null;} else {previous = null;next = current;}current = newSnapshot;stepForwardButton.setEnabled(next != null || await);stepBackButton.setEnabled(previous != null && await);update();}/** Updates the painted display based on the current Snapshot. */private void update() {if (enable) {stepsLabel.setText(String.format("  Steps: %d", current.stepsTaken));uninfectedLabel.setText(String.format("  Uninfected: %d", current.numUninfected));infectedLabel.setText(String.format("  Infected: %d", current.numInfected));recoveredLabel.setText(String.format("  Recovered: %d", current.numRecovered));frame.setVisible(true); // Make sure the window is shown.frame.repaint();}}/*** Prints a representation of the current state of the world to System.out.* While your program is not required to ever call this method, you may find* it useful for debugging purposes.* <ul>* <li>Empty cells are represented by a space.* <li>Uninfected cells are represented by a period (.).* <li>Recovered cells are represented by a star (*).* <li>Infected cells are represented by an at-sign (@).* </ul>* * @param world World array to print.*/public static void printWorld(int[][] world) {for (int i = 0; i < world.length; i++) {for (int j = 0; j < world[i].length; j++) {char c;switch (world[i][j]) {case Config.EMPTY:c = ' ';break;case Config.UNINFECTED:c = '.';break;case Config.RECOVERED:c = '*';break;default:c = '@';break;}System.out.print(c + " ");}System.out.println();}}/*** Gets the current number of uninfected individuals, based on the values* that were passed into {@code showWorld}.* * <p><b>Students' code should not call this method. It is for testing* purposes only.</b>*/public int getUninfectedCount() {return current == null ? 0 : current.numUninfected;}/*** Gets the current number of infected individuals, based on the values that* were passed into {@code showWorld}.* * <p><b>Students' code should not call this method. It is for testing* purposes only.</b>*/public int getInfectedCount() {return current == null ? 0 : current.numInfected;}/*** Gets the current number of recovered individuals, based on the values* that were passed into {@code showWorld}.* * <p><b>Students' code should not call this method. It is for testing* purposes only.</b>*/public int getRecoveredCount() {return current == null ? 0 : current.numRecovered;}/*** Gets the number of simulation steps executed so far, based on the values* that were passed into {@code showWorld}.* * <p><b>Students' code should not call this method. It is for testing* purposes only.</b>*/public int getStepCount() {return current == null ? 0 : current.stepsTaken;}/** JPanel for painting a World on the screen. */private class WorldPane extends JPanel {private static final long serialVersionUID = 1L;public WorldPane() {setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));}@Overridepublic void paint(Graphics graphics) {int[][] world = current.world;Graphics2D g = (Graphics2D) graphics;final Insets insets = getInsets();final int width = getWidth();final int height = getHeight();g.setColor(Color.BLACK);g.fillRect(0, 0, width, height);if (world == null) {// Leave a blank screen.} else {// Paint each tile in the proper location.int size = world.length;double tileWidth = Math.min(width - insets.left - insets.right,height - insets.top - insets.bottom) / (double) size;// First paint blue and pink individuals (and gray walls, for// the extra credit portion of the assignment) at a normal size.for (int row = 0; row < size; row++) {for (int col = 0; col < size; col++) {int tile = world[row][col];if (tile == Config.EMPTY) {// Paint nothing.} else if (tile == Config.WALL) {// Paint a gray square.g.setColor(Color.GRAY);g.fill(new Rectangle2D.Double(col * tileWidth + insets.left,row * tileWidth + insets.top,tileWidth, tileWidth));} else {// Choose a color based on the individual's status.if (tile == Config.UNINFECTED) {g.setColor(Color.CYAN);} else if (tile == Config.RECOVERED) {g.setColor(Color.PINK);} else { // Infected.continue;}// Paint a circle to represent the individual.g.fill(new Ellipse2D.Double((col + 0.1) * tileWidth + insets.left,(row + 0.1) * tileWidth + insets.top,tileWidth * 0.8, tileWidth * 0.8));}}}// Now paint red individuals at a larger size.for (int row = 0; row < size; row++) {for (int col = 0; col < size; col++) {int tile = world[row][col];if (tile == Config.EMPTY) {// Paint nothing.} else {// Choose a color based on the individual's status.if (tile == Config.UNINFECTED) {continue;} else if (tile == Config.RECOVERED) {continue;} else if (tile == Config.WALL){continue;} else { // Infected.g.setColor(Color.RED);}// Paint a circle to represent the individual.g.fill(new Ellipse2D.Double((col - 0.3) * tileWidth + insets.left,(row - 0.3) * tileWidth + insets.top,tileWidth * 1.6, tileWidth * 1.6));}}}}}}private static class Snapshot {public final int[][] world;public final int stepsTaken;public final int numUninfected;public final int numInfected;public final int numRecovered;public Snapshot(int[][] world,int stepsTaken,int numUninfected,int numInfected,int numRecovered) {this.stepsTaken = stepsTaken;this.numUninfected = numUninfected;this.numInfected = numInfected;this.numRecovered = numRecovered;this.world = copy(world);}/** Creates a copy of a world. */private static int[][] copy(int[][] world) {int[][] copy = new int[world.length][];for (int i = 0; i < world.length; i++) {copy[i] = Arrays.copyOf(world[i], world[i].length);}return copy;}}}

3. Config.java

import java.util.Random;/*** Defines constant simulation configuration values. You should refer to these* constants in your program. Do not put these magic numbers directly into your* program's code. Instead, access them like this: {@code Config.RANDOM},* {@code Config.INFECTED}, etc.* * <p><b>DO NOT ADD, REMOVE, OR RENAME VARIABLES IN THIS FILE.</b> You may* change values in order to test your program for different configuration* values.</p>* * @author pollen*/
public class Config {private Config() {// This private constructor prevents anyone from ever creating an// instance of this class.}/*** Random number generator to use for simulation. You may also create your* own Random objects; we just provide this one for your convenience. In* your Epidemic class, you may access it by typing {@code* Config.RANDOM}.*/public static final Random RANDOM = new Random();/*** WorldViewer object to use for showing simulation results to the user in* a GUI (Graphical User Interface) window. Do not create additional* WorldViewer objects, as doing so will break our grading system. Use this* WorldViewer object for displaying all stages of the simulation.*/public static final WorldViewer VIEWER = new WorldViewer();/** Value to represent an empty tile in the world. */public static final int EMPTY = 0;/** Value to represent an uninfected individual in the world. */public static final int UNINFECTED = -1;/*** Value representing a wall in the world. <b>This is only used for the* extra credit portion of the assignment.</b> If you aren't doing extra* credit, then you should ignore this constant.*/public static final int WALL = -2;/*** Value to represent an individual who has recovered from being infected.*/public static final int RECOVERED = 1;/** Value to represent an individual who has just become infected. */public static final int INFECTED = 9;/*** Value to represent an individual who is infected and contagious. Any* value less than or equal to CONTAGIOUS and greater than RECOVERED is* considered a contagious individual.*/public static final int CONTAGIOUS = 7;/*** Probability that infection is passed between any two adjacent* individuals.*/public static final double INFECTION_PROBABILITY = 0.06;/*** Probability that an infected individual dies during any simulation step.* <b>This is only used for the extra credit portion of the assignment.</b>* If you aren't doing extra credit, then you should ignore this constant.*/public static final double DEATH_PROBABILITY = 0.05;/** Width and height of the world, in cells. */public static final int WORLD_SIZE = 90;/** Initial count of uninfected individuals in the simulation. */public static final int INITIAL_UNINFECTED_COUNT =(int)(WORLD_SIZE * WORLD_SIZE * 0.8);/** Initial count of infected individuals in the simulation. */public static final int INITIAL_INFECTED_COUNT = 5;/*** Height of walls to create in the world. <b>This is only used for the* extra credit portion of the assignment.</b> If you aren't doing extra* credit, then you should ignore this constant.*/public static final int WALL_HEIGHT = (int)(WORLD_SIZE * 0.80);/*** Horizontal spacing of walls to create in the world. <b>This is only used* for the extra credit portion of the assignment.</b> If you aren't doing* extra credit, then you should ignore this constant.*/public static final int WALL_SPACING = 8;}

转载于:.html

更多推荐

流行病毒传染模拟仿真实验

本文发布于:2024-02-13 07:21:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1757526.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:流行病毒

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!