A practical introduction to OptimalGrid - Part III  
 

(Post 29/08/2006) In this section, we define a simple cellular problem and show how we would write the Java code that uses OptimalGrid to study the problem.

Các phần đã đăng:

Section 5. Writing an OptimalGrid problem solver

Introduction

In this section, we define a simple cellular problem and show how we would write the Java code that uses OptimalGrid to study the problem.

As we go along, we'll provide links to the full Java source code for the Java classes that we describe. If you have downloaded and installed OptimalGrid, then you can also access the JavaDoc for the OptimalGrid system. If you installed OptimalGrid
into C:\java , then you can use the following URL address:

file://localhost/C:/java/grid/html/javadoc/index.html

Eden model

For our example, we will use the Eden model for bacterial growth. In our problem, we have three entities representing three types of bacteria (A, B, and C) that are growing in a two-dimensional space (petri Dish). We use Cartesian coordinates so the smallest elements or cells in this space are squares with sides of unit length. In the Eden model, each OPC represents a cell that may contain an entity that represents one of the 3 kinds of bacteria. Each cell also contains the methods or rules that describe how the entities interact on site and how they spread or propagate to other sites. The entities contain information about to interact with other entities. In this example, the interaction method causes A to eat B, B to eat C, and C to eat A. The propagation method describes how the bacteria spread. Propagation to adjacent sites or cells requires that each cell also store pointers to (nearest) neighbors. These pointers define a graph and, together with the propagation method, add the communication requirement to the problem. In the example, the propagate method causes, at every iteration, an entity at site (i,j) to spread to its nearest neighbors at sites (i+1,j),(i-1,j),(i,j+1),(i,j-1) each with probability 0.5.

We will study the resulting spread of bacteria visually. Figure 5 shows the status of the three types of bacteria at four different points in time.

Define Java class for Eden model cell

The first step is to define a Java class that defines the contents of and methods used by the OPC.

See the Code listing for OPCEden class.

For this problem, we will implement an OPCEden Java class that extends the OPCAbstract class. OPCAbstract contains the data and behavior that is required for any OPC object.


