📄 pdcelluar.java
字号:
package pdcelluar;import java.awt.*;import java.awt.event.*;import java.applet.*;import java.util.Vector;/** * Title:竞争与合作,动态囚徒困境博弈模拟程序 * Description:主程序 * Copyright: http://agents.yeah.net Copyright (c) 2003 * Company: * @author:jake * @version 1.0 */public class pdcelluar extends Applet implements Runnable{ boolean isStandalone = false; /**Get a parameter value*/ Thread runner;//独立运行线程 //窗口的尺寸,每个方格的大小,边沿的大小,运行延迟 int width1=350,height1=350,square,fringe, delay; static int refreshSteps=1;//刷新率,每隔几个时间步更新一次 static int max=35;//时间的尺寸 static double nonempty_p=0.8,coop_u=0.5,m_value=1.1;//企业比率,合作者的比例,博弈规则 int display_mode=0;//显示模式:0显示策略;1显示id;2显示运动方向 int grid[][], stepLeft;//网格数组,记载每个x,y坐标处的agent的id,stepLeft为单步运行的时候每按一次 //更新的代数 static int steps,cyclemax=2000;//该程序运行了多少步,cyclemax为记载历史数据的最大限度 static Agent[] ag;//agent数组 int AgCount;//agent的总数 Color StateColors[]={ Color.black,Color.blue,Color.red,Color.green, Color.yellow,Color.magenta,Color.white,Color.cyan,Color.orange};//颜色数组 Color idColors[];//id的总数很多,把颜色信息储存到这个数组中 Button pausebutton; boolean running, started=true;//标志程序是否在运行,started标志是否为第一次运行 int HistoryData[];//历史数据,主要记载每次更新的时候合作者的比例 Choice disp_choice; int vonNeuman[][]={{-1,0},{1,0},{0,-1},{0,1}};//vonNeuman的邻居类型 int Moore[][]={{-1,-1},{0,-1},{1,-1},{-1,0},{1,0},{-1,1},{0,1},{1,1}};//Moore的邻居类型 int GN[][]={{0,-2},{-1,-1},{0,-1},{1,-1},{-2,0},{-1,0},{1,0},{2,0},{-1,1},{0,1},{1,1},{0,2}};//GN邻居类型 int Neighbor[][];//邻居数组,根据不同的邻居类型定义该数组. int NeiType=0;//邻居类型,0:vonNeuman,1:Moore,2:Gn类型 public String getParameter(String key, String def) { return isStandalone ? System.getProperty(key, def) : (getParameter(key) != null ? getParameter(key) : def); } /**Construct the applet*/ public pdcelluar() { //定义记录长度 HistoryData=new int[cyclemax]; } /**Initialize the applet*/ public void init() { try { jbInit(); } catch(Exception e) { e.printStackTrace(); } } /**Component initialization*/ private void jbInit() throws Exception { //resize(width,height); pausebutton = new Button("开始"); setLayout(new BorderLayout()); Panel p = new Panel(); this.setBackground(Color.black); p.setBackground(Color.lightGray); p.add(pausebutton); p.add(new Button("单步")); p.add(new Label("显示:")); disp_choice= new Choice(); disp_choice.addItem("策略"); disp_choice.addItem("id"); disp_choice.addItem("移动方向"); p.add(disp_choice); p.add(new Button("设置")); p.add(new Button("查看")); add("South",p); reinit(); } /**Start the applet*/ public void start() { //开始独立线程 if(runner==null){ runner=new Thread(this); runner.start(); } } /**Stop the applet*/ public void stop() { //结束线程 if (runner!=null) { running = false; runner.stop(); runner=null; } } public void run() { //独立线程的运行 repaint(); while (true) { //程序永远循环下去,如果正在运行或者单步运行则进行下一代的操作 if (running || stepLeft > 0) { SetNextGeneration(); //每隔一段时间就刷新屏幕 if( (steps % refreshSteps == 0)|| (stepLeft > 0)) repaint(); if (stepLeft > 0) stepLeft--; showStatus("Steps:"+(steps++)); //每隔delay时间长度才进行刷新 try{Thread.sleep(delay);}catch(InterruptedException e){}; } else try{Thread.sleep(500);}catch(InterruptedException e){}; }} /**Destroy the applet*/ public void destroy() { if (runner!=null) { running = false; runner.stop(); runner=null; } } /**Get Applet information*/ public String getAppletInfo() { return "Applet Information"; } /**Get parameter info*/ public String[][] getParameterInfo() { return null; } /**Main method*/ public static void main(String[] args) { pdcelluar applet = new pdcelluar(); applet.isStandalone = true; Frame frame; frame = new Frame() { protected void processWindowEvent(WindowEvent e) { super.processWindowEvent(e); if (e.getID() == WindowEvent.WINDOW_CLOSING) { System.exit(0); } } public synchronized void setTitle(String title) { super.setTitle(title); enableEvents(AWTEvent.WINDOW_EVENT_MASK); } }; frame.setTitle("Applet Frame"); frame.add(applet, BorderLayout.CENTER); applet.init(); applet.start(); //frame.setSize(400,320); Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); frame.setLocation((d.width - frame.getSize().width) / 2, (d.height - frame.getSize().height) / 2); frame.setVisible(true); }public void alloc (int sq,int fr, int dly) { //初始化参数 square = sq; // square size of grid's cell fringe = fr; // size of fringe for grid view delay = dly; // sleep timeout im msec between generations //refreshSteps = refresh; // repaint grid every 'refresh' generation only grid = new int[max][max];}public void reinit(){ //整个程序的初始化 running = false; started = true; stepLeft = steps = 0; display_mode=disp_choice.getSelectedIndex(); int sq; int free; //计算出没个方格的大小和边沿的大小 if(width1>height1){ free=height1; }else{ free=width1; } //方格为7/8 sq=(int)(7*free/(8*max)); //边沿为1/8 int fr=(int)(free/max-sq); alloc (sq,fr,200); //初始时刻预算出总共有多少个agent AgCount=(int)(max*max*nonempty_p); //临时数组,为每个agent记忆坐标 int x1[]; int y1[]; x1=new int[2*AgCount]; y1=new int[2*AgCount]; //初始化AgCount AgCount=0; //随机选择企业的位置,并开始AgCount计数 for(int i=0;i<max;i++){ for(int j=0;j<max;j++){ double E = Math.random(); if(E>1-nonempty_p){ //不空的比例 grid[i][j]=AgCount; x1[AgCount]=i; y1[AgCount]=j; AgCount++; }else{ //空格的比例 grid[i][j]=0; } } } //给每个Agent分配颜色 idColors=new Color[AgCount]; int seg=(int)(256*256*256/AgCount); for(int i=1;i<=AgCount;i++){ idColors[i-1]=new Color(i*seg); } //新建Agent个体,并付以初值 ag=new Agent[AgCount]; for(int i=0;i<AgCount;i++){ ag[i]=new Agent(); ag[i].x=x1[i]; ag[i].y=y1[i]; ag[i].id=i; ag[i].m=m_value; double E=Math.random(); //随机的选择合作与不合作的策略 if(E>coop_u){ //不合作 ag[i].state=2; }else{ //合作 ag[i].state=1; } ag[i].total_resource=0; ag[i].cur_resource=0; } //给历史纪录清空 for(int i=0;i<cyclemax;i++){ HistoryData[i]=-1; } //给邻居数组赋值 switch(NeiType){ case(0): Neighbor=new int[vonNeuman.length][2]; for(int i=0;i<2;i++){ for(int j=0;j<vonNeuman.length;j++){ Neighbor[j][i]=vonNeuman[j][i]; } } break; case(1): Neighbor=new int[Moore.length][2]; for(int i=0;i<2;i++){ for(int j=0;j<Moore.length;j++){ Neighbor[j][i]=Moore[j][i]; } } break; case(2): Neighbor=new int[GN.length][2]; for(int i=0;i<2;i++){ for(int j=0;j<GN.length;j++){ Neighbor[j][i]=GN[j][i]; } } } //重画整个图面 repaint(); // update(this.getGraphics());}public void SetNextGeneration() { //每个周期进行的操作 double maxResource; int cCount=0; //让每个Agent根它的邻居们进行博弈 //博弈规则: // 合作 不合作 //合作 1,1 0,m_Value //不合作 m_Value,0 0,0 for(int i=0;i<AgCount;i++){ ag[i].cur_resource=0; if(ag[i].state==1){ //如果当前的Agent的当前状态是合作,就计数到cCount中 cCount++; } //进行博弈,根据邻居数组选择邻居 for(int j=0;j<Neighbor.length;j++){ int x=ag[i].x+Neighbor[j][0]; int y=ag[i].y+Neighbor[j][1]; //让坐标循环起来 if(x<0)x+=max; x=x%max; if(y<0)y+=max; y=y%max; //获得x,y坐标处的Agent的id。 int id=grid[x][y]; if(id!=0){ //如果id不是0,就进行囚徒困境博弈 Agent ag1=ag[id]; double m=ag[i].PlayPD(ag[i].state,ag1.state); //根据博弈的规则更新当前agent的资源 ag[i].cur_resource+=m; ag[i].total_resource+=m; } } } //记载历史数据,把每一步中合作者的数目记录到数组中 int index=steps%cyclemax; HistoryData[index]=cCount; //进行学习,学习规则: //查找当前方格的所有邻居,发现有收益最大的方格就模仿它的策略 for(int i=0;i<AgCount;i++){ maxResource=ag[i].cur_resource; int new_state=ag[i].state; for(int j=0;j<Neighbor.length;j++){ //寻找周围的邻居 int x=ag[i].x+Neighbor[j][0]; int y=ag[i].y+Neighbor[j][1]; //让坐标循环起来 if(x<0)x+=max; x=x%max; if(y<0)y+=max; y=y%max; int id=grid[x][y]; if(id!=0){ Agent ag1=ag[id]; //选择邻居中拥有最多资源的,学习它的策略 if(ag1.cur_resource>maxResource){ new_state=ag1.state; maxResource=ag1.cur_resource; } } } ag[i].state=new_state; //随机选择运动的方向 ag[i].direction=(int)(Neighbor.length*Math.random()); //确定下一个时刻将要去的方格 ag[i].next_x=ag[i].x+Neighbor[ag[i].direction][0]; ag[i].next_y=ag[i].y+Neighbor[ag[i].direction][1]; //保证下一步的坐标循环起来 if(ag[i].next_x<0)ag[i].next_x+=max; ag[i].next_x=ag[i].next_x%max; if(ag[i].next_y<0)ag[i].next_y+=max; ag[i].next_y=ag[i].next_y%max; } //进行移动,移动规则: //随机选择一个朝向的方向,并检查朝向的这个方格是否为空,如果空,则查找它周围的agent //是否也朝向这个方格,如果朝向则不动,否则移动。如果该agent朝向的方格不为空,它就原地不动 for(int i=0;i<AgCount;i++){ int x=ag[i].next_x; int y=ag[i].next_y; //获得下一步将要去的坐标 if(x<0)x+=max; x=x%max; if(y<0)y+=max; y=y%max; //判断是否那个格子已经被别的企业占领 int id=grid[x][y]; if(id==0){ //如果那个方格子是空的 int objs=0; //搜索那个格子周围的agent for(int k=0;k<Neighbor.length;k++){ //获得那个格子邻居的状态 int x1=x+Neighbor[k][0]; int y1=y+Neighbor[k][1]; if(x1<0)x1+=max; x1=x1%max; if(y1<0)y1+=max; y1=y1%max; int id1=grid[x1][y1]; if(id1!=0){ //如果邻居中的agent朝向的格子是当前这个格子,则开始冲突数计数 int x2=ag[id1].next_x; int y2=ag[id1].next_y; if(x2==x&&y2==y){ objs++; } } } //如果冲突数计数<2,意味着只有当前agent朝向这个格子,则它可以占领,如果还有其他企业朝向,则不动 if(objs<2){ //当前agent移动到它朝向的格子 grid[ag[i].x][ag[i].y]=0; ag[i].x=x; ag[i].y=y; grid[x][y]=ag[i].id; } } }}public void update(Graphics g) { paint(g);}public void paint (Graphics g) { //画图 if (started) { //如果重新开始,就刷新矩形 g.clearRect(0,0,width1,height1); g.setColor( StateColors [0]); g.fillRect(0,0,width1,height1); started = false; } //对所有的坐标循环,如果坐标处的id为0就画背景色,否则按照显示模式画颜色 for (int X=0;X<max;X++) for (int Y=0;Y<max;Y++) { if(grid[X][Y]!=0){ int show=0; if(display_mode==0){ show=ag[grid[X][Y]].state; g.setColor( StateColors [show]); }else if(display_mode==1){ show=grid[X][Y]; g.setColor(idColors[show]); }else if(display_mode==2){ show=ag[grid[X][Y]].direction; g.setColor( StateColors [show]); } }else{ g.setColor(StateColors[0]); } g.fillRect(X*(square+fringe),Y*(square+fringe),square,square); }}public boolean action(Event ev, Object arg){ if ( ev.target instanceof Button) { //处理按钮时间响应 String button = (String) arg; if (button.equals("停止")) { pausebutton.setLabel("开始"); running = false; } else if (button.equals("开始")) { pausebutton.setLabel("停止"); running = true; } else if (button.equals("单步")) { stepLeft = 1; if (running) { pausebutton.setLabel("开始"); running = false; } } else if(button.equals("设置")){ running=false; CelluarControl ctl=new CelluarControl(this); ctl.setSize(300,300); ctl.show(); } else if(button.equals("查看")){ ViewLog ctl=new ViewLog(this); ctl.setSize(550,400); ctl.show(); } return true; } else if ( ev.target instanceof Choice) { int olddisp,disp1; olddisp=display_mode; disp1=disp_choice.getSelectedIndex(); if(disp1!=olddisp){ display_mode=disp1; } return true; } else return false;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -