package mior.model; import java.util.Random; public class CPUMiorModel extends SimpleMiorModel { public final int OFFER_INVALID = -1; public final int OFFER_UNINIT = -2; public CPUMiorModel(MiorWorld world) { super(world); } @Override public void doTopologyImpl() { int occupation = 0; int tailleMax = 0; for (int iMM = 0; iMM < mmList.length; iMM++) { int taille = 0; for (int iOM = 0; iOM < omList.length; iOM++) { final MiorMM mm = mmList[iMM]; final MiorOM om = omList[iOM]; final int offset = iMM * world.nbOM + iOM; final float dx = mm.x - om.x; final float dy = mm.y - om.y; if (Math.sqrt(dx * dx + dy * dy) < world.RA) { associations[offset] = OFFER_UNINIT; taille++; occupation++; } else { associations[offset] = OFFER_INVALID; } } tailleMax = Math.max(tailleMax, taille); } final int maxCapacity = nbOM * nbMM; final double fraction = (100.0 * occupation) / maxCapacity; //System.out.println("Occupation : " + occupation + "/" + maxCapacity // + "\t(" + fraction + "%)"); //System.out.println("Taille max : " + tailleMax + "/" + nbOM); } @Override protected void doLiveImpl() { for (int iMM = 0; iMM < world.nbMM; iMM++) { final int indexes[] = getOMIndexes(); breath(iMM, indexes); if (mmList[iMM].dormance == 0) { grow(iMM, indexes); } } clean(); } @Override protected void releaseImpl() { } private void breath(int iMM, int[] indexes) { final MiorMM mm = mmList[iMM]; final int totalNeed = (int) (mm.carbone * world.RR); int remainingNeed = totalNeed; // Check if ressources seems to be available for (final int iOM : indexes) { final int offset = iMM * world.nbOM + iOM; if (remainingNeed < 0) { break; } // System.out.println(associations[mmOffset + iOM]); if (associations[offset] != OFFER_INVALID) { final int offer = (int) (world.K * omList[iOM].carbone); // System.out.println("MM(" + iMM + "): OM(" + iOM + ") offers " // + offer + ", remaining need : " + remainingNeed); remainingNeed -= offer; } } if (remainingNeed > 0) { mm.dormance = 1; } else { mm.dormance = 0; remainingNeed = totalNeed; for (final int iOM : indexes) { if (remainingNeed < 0) { break; } final int offset = iMM * world.nbOM + iOM; if (associations[offset] != OFFER_INVALID) { final MiorOM om = omList[iOM]; int offer, consum; synchronized (om) { offer = (int) (world.K * om.carbone); consum = Math.min(offer, remainingNeed); remainingNeed -= consum; om.carbone -= consum; } synchronized (world) { world.CO2 += consum; } associations[offset] = offer - consum; } } } } private int[] getOMIndexes() { final Random rng = new Random(); final int[] indexes = new int[world.nbOM]; for (int i = 0; i < indexes.length; i++) { indexes[i] = i; } shuffle(indexes, rng); return indexes; } private void grow(int iMM, int[] indexes) { final MiorMM mm = mmList[iMM]; final int totalNeed = (int) (mm.carbone * world.GR); int remainingNeed = totalNeed; for (final int iOM : indexes) { if (remainingNeed < 0) { break; } final int omOffset = iMM * omList.length + iOM; int offer; if (associations[omOffset] != OFFER_INVALID) { final MiorOM om = omList[iOM]; synchronized (om) { if (associations[omOffset] != OFFER_UNINIT) { offer = associations[omOffset]; } else { offer = (int) (world.K * om.carbone); } final int consum = Math.min(offer, remainingNeed); remainingNeed -= consum; om.carbone -= consum; mm.carbone += consum; } } } } private void clean() { for (int i = 0; i < associations.length; i++) { if (associations[i] != OFFER_INVALID) { associations[i] = OFFER_UNINIT; } } } private void shuffle(int[] a, Random rng) { for (int i = a.length - 1; i >= 1; i--) { final int j = rng.nextInt(i + 1); final int t = a[i]; a[i] = a[j]; a[j] = t; } } }