public class OPCEden extends OPCAbstract
implements Serializable, Cloneable {

An OPCEden class contains two methods that are run at each iteration of the problem.

  • propagation()
  • localInteraction()

The propagation() method describes how the bacteria spread. Propagation to adjacent sites or cells requires that each cell also store pointers to (nearest) neighbors. These pointers define a graph and together with the propagation method add the communication requirement to the problem. In the example, the propagate method causes, at every iteration, a bacteria at site (i,j) to spread to its nearest neighbors at sites (i+1,j),(i-1,j),(i,j+1),(i,j-1) each with probability 0.4 (the classic Eden model for bacterial growth).

The localInteraction() method causes bacteria A to eat B, B to eat C, and C to eat A.

When the problem is run with a grid of networked machines, one or more neighbors of an OPC may reside on a separate machine, but that is transparent to the OPCEden class.

Define Java class for the Eden entity

An Eden OPC may contain occupants that represent a type of bacteria of a specified type or species (i.e. A, B or C) that is living in the cell. It has a foodID attribute that represents the type of food (another type of bacteria in this predator prey example) that it will eat. For this example code, bacteria A eats B; B eats C; and C eats A. In other models, entities might represent a fluid, an electron or electron density, local stress, bacteria, heat, temperature, etc. For our Eden model, we will define a Java class, EntityEden, that describes the bacteria.

See the Code Listing for EntityEden class.


public class EntityEden extends EntityAbstract
implements Serializable, Cloneable {

An EntityEden class uses the following instance variables.

  • _entityID ID of this bacteria. Inherited from EntityAbstract
  • _foodID ID of the bacteria this bacteria will eat.
  • _alive true if the bacteria is alive
  • _propagationprob Probability that this bacteria will propagate to its neighbor
  • _rgbColor Color assigned to this bacteria. This is inherited from EntityAbstract and is used for graphical representation of the problem.

Define Java class for Eden properties

An Eden OPC may contain properties that represent the properties assigned to this OPC. Properties might be local elastic constants, local hardness, local conductivity, thermal conductivity, heat capacity, and so forth. For our Eden model, we will define the PropertyEden which describes the adjustment to the probability with which bacteria associated with an OPC will propagate to its neighbors.

See the Code listing for PropertyEden class.

Eden model propagate() method

The important parts of the OPCEden.propagate() method are shown below.

See the Code listing for OPCEden Propagate().

The propagate() method is passed the following parameters.

  • int collectionIndex_ -- Index to the OPCCollection
  • VppAbstract vpp_ -- Reference to the VPP for this OPC element
  • int iteration_ -- Iteration number
  • Random rnd_ -- Random number generator

public synchronized ArrayList propagate(int collectionIndex_,
VppAbstract vpp_, int iteration_, Random rnd_) {

It will now get a list of all the neighboring OPCs.


ArrayList tempArray = this.getAllOPCNeighbors(collectionIndex_, vpp_);

It will now iterate through the neighboring OPCs and for each one call the processNeighbor() method that will handle propagation between that OPC back to the current OPC.


Iterator iter = tempArray.iterator();
while (iter.hasNext()) {
// get the collection element
OPCEden OPCNeighbor = (OPCEden) iter.next();
// propagate neighbors entities to newOccupants
processNeighbor(OPCNeighbor,newOccupants,vpp_,iteration_,rnd_);
} // while hasNext

Now it has in newOccupants a list of competing entities. We will return this new ArrayList. Note that we do not store it yet in the current OPC because when we process the next OPC, it will look at this OPC as a neighbor and we want it to be unchanged. The ArrayList that we return here will be an input to the localInteraction method.


return newOccupants;

Eden model localInteration() method

The following is the important code for the OPCEden localInteraction() method.

See the Code listing for OPCEden localInteraction().

The localInteraction() method is passed a reference to the VPP, the iteration number and an ArrayList of competing entity objects that belong to this OPC as the result of the propagation() method.


public synchronized void localInteraction(VppAbstract vpp_, \
int iteration_, ArrayList occupants_) {

It will now go through the list of competing entities, and based on the rules of which bacteria (entities) eat which, it will come up with only one remaining bacteria. Remember! A eats B, B eats C, and C eats A.


// are there any occupants?
if ((occupants_ != null) && (occupants_.size() > 1)) {
// yes, then loop through them
for (int i = 0; i < occupants_.size(); i++) {
for (int j = 0; j < occupants_.size(); j++) {
if (i == j) continue;
EntityEden obj1 = (EntityEden) occupants_.get(i);
EntityEden obj2 = (EntityEden) occupants_.get(j);
// obj2._foodID contains the type of food that obj2 eats.
// so if it matches the EntityID for obj1, then obj2 eats obj1.
if (obj2.isAlive() && (obj2.getFoodID() == obj1.getEntityID())) {
//yes, then obj1 is dead
obj1.setAlive(false);
}
} // for j
} // for i. First loop checks for predators

It will now go through the list of occupants and remove the dead ones.


for (Iterator iter = occupants_.iterator(); iter.hasNext();) {
EntityEden obj1 = (EntityEden) iter.next();
if ( ! obj1.isAlive() ) {
// no, then log the population change and remove it
vpp_._valueMonitor.accumulateValueData(iteration_, obj1.getEntityID(), -1);
iter.remove();
}
} // iterate. Second loop removed dead occupants
} // end if not null or empty

It will now save the list of EntityEden objects to the OPCEden instance.


super.setOccupants(occupants_);

EntityEden class

The following is the important part of the code for the EntityEden class.

See also Code Listing for EntityEden class.


public class EntityEden extends EntityAbstract {
private boolean _dead = false;
private double _propagationProb;
private int _foodID = 0;
/**
* Types of bacteria are TYPE_A, TYPE_B and TYPE_C
*
* TYPE_A eats TYPE_B; TYPE_B eats TYPE_C and TYPE_C eats TYPE_A
*/
public static final int TYPE_A = 5;
public static final int TYPE_B = 3;
public static final int TYPE_C = 2;
/**
* Predefined entities used by VppEdenInitializer to set up 
* initial conditions
*/
public static final EntityEden ENTITY_A = new EntityEden(
   TYPE_A,TYPE_B,0.4);
public static final EntityEden ENTITY_B = new EntityEden(
   TYPE_B,TYPE_C,0.4);
public static final EntityEden ENTITY_C = new EntityEden(
   TYPE_C,TYPE_A,0.4);
/**
*
* Construct and EntityEden with default values.
* This public constructor is required so that the XML support
* can dynamically build from an XML file.
*/
public EntityEden() {
}
/**
* Builds an Eden entity instance which describes a bacteria.
* @param entityID_ The type of bacteria TYPE_A, TYPE_B or TYPE_C
* @param foodID_ Food: The type of bacteria this one eats
* @param double propagationProb_ The propagation probability
*/
public EntityEden(int entityID_, int foodID_, double propagationProb_) {
_propProb = propagationProb_;
_entityID = entityID_;
_alive = true;
_foodID = foodID_;
// define the color based on type
if (_entityID == TYPE_A) {
_rgbColor = Color.RED.getRGB();
} else if (_entityID == TYPE_B) {
_rgbColor = Color.GREEN.getRGB();
} else if (_entityID == TYPE_C) {
_rgbColor = Color.BLUE.getRGB();
} else {
Debug.error("EntityEden:"," Invalid Entity. entityID="+_entityID);
}
}

EntityEden Class, continued

The following two sections show the getXML and initFromXML methods that are part of the code for the EntityEden class.

Because the entityEden class has added some new instance variables (_foodID and _propagationProb), it needs to add these to the generated XML and be able to initialize the value when the XML is read back in. This is taken care of by the getXML() and initFromXML() methods which are shown below. These two methods are required in EntityEden and PropertyEden because they have added unique instance variables. If OPCEden had added instance variables, it would require these methods also. If they are not included, the XML created and read by the problem would not be complete. Note that the instance variable _dead is not specified. It is only used to pass state from the propagate() method to the localInteraction() method and is not needed to show state at the end of an interval.


/**************************************************************************
** getXML() **
*******************/
/**
*
* Generates an XML representation of an entity object
* to be appended to the EntityElement by the XMLOPCCollectionWriter.
* These elements contain any data unique to a class
* extending EntityAbstract (this class).
*
* The XML support will generate something like the following for
* the EntityAbstract object. Note that the code in this method has
* added "food="3" to the attributes.
*
*
* 
* 
* 
*
*
*
* This element must contain all data unique to a class extending 
* entityAbstract. The first thing the getXML() method implementation
* should do in any class extending entityAbstract is to call
* the getXmlElement() method from its superclass to get the basic
* XML for an abstract entity.
*
* Uses the libraries defining element defined in org.jdom
*
* @see com.ibm.almaden.smartgrid.EntityAbstract
*
*
* @returns entityElement the XML representation for an EntityEden class
*
*
***************************************************************************
*/
public Element getXML() {
// It must first call the getXMLElement for the entityAbstract
Element entityElement = super.getXmlElement();
// now add the _foodID and _probProb attribute to the XML.
entityElement.setAttribute(PROBABILITY, "" + this._propProb);
entityElement.setAttribute(FOOD_ID, "" + this._foodID);
return entityElement;
}// getXML()

More about the EntityEden class

This is the initFromXML() method


/**************************************************************************
** initFromXML() **
*******************/
/**
** Required method. Generates a new EntityEden instance from
* an XML representation of the entity.
*
* This method initializes an EntityEden object based on the
* XML that was created by the getXML() method.
* Using the following line of XML, the EntityEden instance
* will be recreated including the "foodID" value that this class
* defines.
*
* 
* 
* 
*
** Generates a new EntityEden instance from an XML element
* The first thing any entity.initFromXML() method must do
* is call super. initCommonSubsetFromXML() to initialize
* those entities characteristic of any class extending
* entityAbstract.
*
* Uses the libraries
* org.jdom.Element;
*
* @see com.ibm.almaden.smartgrid.EntityAbstract
*
* @param entityElement_ the xml representation of a property object
*
*
*
***************************************************************************
*/
public void initFromXML(Element entityElement_) {
super.initCommonSubsetFromXML(entityElement_);
this._propProb = getDoubleAttribute(entityElement_, PROBABILITY);
this._foodID = getIntAttribute(entityElement_, FOOD_ID);
}// initFromXMLL()

PropertyEden class

The Property class defines any properties that may apply to the OPC or its entities. In this example of the Eden model, the PropertyEden class is used to modify the propagation of the EntityEden objects (the bacteria). In other models, properties might be local elastic constants, local hardness, local conductivity, thermal conductivity, heat capacity, and so forth.

The adjustment to the probability value is a new instance variable in the PropertyEden class. If the PropertyId matches the entity, then the propagation probability is increased by the PropertyEden probability value. Otherwise, it is decreased by that value. Think of this class as an abstract property or factor that makes a specific OPC more or less friendly to a particular type of bacteria. Because the probability value is an addition to PropertyAbstract instance variables, it requires getXML() and initFromXML() methods similar to the EntityEden methods.

See the Code listing for PropertyEden class.

VppEdenInitializer Class

The VppEdenInitializer class extends VppDataInitializerAbstract.

Most applications will need to provide a class to initialize the state of the application specific OPCs in the original collections describing a problem at time zero (the beginning of a run). If the OPC classes have application-specific data they will require application-specific initializers. These classes are used when a run is started using the ProblemAutoBuilder which constructs the problem state from scratch. These classes are not required when launching a problem with the ProblemBuilderXML as the problem state defined in the XML documents are, presumably, properly initialized.

The VppEdenInitializer class determines what bacteria (what entities) are placed in new OPCEden instances used to populate the initial collections. For now, properties are not set by VppEdenInitializer. The VppEdenInitializer picks one collection in each VPP and puts an instance of each of the three EntityEden bacteria types in different OPCEden objects.

See the Code Listing for VppEdenInitializer class.

AppUtils class

The Eden model does not use a specific application utility class. All the data and methods required for the Eden model are contained in the OPC class (so the Eden model, by default, uses the empty class AppUtilsGeneric). The application programmer can define a class that implements the AppUtilsAbstract class. It can contain application-specific utility functions and data that can be initialized from the application configuration file at startup. Every OPC can share one instance of an implementation of AppUtilsAbstract. This provides an efficient place to store data and/or methods common to every OPC in an application. It is not required that the user implement this utility. By default, the AppUtilsGeneric class is used.

See the Code listing for AppUtilsGeneric class.

eden.cfg file

Every application can specify an application-specific config file. If not required, the grid.cfg file sets the necessary defaults. We suggest that developers always use an application-specific configuration if for no other reason than to specify in a concise way the necessary class files used for their application. See the eden.cfg file file provided in the distributed example. The VppEdenInitializer code show an example of the simple code needed to access the configuration data.

An excerpt from both the system configuration file, grid.cfg, and the problem configuration file, eden.cfg, is shown below:


# grid.cfg
[a]
...
appConfigFile = ./eden.cfg
...
# eden.cfg
# This is the configuration file for the Eden model application
# running on OptimalGrid
#-----------------------------------------------------------
# The [problem] section contains general specifications for
# the Eden model problem
#-----------------------------------------------------------
#
[problem]
OPCClass = com.ibm.almaden.smartgrid.apps.eden.OPCEden
utilClass = com.ibm.almaden.smartgrid.AppUtilsGeneric
vppInitializerClass = com.ibm.almaden.smartgrid.\
apps.eden.VppEdenInitializer

The name of the config file to use can be set in the grid.cfg file as shown above or it can be specified on the command line.

./grid.bat -problemConfig ./eden.cfg

When the problem manager is started, a dialog window will be displayed so that you can make temporary changes to the OptimalGrid configuration.

Further problem termination

When the problem terminates, the final status of each OPC is written as XML. You could use this XML output file to start another OptimalGrid session or write your own data reduction program to read and process the XML.

The following is an excerpt of the XML that is written for the Eden model problem.

<?xml version="1.0" encoding="UTF-8"?>
<OptimalGrid>
<OPCCollection Name="c0" Number="0" Size="144" VppOwner="VPP_0" LocalTime="401">
<MinCoord xVal="0" yVal="0" zVal="0" />
<MaxCoord xVal="11" yVal="11" zVal="0" />
<CollectionEdge Index="0" UniqueKey="c0.0">
<RequiredConnection ReqKey="c1.0" VppOwnerName="VPP_1" />
</CollectionEdge>
<CollectionEdge Index="1" UniqueKey="c0.1">
<RequiredConnection ReqKey="c4.0" VppOwnerName="VPP_0" />
</CollectionEdge>
<CollectionEdge Index="2" UniqueKey="c0.2">
<RequiredConnection ReqKey="c1.2" VppOwnerName="VPP_1" />
<RequiredConnection ReqKey="c4.1" VppOwnerName="VPP_0" />
</CollectionEdge>
<collectionArray>
<OPC Index="0" parentEdgeID="-1" parentEdgeIndex="-1">
<class name="class com.ibm.almaden.smartgrid.apps.eden.OPCEden" />
<Coords xVal="0" yVal="0" zVal="0" />
<localNeighbor Id="1" />
<localNeighbor Id="12" />
<entityAbstract Id="5" color="16711680" prob="0.4" food="3">
<class name="class com.ibm.almaden.smartgrid.apps.eden.EntityEden" />
</entityAbstract>
</OPC>
<OPC Index="1" parentEdgeID="-1" parentEdgeIndex="-1">
<class name="class com.ibm.almaden.smartgrid.apps.eden.OPCEden" />
<Coords xVal="1" yVal="0" zVal="0" />
<localNeighbor Id="2" />
<localNeighbor Id="0" />
<localNeighbor Id="13" />
<entityAbstract Id="2" color="255" prob="0.4" food="5">
<class name="class com.ibm.almaden.smartgrid.apps.eden.EntityEden" />
</entityAbstract>
</OPC>
...

(Copyright IBM Corporation)


 
 

 
     
 
Công nghệ khác:


A practical introduction to OptimalGrid - Part IIA practical introduction to OptimalGrid - Part I
Những Keyboard cho dân chơi Game - phần 1Kiến trúc đa nhân, thời đại mới của vi xử lý (Phần II)
Kiến trúc đa nhân, thời đại mới của vi xử lý (Phần I)Tăng 3 lần sức mạnh cho FlashGet!
  Xem tiếp    
 
Lịch khai giảng của hệ thống
 
Ngày
Giờ
T.Tâm
TP Hồ Chí Minh
Hà Nội
 
   
New ADSE - Nhấn vào để xem chi tiết
Mừng Sinh Nhật Lần Thứ 20 FPT-APTECH
Nhấn vào để xem chi tiết
Bảng Vàng Thành Tích Sinh Viên FPT APTECH - Nhấn vào để xem chi tiết
Cập nhật công nghệ miễn phí cho tất cả cựu sinh viên APTECH toàn quốc
Tiết Thực Vì Cộng Đồng
Hội Thảo CNTT
Những khoảnh khắc không phai của Thầy Trò FPT-APTECH Ngày 20-11