📄 bfagent.java
字号:
getDividendFromWorld(); global_mean = price + dividend; forecast = lforecast = global_mean; // Initialize the forecasts, put them into Swarm Array //keep the 0'th forecast in a "know nothing" condition fcastList.add(0, this.createNewForecast()); //create rest of forecasts with random conditions for ( i = 1; i < numfcasts; i++) { aForecast = this.createNewForecast() ; this.setConditionsRandomly (aForecast); fcastList.add(i, aForecast); //put aForecast into Swarm array "fcastlist" }/* Compute average specificity */ //pj: Here is the proper way to iterate over Swarm collections for( i=1; i < numfcasts; i++ ) { aForecast = (BFCast)fcastList.get(i); sumspecificity += aForecast.getSpecificity(); //[aForecast print]; } avspecificity = (double) sumspecificity/(double)numfcasts; return this;}/*"Creates a new forecast object (instance of BFCast), with all condition bits set to 00 here, meaning "don't care. It also sets values for the other coefficients inside the BFCast. This method is accessed at several points throughout the BFagent class when new forecasts are needed."*/public BFCast createNewForecast(){ BFCast aForecast; //needed to set values of a,b,and c double abase = privateParams.a_min + 0.5*(1.0-privateParams.subrange)*privateParams.a_range; double bbase = privateParams.b_min + 0.5*(1.0-privateParams.subrange)*privateParams.b_range; double cbase = privateParams.c_min + 0.5*(1.0-privateParams.subrange)*privateParams.c_range; double asubrange = privateParams.subrange*privateParams.a_range; double bsubrange = privateParams.subrange*privateParams.b_range; double csubrange = privateParams.subrange*privateParams.c_range; aForecast= new BFCast(this.getZone()); aForecast.setCondwords( privateParams.condwords); aForecast.setCondbits( privateParams.condbits); aForecast.setNNulls( privateParams.nnulls); aForecast.setBitcost( privateParams.bitcost); aForecast.createEnd(); aForecast.setForecast(0.0); aForecast.setLforecast(global_mean); //note aForecast has the forecast conditions=0 by its own createEnd. //also inside its createEnd, lastactive =1, specificity=0, variance=99999; //pj: Controversy/confusion BFagent.m as originally distributed used //definitions for variance and strength that did not match the //bfagent.m file or the documentation. I'm following bfagent.m and //the docs, ignoring what was in BFagent.m aForecast.setVariance(privateParams.newfcastvar); //same as bfagent's init aForecast.setStrength(0.0); /* Set the forecasting parameters for each fcast to random values in a * fraction "subrange" of their range, centered at the midpoint. For * subrange=1 this is the whole range (min to max). For subrange=0.5, * values lie between 1/4 and 3/4 of this range. subrange=0 gives * homogeneous agents, with values at the middle of their min-max range. */ aForecast.setAval(abase + drand()*asubrange); aForecast.setBval(bbase + drand()*bsubrange); aForecast.setCval(cbase + drand()*csubrange); return aForecast;}/*"Take a forecast object and randomly change the bits that govern which conditions it monitors. This appears to be a piece of functionality that could move to the BFCast class itself. There were quite a few of these details floating around in BFagent at one time, many are gone now."*/public Object setConditionsRandomly( BFCast fcastObject){ int bit; double problist[] = new double[privateParams.condbits]; int bitlist[] = new int[privateParams.condbits]; java.lang.System.arraycopy(privateParams.getBitListPtr(), 0, bitlist, 0, privateParams.condbits); java.lang.System.arraycopy(privateParams.getProbListPtr(), 0, problist, 0, privateParams.condbits); for(bit=0; bit< privateParams.condbits; bit++) { if (bitlist[bit] < 0) { fcastObject.setConditionsbit$FromZeroTo(bit,3);//3=11 is a "filler" } else if (drand() < problist[bit]) { fcastObject.setConditionsbit$FromZeroTo( bit ,irand(2)+1); //remember 1 means no, or binary 01, and 2 means Yes, or 10 fcastObject.incrSpecificity();//pj: I wish this were automatic! fcastObject.updateSpecfactor(); } } return this;}public Object prepareForTrading() /*" * Set up a new active list for this agent's forecasts, and compute the * coefficients pdcoeff and offset in the equation * forecast = pdcoeff*(trialprice+dividend) + offset * * The active list of all the fcasts matching the present conditions is saved * for later updates. "*/{ //register struct BF_fcast *fptr, *topfptr, **nextptr; //unsigned int real0, real1, real2, real3, real4 = 0 ; double weight, countsum, forecastvar=0.0; int mincount; int nactive; //pj: for getting values from world BitVector myworld = new BitVector(this.getZone()); myworld.setCondwords( params.condwords); myworld.setCondbits( params.condbits); myworld.createEnd(); //for using indexes of forecast objects BFCast aForecast; double a, b, c, sum, sumv;// if (WEIGHTED == 1) //struct BF_fcast *bestfptr; BFCast bestForecast;//else double maxstrength;//else // First the genetic algorithm is run if due currentTime = Globals.env.getCurrentTime(); if (currentTime >= privateParams.firstgatime && drand() < privateParams.gaprob) { this.performGA(); //activeList removeAll; } //this saves a copy of the agent's last as lforecast. lforecast = forecast; myworld = this.collectWorldData(this.getZone()); this.updateActiveList(myworld); // myworld.drop(); //was created inside collectWorldData if(WEIGHTED == 1){ // Construct weighted-average forecast // The individual forecasts are: p + d = a(p+d) + b(d) + c // We often lock b at 0 by setting b_min = b_max = 0. //pj: note I started updating this code to match the rest, but then //pj: I realized it did not work as it was before, so I stopped //pj: messing with it. Don't expect the CPPFLAG WEIGHTED to do //pj: anything good. a = 0.0; b = 0.0; c = 0.0; sumv = 0.0; sum = 0.0; nactive = 0; mincount = privateParams.mincount; /* for( i=0; i < numfcasts; i++ ) { aForeCast = (BFCast)fcastList.get(i); sumspecificity += aForecast.getSpecificity(); //[aForecast print]; } */ for( int i=0; i<activeList.size(); i++ ) { aForecast = (BFCast)activeList.get(i); aForecast.setLastactive(i); if ( aForecast.incrCount() >= mincount ) { double sumstrength; double strength; strength=aForecast.getStrength(); ++nactive; a += strength*aForecast.getAval(); b += strength*aForecast.getBval() ; c += strength*aForecast.getCval() ; sum += strength; sumv += aForecast.getVariance(); } } if (nactive != 0) { pdcoeff = a/sum; offset = (b/sum)*dividend + (c/sum); if(privateParams.individual!=0){ forecastvar = variance; } else{ forecastvar = sumv/((double)nactive); } } }else{ //NOT WEIGHTED MODEL // Go through the list and find best forecast maxstrength = -1e50; bestForecast = null; nactive = 0; mincount = privateParams.mincount; //pj: Kept as example of "homemade list" in ASM-2.0// for (fptr=activelist; fptr!=NULL; fptr=fptr->next) // { // fptr->lastactive = currentTime; // if (++fptr->count >= mincount) // { // ++nactive; // if (fptr->strength > maxstrength) // { // maxstrength = fptr->strength; // bestfptr = fptr; // } // } // } //??Following code causes a bug when numfcasts is small. It causes //nactive >0 even though there is no best forecast. ?? Track it down //This problem existed in ASM-2.0, should back track it. for( int i=0; i<activeList.size(); i++ ) { aForecast = (BFCast)activeList.get(i); aForecast.setLastactive(currentTime); if(aForecast.incrCount() >= mincount) { double strength=aForecast.getStrength(); ++nactive; if (strength > maxstrength) { maxstrength = strength; bestForecast= aForecast; } } } // Here is the way it was in ASM-2.0 // if (nactive) // { // pdcoeff = bestfptr->a; // offset = bestfptr->b*dividend + bestfptr->c; // forecastvar = (privateParams->individual? bestfptr->variance :variance); // } if (nactive!=0) // meaning that at least some forecasts are active { pdcoeff = bestForecast.getAval(); offset = bestForecast.getBval()*dividend + bestForecast.getCval(); if(privateParams.individual!=0){ forecastvar = variance; } else{ forecastvar = bestForecast.getVariance(); } } else // meaning "nactive" zero, no forecasts are active { // No forecasts are minimally adequate!! // Use weighted (by count) average of all rules countsum = 0.0; pdcoeff = 0.0; offset = 0.0; mincount = privateParams.mincount; for( int i=0; i<fcastList.size(); i++ ) { aForecast = (BFCast)fcastList.get(i); if (aForecast.getCnt() >= mincount) { countsum += weight = aForecast.getStrength(); offset += (aForecast.getBval()*dividend + aForecast.getCval())*weight; pdcoeff += aForecast.getAval()*weight; } if (countsum > 0.0) { offset /= countsum; pdcoeff /= countsum; } else { offset = global_mean; } forecastvar = variance; // 縔 le pones la varianza de los mejores? } } }//#endif divisor = privateParams.lambda*forecastvar; return this;}/*"A forecast has a set of conditions it is watching. These are packedtight in a BitVector. We need the world data about the status of thoseconditions packed the same way, in order to make quick checks to findout if the world conditions are matched by the BitVector'sconditions. This method creates a BitVector to match the conditionsthat are being monitored by the agent's forecasts. This requires theuse of the design assumption that all of an agent's forecasts have thesame bitlist."*/public BitVector collectWorldData(Zone aZone){ int i,n,nworldbits; BitVector world; nworldbits = (Agent.worldForAgent).getNumWorldBits(); int bitlist[] = new int[privateParams.condbits]; int myRealWorld[]= new int[nworldbits]; world= new BitVector(this.getZone()); world.setCondwords( params.condwords); world.setCondbits( params.condbits); world.createEnd(); bitlist = params.getBitListPtr(); (Agent.worldForAgent).getRealWorld( myRealWorld); for (i=0; i < params.condbits; i++) { if ((n = bitlist[i]) >= 0) //myworld[WORD(i)] |= myRealWorld[n] << ((i%16)*2); world.setConditionsbit$To( i , myRealWorld[n]); } //[aZone free: myRealWorld]; return world;}public boolean changeIntToBoolean(int a){ if (a!=0) return true; else return false; }/*"This is the main inner loop over forecasts. Go through the list of active forecasts, compare how they did against the world. Notice the switch that checks to see how big the bitvector (condwords) is before proceeding. At one time, this gave a significant speedup. The original sfsm authors say 'Its ugly, but it works. Don't mess with it!' (pj: I've messed with it, and don't notice much of a speed effect on modern computers with modern compilers :> My alternative implementation is commented out inside this method)"*/ public Object updateActiveList(BitVector worldvalues){ BFCast aForecast; this.copyList$To(activeList , oldActiveList); //pj: note, if activeList is empty, then oldActiveList will be empty. activeList.clear(); //pj:copy forecasted values from objects in active to oldActiveList for( int i=0; i<oldActiveList.size(); i++ )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -