PageRenderTime 88ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/mona/projects/mox/src/EvolveMoxen.java

#
Java | 1786 lines | 1518 code | 161 blank | 107 comment | 298 complexity | cdccfc29d7a29099e365344224cb33a4 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * Evolve individual mox foragers and predator-forager pairs
  3. * by mutating and recombining parameters.
  4. */
  5. import java.util.*;
  6. import java.io.*;
  7. import mona.NativeFileDescriptor;
  8. public class EvolveMoxen
  9. {
  10. // Usage.
  11. public static final String Usage =
  12. "Usage:\n" +
  13. " New run:\n" +
  14. " java EvolveMoxen\n" +
  15. " -generations <evolution generations>\n" +
  16. " -steps <moxen steps>\n" +
  17. " [-stepGameOfLife]\n" +
  18. " -moxPopulations \"" + EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getName() +
  19. "\" | \"" + EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getName() + "\"\n" +
  20. " [-trainForagers (train foragers before evaluating them)]\n" +
  21. " -loadCells <file name> (repeatable option)\n" +
  22. " -output <evolution output file name>\n" +
  23. " [-mutationRate <mutation rate>]\n" +
  24. " [-randomMutationRate <random mutation rate>]\n" +
  25. " [-maxSensorRange <maximum sensor range>]\n" +
  26. " [-randomSeed <random seed> (for new run)]\n" +
  27. " [-logfile <log file name>]\n" +
  28. " [-dashboard (run with mox world dashboard)]\n" +
  29. " Resume run:\n" +
  30. " java EvolveMoxen\n" +
  31. " -generations <evolution generations>\n" +
  32. " -steps <moxen steps>\n" +
  33. " [-stepGameOfLife]\n" +
  34. " [-trainForagers (train foragers before evaluating them)]\n" +
  35. " -input <evolution input file name>\n" +
  36. " -output <evolution output file name>\n" +
  37. " [-mutationRate <mutation rate>]\n" +
  38. " [-randomMutationRate <random mutation rate>]\n" +
  39. " [-maxSensorRange <maximum sensor range>]\n" +
  40. " [-randomSeed <random seed> (for new run)]\n" +
  41. " [-logfile <log file name>]\n" +
  42. " [-dashboard (run with mox world dashboard)]\n" +
  43. " Extract into mox_world_forager|predator_<mox id>_world_<number>.mw files:\n" +
  44. " java EvolveMoxen\n" +
  45. " -extract\n" +
  46. " -input <evolution input file name>\n" +
  47. " Print population properties:\n" +
  48. " java EvolveMoxen\n" +
  49. " -properties\n" +
  50. " -input <evolution input file name>\n" +
  51. " Print evolution statistics:\n" +
  52. " java EvolveMoxen\n" +
  53. " -statistics\n" +
  54. " -input <evolution input file name>";
  55. // Generations.
  56. int Generation;
  57. int Generations;
  58. // Steps.
  59. int Steps;
  60. // Step Game of Life?
  61. boolean StepGameOfLife;
  62. // Mox populations.
  63. EvolveCommon.MOX_POPULATIONS MoxPopulations;
  64. // Train foragers?
  65. boolean TrainForagers;
  66. // File names.
  67. ArrayList<String> CellsFileNames;
  68. String InputFileName;
  69. String OutputFileName;
  70. String LogFileName;
  71. PrintWriter LogWriter;
  72. // Random numbers.
  73. Random Randomizer;
  74. // Run with dashboard.
  75. boolean Dashboard;
  76. // Extract moxen files.
  77. boolean Extract;
  78. // Print population properties.
  79. boolean PrintProperties;
  80. // Print evolution statistics.
  81. boolean PrintStatistics;
  82. // Evolution statistics.
  83. double[] ForagerFittest;
  84. double[] ForagerAverage;
  85. double[] PredatorFittest;
  86. double[] PredatorAverage;
  87. // Maximum mox cycle time.
  88. long MaxMoxCycleTime;
  89. // Mox worlds.
  90. ArrayList<MoxWorld> moxWorlds;
  91. // Populations.
  92. EvolveCommon.Member[] ForagerPopulation;
  93. EvolveCommon.Member[] PredatorPopulation;
  94. // Constructor.
  95. public EvolveMoxen(String[] args)
  96. {
  97. int i;
  98. // Get options.
  99. Generation = 0;
  100. Generations = -1;
  101. Steps = -1;
  102. StepGameOfLife = false;
  103. boolean gotStepGameOfLife = false;
  104. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  105. TrainForagers = false;
  106. boolean gotMoxPopulations = false;
  107. CellsFileNames = new ArrayList<String>();
  108. InputFileName = OutputFileName = LogFileName = null;
  109. LogWriter = null;
  110. boolean gotMutationRate = false;
  111. boolean gotRandomMutationRate = false;
  112. boolean gotMaxSensorRange = false;
  113. boolean gotRandomSeed = false;
  114. Extract = false;
  115. PrintProperties = false;
  116. PrintStatistics = false;
  117. Dashboard = false;
  118. for (i = 0; i < args.length; i++)
  119. {
  120. if (args[i].equals("-generations"))
  121. {
  122. i++;
  123. if (i >= args.length)
  124. {
  125. System.err.println(Usage);
  126. System.exit(1);
  127. }
  128. Generations = Integer.parseInt(args[i]);
  129. if (Generations < 0)
  130. {
  131. System.err.println(Usage);
  132. System.exit(1);
  133. }
  134. continue;
  135. }
  136. if (args[i].equals("-steps"))
  137. {
  138. i++;
  139. if (i >= args.length)
  140. {
  141. System.err.println(Usage);
  142. System.exit(1);
  143. }
  144. Steps = Integer.parseInt(args[i]);
  145. if (Steps < 0)
  146. {
  147. System.err.println(Usage);
  148. System.exit(1);
  149. }
  150. continue;
  151. }
  152. if (args[i].equals("-stepGameOfLife"))
  153. {
  154. StepGameOfLife = true;
  155. gotStepGameOfLife = true;
  156. continue;
  157. }
  158. if (args[i].equals("-moxPopulations"))
  159. {
  160. i++;
  161. if (i >= args.length)
  162. {
  163. System.err.println(Usage);
  164. System.exit(1);
  165. }
  166. if (args[i].equals(EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getName()))
  167. {
  168. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  169. }
  170. else if (args[i].equals(EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getName()))
  171. {
  172. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS;
  173. }
  174. else
  175. {
  176. System.err.println(Usage);
  177. System.exit(1);
  178. }
  179. gotMoxPopulations = true;
  180. continue;
  181. }
  182. if (args[i].equals("-trainForagers"))
  183. {
  184. TrainForagers = true;
  185. continue;
  186. }
  187. if (args[i].equals("-loadCells"))
  188. {
  189. i++;
  190. if (i >= args.length)
  191. {
  192. System.err.println(Usage);
  193. System.exit(1);
  194. }
  195. CellsFileNames.add(new String(args[i]));
  196. continue;
  197. }
  198. if (args[i].equals("-input"))
  199. {
  200. i++;
  201. if (i >= args.length)
  202. {
  203. System.err.println(Usage);
  204. System.exit(1);
  205. }
  206. InputFileName = new String(args[i]);
  207. continue;
  208. }
  209. if (args[i].equals("-output"))
  210. {
  211. i++;
  212. if (i >= args.length)
  213. {
  214. System.err.println(Usage);
  215. System.exit(1);
  216. }
  217. OutputFileName = new String(args[i]);
  218. continue;
  219. }
  220. if (args[i].equals("-mutationRate"))
  221. {
  222. i++;
  223. if (i >= args.length)
  224. {
  225. System.err.println(Usage);
  226. System.exit(1);
  227. }
  228. EvolveCommon.MutationRate = Double.parseDouble(args[i]);
  229. if ((EvolveCommon.MutationRate < 0.0) || (EvolveCommon.MutationRate > 1.0))
  230. {
  231. System.err.println(Usage);
  232. System.exit(1);
  233. }
  234. gotMutationRate = true;
  235. continue;
  236. }
  237. if (args[i].equals("-randomMutationRate"))
  238. {
  239. i++;
  240. if (i >= args.length)
  241. {
  242. System.err.println(Usage);
  243. System.exit(1);
  244. }
  245. EvolveCommon.RandomMutationRate = Double.parseDouble(args[i]);
  246. if ((EvolveCommon.RandomMutationRate < 0.0) || (EvolveCommon.RandomMutationRate > 1.0))
  247. {
  248. System.err.println(Usage);
  249. System.exit(1);
  250. }
  251. gotRandomMutationRate = true;
  252. continue;
  253. }
  254. if (args[i].equals("-maxSensorRange"))
  255. {
  256. i++;
  257. if (i >= args.length)
  258. {
  259. System.err.println(Usage);
  260. System.exit(1);
  261. }
  262. EvolveCommon.MaxSensorRange = Float.parseFloat(args[i]);
  263. if (EvolveCommon.MaxSensorRange < 0.0f)
  264. {
  265. System.err.println(Usage);
  266. System.exit(1);
  267. }
  268. gotMaxSensorRange = true;
  269. continue;
  270. }
  271. if (args[i].equals("-randomSeed"))
  272. {
  273. i++;
  274. if (i >= args.length)
  275. {
  276. System.err.println(Usage);
  277. System.exit(1);
  278. }
  279. EvolveCommon.RandomSeed = Integer.parseInt(args[i]);
  280. gotRandomSeed = true;
  281. continue;
  282. }
  283. if (args[i].equals("-logfile"))
  284. {
  285. i++;
  286. if (i >= args.length)
  287. {
  288. System.err.println(Usage);
  289. System.exit(1);
  290. }
  291. LogFileName = new String(args[i]);
  292. continue;
  293. }
  294. if (args[i].equals("-dashboard"))
  295. {
  296. Dashboard = true;
  297. continue;
  298. }
  299. if (args[i].equals("-extract"))
  300. {
  301. Extract = true;
  302. continue;
  303. }
  304. if (args[i].equals("-properties"))
  305. {
  306. PrintProperties = true;
  307. continue;
  308. }
  309. if (args[i].equals("-statistics"))
  310. {
  311. PrintStatistics = true;
  312. continue;
  313. }
  314. System.err.println(Usage);
  315. System.exit(1);
  316. }
  317. // Extract moxen files or print properties?
  318. if (Extract || PrintProperties || PrintStatistics)
  319. {
  320. if ((Generations != -1) || (Steps != -1) || gotStepGameOfLife ||
  321. gotMoxPopulations || TrainForagers || (InputFileName == null) ||
  322. (OutputFileName != null) || (CellsFileNames.size() > 0) ||
  323. (LogFileName != null) || gotMutationRate || gotRandomMutationRate ||
  324. gotMaxSensorRange || gotRandomSeed || Dashboard)
  325. {
  326. System.err.println(Usage);
  327. System.exit(1);
  328. }
  329. if (Extract && (PrintProperties || PrintStatistics))
  330. {
  331. System.err.println(Usage);
  332. System.exit(1);
  333. }
  334. if (PrintProperties && (Extract || PrintStatistics))
  335. {
  336. System.err.println(Usage);
  337. System.exit(1);
  338. }
  339. if (PrintStatistics && (Extract || PrintProperties))
  340. {
  341. System.err.println(Usage);
  342. System.exit(1);
  343. }
  344. }
  345. else
  346. {
  347. if (Generations == -1)
  348. {
  349. System.err.println("Generations option required");
  350. System.err.println(Usage);
  351. System.exit(1);
  352. }
  353. if (Steps == -1)
  354. {
  355. System.err.println("Steps option required");
  356. System.err.println(Usage);
  357. System.exit(1);
  358. }
  359. if (OutputFileName == null)
  360. {
  361. System.err.println("Output file required");
  362. System.err.println(Usage);
  363. System.exit(1);
  364. }
  365. if (InputFileName != null)
  366. {
  367. if (gotMoxPopulations || (CellsFileNames.size() > 0))
  368. {
  369. System.err.println(Usage);
  370. System.exit(1);
  371. }
  372. }
  373. else
  374. {
  375. if (!gotMoxPopulations || (CellsFileNames.size() == 0))
  376. {
  377. System.err.println(Usage);
  378. System.exit(1);
  379. }
  380. }
  381. }
  382. // Set maximum sensor range.
  383. ForagerMox.MAX_SENSOR_RANGE = EvolveCommon.MaxSensorRange;
  384. PredatorMox.MAX_SENSOR_RANGE = EvolveCommon.MaxSensorRange;
  385. // Seed random numbers.
  386. Randomizer = new Random(EvolveCommon.RandomSeed);
  387. // Open log file?
  388. if (LogFileName != null)
  389. {
  390. try
  391. {
  392. LogWriter = new PrintWriter(new FileOutputStream(new File(LogFileName)));
  393. }
  394. catch (Exception e) {
  395. System.err.println("Cannot open log file " + LogFileName +
  396. ":" + e.getMessage());
  397. System.exit(1);
  398. }
  399. }
  400. }
  401. // Start evolve.
  402. public void start()
  403. {
  404. // Initialize populations?
  405. if (InputFileName == null)
  406. {
  407. init();
  408. }
  409. else
  410. {
  411. // Load populations.
  412. load();
  413. }
  414. // Log run.
  415. log("Initializing evolve:");
  416. log(" Options:");
  417. log(" generations=" + Generations);
  418. log(" steps=" + Steps);
  419. if (StepGameOfLife)
  420. {
  421. log(" stepGameOfLife=true");
  422. }
  423. else
  424. {
  425. log(" stepGameOfLife=false");
  426. }
  427. if (InputFileName == null)
  428. {
  429. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  430. {
  431. log(" MoxPopulations=" + EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getName());
  432. }
  433. else
  434. {
  435. log(" MoxPopulations=" + EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getName());
  436. }
  437. for (int i = 0; i < CellsFileNames.size(); i++)
  438. {
  439. log(" loadCells=" + CellsFileNames.get(i));
  440. }
  441. }
  442. else
  443. {
  444. log(" input=" + InputFileName);
  445. }
  446. log(" output=" + OutputFileName);
  447. log(" MutationRate=" + EvolveCommon.MutationRate);
  448. log(" RandomMutationRate=" + EvolveCommon.RandomMutationRate);
  449. log(" MaxSensorRange=" + EvolveCommon.MaxSensorRange);
  450. log(" RandomSeed=" + EvolveCommon.RandomSeed);
  451. log(" Parameters:");
  452. log(" FORAGER_FIT_POPULATION_SIZE=" + EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  453. log(" FORAGER_NUM_MUTANTS=" + EvolveCommon.FORAGER_NUM_MUTANTS);
  454. log(" FORAGER_NUM_OFFSPRING=" + EvolveCommon.FORAGER_NUM_OFFSPRING);
  455. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  456. {
  457. log(" PREDATOR_FIT_POPULATION_SIZE=" + EvolveCommon.PREDATOR_FIT_POPULATION_SIZE);
  458. log(" PREDATOR_NUM_MUTANTS=" + EvolveCommon.PREDATOR_NUM_MUTANTS);
  459. log(" PREDATOR_NUM_OFFSPRING=" + EvolveCommon.PREDATOR_NUM_OFFSPRING);
  460. }
  461. // Extract moxen files?
  462. if (Extract)
  463. {
  464. extract();
  465. return;
  466. }
  467. // Print population properties?
  468. if (PrintProperties)
  469. {
  470. printProperties();
  471. return;
  472. }
  473. // Print evolution statistics?
  474. if (PrintStatistics)
  475. {
  476. printStatistics();
  477. return;
  478. }
  479. // Set maximum mox cycle time according to current running conditions.
  480. MaxMoxCycleTime = Mox.getMaxCycleTime();
  481. // Evolution loop.
  482. log("Begin evolve:");
  483. for (Generations += Generation; Generation < Generations; Generation++)
  484. {
  485. log("Generation=" + Generation);
  486. evolve(Generation);
  487. // Save populations?
  488. if ((Generation % EvolveCommon.SAVE_FREQUENCY) == 0)
  489. {
  490. save(Generation);
  491. }
  492. }
  493. // Save populations.
  494. save(Generation - 1);
  495. log("End evolve");
  496. }
  497. // Initialize evolution.
  498. void init()
  499. {
  500. int i;
  501. MoxWorld moxWorld;
  502. moxWorlds = new ArrayList<MoxWorld>();
  503. for (i = 0; i < CellsFileNames.size(); i++)
  504. {
  505. try
  506. {
  507. moxWorld = new MoxWorld();
  508. moxWorld.loadCells(CellsFileNames.get(i));
  509. moxWorlds.add(moxWorld);
  510. if (i > 0)
  511. {
  512. if ((moxWorlds.get(0).getWidth() != moxWorld.getWidth()) ||
  513. (moxWorlds.get(0).getHeight() != moxWorld.getHeight()))
  514. {
  515. System.err.println("Dimensions in cells file " +
  516. CellsFileNames.get(i) +
  517. "must equal those in other cells files");
  518. System.exit(1);
  519. }
  520. }
  521. }
  522. catch (Exception e) {
  523. System.err.println("Cannot load cells file " +
  524. CellsFileNames.get(i) +
  525. ":" + e.getMessage());
  526. System.exit(1);
  527. }
  528. }
  529. ForagerPopulation = new EvolveCommon.Member[EvolveCommon.FORAGER_POPULATION_SIZE];
  530. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  531. {
  532. if (i == 0)
  533. {
  534. ForagerPopulation[i] =
  535. new EvolveCommon.Member(Mox.SPECIES.FORAGER.getValue(), 0,
  536. 0, 0, Mox.DIRECTION.NORTH.getValue(), Randomizer);
  537. }
  538. else
  539. {
  540. // Mutate parameters.
  541. ForagerPopulation[i] =
  542. new EvolveCommon.Member(ForagerPopulation[0], 0, Randomizer);
  543. }
  544. }
  545. ForagerFittest = new double[Generations + 1];
  546. ForagerAverage = new double[Generations + 1];
  547. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  548. {
  549. PredatorPopulation = new EvolveCommon.Member[EvolveCommon.PREDATOR_POPULATION_SIZE];
  550. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  551. {
  552. if (i == 0)
  553. {
  554. PredatorPopulation[i] =
  555. new EvolveCommon.Member(Mox.SPECIES.PREDATOR.getValue(), 0,
  556. moxWorlds.get(0).getWidth() - 1,
  557. moxWorlds.get(0).getHeight() - 1,
  558. Mox.DIRECTION.SOUTH.getValue(), Randomizer);
  559. }
  560. else
  561. {
  562. // Mutate parameters.
  563. PredatorPopulation[i] =
  564. new EvolveCommon.Member(PredatorPopulation[0], 0, Randomizer);
  565. }
  566. }
  567. PredatorFittest = new double[Generations + 1];
  568. PredatorAverage = new double[Generations + 1];
  569. }
  570. }
  571. // Load evolution.
  572. void load()
  573. {
  574. int i, n;
  575. FileInputStream input = null;
  576. NativeFileDescriptor fd = null;
  577. DataInputStream reader = null;
  578. MoxWorld moxWorld;
  579. // Open the file.
  580. try
  581. {
  582. input = new FileInputStream(new File(InputFileName));
  583. reader = new DataInputStream(input);
  584. fd = new NativeFileDescriptor(InputFileName, "r");
  585. fd.open();
  586. }
  587. catch (Exception e) {
  588. System.err.println("Cannot open input file " + InputFileName +
  589. ":" + e.getMessage());
  590. }
  591. try
  592. {
  593. Generation = Utility.loadInt(reader);
  594. Generation++;
  595. }
  596. catch (Exception e) {
  597. System.err.println("Cannot load from file " + InputFileName +
  598. ":" + e.getMessage());
  599. System.exit(1);
  600. }
  601. // Load mox world.
  602. moxWorlds = new ArrayList<MoxWorld>();
  603. try
  604. {
  605. n = Utility.loadInt(reader);
  606. for (i = 0; i < n; i++)
  607. {
  608. moxWorld = new MoxWorld();
  609. moxWorld.load(input, fd);
  610. moxWorlds.add(moxWorld);
  611. }
  612. }
  613. catch (Exception e) {
  614. System.err.println("Cannot load mox world from file " + InputFileName +
  615. ":" + e.getMessage());
  616. System.exit(1);
  617. }
  618. // Load populations.
  619. try
  620. {
  621. if (Utility.loadInt(reader) == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getValue())
  622. {
  623. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  624. }
  625. else
  626. {
  627. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS;
  628. }
  629. ForagerPopulation = new EvolveCommon.Member[EvolveCommon.FORAGER_POPULATION_SIZE];
  630. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  631. {
  632. ForagerPopulation[i] =
  633. new EvolveCommon.Member(Mox.SPECIES.FORAGER.getValue(), 0, 0, 0, 0, Randomizer);
  634. ForagerPopulation[i].load(input, fd);
  635. }
  636. ForagerFittest = new double[Generation + Generations + 1];
  637. ForagerAverage = new double[Generation + Generations + 1];
  638. for (i = 0; i < Generation; i++)
  639. {
  640. ForagerFittest[i] = Utility.loadDouble(reader);
  641. ForagerAverage[i] = Utility.loadDouble(reader);
  642. }
  643. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  644. {
  645. PredatorPopulation = new EvolveCommon.Member[EvolveCommon.PREDATOR_POPULATION_SIZE];
  646. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  647. {
  648. PredatorPopulation[i] =
  649. new EvolveCommon.Member(Mox.SPECIES.PREDATOR.getValue(), 0, 0, 0, 0, Randomizer);
  650. PredatorPopulation[i].load(input, fd);
  651. }
  652. PredatorFittest = new double[Generation + Generations + 1];
  653. PredatorAverage = new double[Generation + Generations + 1];
  654. for (i = 0; i < Generation; i++)
  655. {
  656. PredatorFittest[i] = Utility.loadDouble(reader);
  657. PredatorAverage[i] = Utility.loadDouble(reader);
  658. }
  659. }
  660. input.close();
  661. fd.close();
  662. }
  663. catch (Exception e) {
  664. System.err.println("Cannot load populations from file " + InputFileName +
  665. ":" + e.getMessage());
  666. System.exit(1);
  667. }
  668. }
  669. // Save evolution.
  670. void save(int generation)
  671. {
  672. int i, n;
  673. FileOutputStream output = null;
  674. NativeFileDescriptor fd = null;
  675. PrintWriter writer = null;
  676. try
  677. {
  678. output = new FileOutputStream(new File(OutputFileName));
  679. writer = new PrintWriter(output);
  680. fd = new NativeFileDescriptor(OutputFileName, "w");
  681. fd.open();
  682. }
  683. catch (Exception e) {
  684. System.err.println("Cannot open output file " + OutputFileName +
  685. ":" + e.getMessage());
  686. System.exit(1);
  687. }
  688. try
  689. {
  690. Utility.saveInt(writer, generation);
  691. writer.flush();
  692. }
  693. catch (Exception e) {
  694. System.err.println("Cannot save to file " + OutputFileName +
  695. ":" + e.getMessage());
  696. System.exit(1);
  697. }
  698. // Save mox world.
  699. try
  700. {
  701. n = moxWorlds.size();
  702. Utility.saveInt(writer, n);
  703. writer.flush();
  704. for (i = 0; i < n; i++)
  705. {
  706. moxWorlds.get(i).save(output, fd);
  707. }
  708. }
  709. catch (Exception e) {
  710. System.err.println("Cannot save mox world to file " + OutputFileName +
  711. ":" + e.getMessage());
  712. System.exit(1);
  713. }
  714. // Save populations.
  715. try
  716. {
  717. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  718. {
  719. Utility.saveInt(writer, EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getValue());
  720. }
  721. else
  722. {
  723. Utility.saveInt(writer, EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getValue());
  724. }
  725. writer.flush();
  726. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  727. {
  728. ForagerPopulation[i].save(output, fd);
  729. }
  730. writer.flush();
  731. for (i = 0, n = generation + 1; i < n; i++)
  732. {
  733. Utility.saveDouble(writer, ForagerFittest[i]);
  734. Utility.saveDouble(writer, ForagerAverage[i]);
  735. }
  736. writer.flush();
  737. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  738. {
  739. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  740. {
  741. PredatorPopulation[i].save(output, fd);
  742. }
  743. writer.flush();
  744. for (i = 0, n = generation + 1; i < n; i++)
  745. {
  746. Utility.saveDouble(writer, PredatorFittest[i]);
  747. Utility.saveDouble(writer, PredatorAverage[i]);
  748. }
  749. }
  750. writer.flush();
  751. output.close();
  752. fd.close();
  753. }
  754. catch (Exception e) {
  755. System.err.println("Cannot save populations to file " + OutputFileName +
  756. ":" + e.getMessage());
  757. System.exit(1);
  758. }
  759. }
  760. // Evolution generation.
  761. void evolve(int generation)
  762. {
  763. // Train foragers?
  764. if (TrainForagers)
  765. {
  766. trainForagers();
  767. }
  768. // Evaluate member fitness.
  769. evaluate(generation);
  770. // Prune unfit members.
  771. prune();
  772. // Create new members by mutation.
  773. mutate();
  774. // Create new members by mating.
  775. mate();
  776. }
  777. // Train foragers.
  778. void trainForagers()
  779. {
  780. int i, j, step;
  781. int blueFoodNeedIdx;
  782. Mox mox;
  783. ArrayList<Mox> moxen;
  784. MoxWorld moxWorld;
  785. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  786. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  787. {
  788. mox = ForagerPopulation[i].mox;
  789. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  790. moxen = new ArrayList<Mox>(1);
  791. moxen.add(0, mox);
  792. // Train mox in all mox worlds.
  793. ForagerPopulation[i].fitness = 0.0;
  794. for (j = 0; j < moxWorlds.size(); j++)
  795. {
  796. moxWorld = moxWorlds.get(j);
  797. moxWorld.setMoxen(moxen);
  798. moxWorld.reset();
  799. // Step world.
  800. if (Dashboard)
  801. {
  802. moxWorld.createDashboard();
  803. Dashboard = moxWorld.updateDashboard(0, Steps,
  804. "forager training" +
  805. ", member=" + i + ", mox=" + mox.id +
  806. ", world=" + j +
  807. ", blue food need=" +
  808. mox.getNeed(blueFoodNeedIdx));
  809. }
  810. for (step = 0; step < Steps; step++)
  811. {
  812. if (mox.getNeed(blueFoodNeedIdx) == 0.0)
  813. {
  814. break;
  815. }
  816. if (!mox.isAlive)
  817. {
  818. break;
  819. }
  820. setTrainingResponse(mox, moxWorld);
  821. moxWorld.stepMoxen();
  822. if (StepGameOfLife)
  823. {
  824. moxWorld.stepGameOfLife();
  825. }
  826. if (Dashboard)
  827. {
  828. Dashboard = moxWorld.updateDashboard(step + 1, Steps,
  829. "forager training" +
  830. ", member=" + i + ", mox=" + mox.id +
  831. ", world=" + j +
  832. ", blue food need=" +
  833. mox.getNeed(blueFoodNeedIdx));
  834. }
  835. }
  836. moxWorld.destroyDashboard();
  837. moxWorld.setMoxen(new ArrayList<Mox>());
  838. moxWorld.reset();
  839. }
  840. }
  841. }
  842. // Set mox training response.
  843. void setTrainingResponse(Mox mox, MoxWorld moxWorld)
  844. {
  845. int x, y, nx, ny, ex, ey, sx, sy, wx, wy, w, h;
  846. int d, dn, de, ds, dw;
  847. int blueFoodNeedIdx;
  848. boolean needBlueFood;
  849. // Locate adjacent cells.
  850. w = moxWorld.getWidth();
  851. h = moxWorld.getHeight();
  852. nx = mox.x;
  853. ny = ((mox.y + 1) % h);
  854. ex = (mox.x + 1) % w;
  855. ey = mox.y;
  856. sx = mox.x;
  857. sy = mox.y - 1;
  858. if (sy < 0) { sy += h; }
  859. wx = mox.x - 1;
  860. if (wx < 0) { wx += w; }
  861. wy = mox.y;
  862. // Get distance from goal to nearest adjacent cell.
  863. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  864. needBlueFood = false;
  865. if (mox.getNeed(blueFoodNeedIdx) > 0.0)
  866. {
  867. needBlueFood = true;
  868. }
  869. dn = de = ds = dw = -1;
  870. for (x = 0; x < w; x++)
  871. {
  872. for (y = 0; y < h; y++)
  873. {
  874. if ((moxWorld.gameOfLife.cells[x][y] == GameOfLife.BLUE_CELL_COLOR_VALUE) &&
  875. needBlueFood)
  876. {
  877. d = dist(x, y, nx, ny, w, h);
  878. if ((dn == -1) || (d < dn))
  879. {
  880. dn = d;
  881. }
  882. d = dist(x, y, ex, ey, w, h);
  883. if ((de == -1) || (d < de))
  884. {
  885. de = d;
  886. }
  887. d = dist(x, y, sx, sy, w, h);
  888. if ((ds == -1) || (d < ds))
  889. {
  890. ds = d;
  891. }
  892. d = dist(x, y, wx, wy, w, h);
  893. if ((dw == -1) || (d < dw))
  894. {
  895. dw = d;
  896. }
  897. }
  898. }
  899. }
  900. if (dn == -1)
  901. {
  902. return;
  903. }
  904. if (mox.direction == Mox.DIRECTION.NORTH.getValue())
  905. {
  906. if ((dn <= de) && (dn <= dw) && (dn <= ds))
  907. {
  908. mox.overrideResponse(Mox.RESPONSE_TYPE.FORWARD.getValue());
  909. }
  910. else if ((de <= dw) && (de <= ds))
  911. {
  912. mox.overrideResponse(Mox.RESPONSE_TYPE.RIGHT.getValue());
  913. }
  914. else
  915. {
  916. mox.overrideResponse(Mox.RESPONSE_TYPE.LEFT.getValue());
  917. }
  918. return;
  919. }
  920. else if (mox.direction == Mox.DIRECTION.EAST.getValue())
  921. {
  922. if ((de <= dn) && (de <= ds) && (de <= dw))
  923. {
  924. mox.overrideResponse(Mox.RESPONSE_TYPE.FORWARD.getValue());
  925. }
  926. else if ((ds <= dn) && (ds <= dw))
  927. {
  928. mox.overrideResponse(Mox.RESPONSE_TYPE.RIGHT.getValue());
  929. }
  930. else
  931. {
  932. mox.overrideResponse(Mox.RESPONSE_TYPE.LEFT.getValue());
  933. }
  934. return;
  935. }
  936. else if (mox.direction == Mox.DIRECTION.SOUTH.getValue())
  937. {
  938. if ((ds <= de) && (ds <= dw) && (ds <= dn))
  939. {
  940. mox.overrideResponse(Mox.RESPONSE_TYPE.FORWARD.getValue());
  941. }
  942. else if ((dw <= de) && (dw <= dn))
  943. {
  944. mox.overrideResponse(Mox.RESPONSE_TYPE.RIGHT.getValue());
  945. }
  946. else
  947. {
  948. mox.overrideResponse(Mox.RESPONSE_TYPE.LEFT.getValue());
  949. }
  950. return;
  951. }
  952. else
  953. {
  954. if ((dw <= dn) && (dw <= ds) && (dw <= de))
  955. {
  956. mox.overrideResponse(Mox.RESPONSE_TYPE.FORWARD.getValue());
  957. }
  958. else if ((dn <= ds) && (dn <= de))
  959. {
  960. mox.overrideResponse(Mox.RESPONSE_TYPE.RIGHT.getValue());
  961. }
  962. else
  963. {
  964. mox.overrideResponse(Mox.RESPONSE_TYPE.LEFT.getValue());
  965. }
  966. return;
  967. }
  968. }
  969. // City-block distance.
  970. int dist(int x1, int y1, int x2, int y2, int w, int h)
  971. {
  972. int d, dx, dy;
  973. dx = x2 - x1;
  974. if (dx < 0) { dx = -dx; }
  975. d = w - dx;
  976. if (d < dx) { dx = d; }
  977. dy = y2 - y1;
  978. if (dy < 0) { dy = -dy; }
  979. d = h - dy;
  980. if (d < dy) { dy = d; }
  981. d = dx + dy;
  982. return(d);
  983. }
  984. // Evaluate member fitnesses.
  985. void evaluate(int generation)
  986. {
  987. int i, j, step;
  988. int blueFoodNeedIdx, moxFoodNeedIdx;
  989. int moxFoodStep;
  990. Mox mox;
  991. long excessCycleTime;
  992. String logEntry;
  993. ArrayList<Mox> moxen;
  994. MoxWorld moxWorld;
  995. log("Evaluate:");
  996. // Prepare for evaluation.
  997. prepareEvaluation(generation);
  998. // Evaluate foragers.
  999. log(" Foragers:");
  1000. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  1001. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  1002. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  1003. {
  1004. // Set up mox world.
  1005. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1006. {
  1007. mox = ForagerPopulation[i].mox;
  1008. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1009. moxen = new ArrayList<Mox>(1);
  1010. moxen.add(0, mox);
  1011. }
  1012. else
  1013. {
  1014. // Set up mox world with random fit predator.
  1015. mox = PredatorPopulation[Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE)].mox;
  1016. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  1017. moxen = new ArrayList<Mox>(2);
  1018. moxen.add(0, mox);
  1019. mox = ForagerPopulation[i].mox;
  1020. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1021. moxen.add(1, mox);
  1022. }
  1023. // Evaluate mox in all mox worlds.
  1024. excessCycleTime = 0;
  1025. ForagerPopulation[i].fitness = 0.0;
  1026. for (j = 0; j < moxWorlds.size(); j++)
  1027. {
  1028. moxWorld = moxWorlds.get(j);
  1029. moxWorld.setMoxen(moxen);
  1030. moxWorld.reset();
  1031. // Step world.
  1032. if (Dashboard)
  1033. {
  1034. moxWorld.createDashboard();
  1035. Dashboard = moxWorld.updateDashboard(0, Steps,
  1036. "generation=" + generation +
  1037. ", member=" + i + ", mox=" + mox.id +
  1038. ", world=" + j +
  1039. ", blue food need=" +
  1040. mox.getNeed(blueFoodNeedIdx));
  1041. }
  1042. for (step = 0; step < Steps; step++)
  1043. {
  1044. mox.startCycleTimeAccumulation();
  1045. moxWorld.stepMoxen();
  1046. if (!mox.isAlive)
  1047. {
  1048. break;
  1049. }
  1050. if (mox.getNeed(blueFoodNeedIdx) == 0.0)
  1051. {
  1052. ForagerPopulation[i].fitness += 1.0 + (1.0 / (double)(step + 1));
  1053. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1054. }
  1055. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  1056. {
  1057. excessCycleTime = mox.getCycleTimeAccumulator();
  1058. break;
  1059. }
  1060. if (StepGameOfLife)
  1061. {
  1062. moxWorld.stepGameOfLife();
  1063. }
  1064. if (Dashboard)
  1065. {
  1066. Dashboard = moxWorld.updateDashboard(step + 1, Steps,
  1067. "generation=" + generation +
  1068. ", member=" + i + ", mox=" + mox.id +
  1069. ", world=" + j +
  1070. ", blue food need=" +
  1071. mox.getNeed(blueFoodNeedIdx));
  1072. }
  1073. }
  1074. moxWorld.destroyDashboard();
  1075. moxWorld.setMoxen(new ArrayList<Mox>());
  1076. moxWorld.reset();
  1077. }
  1078. logEntry = " member=" + i + ", " + ForagerPopulation[i].getInfo();
  1079. if (!mox.isAlive)
  1080. {
  1081. logEntry = logEntry + ", eaten";
  1082. }
  1083. if (excessCycleTime > 0)
  1084. {
  1085. logEntry = logEntry + ", excess cycle time=" + excessCycleTime;
  1086. }
  1087. log(logEntry);
  1088. }
  1089. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1090. {
  1091. return;
  1092. }
  1093. // Evaluate predators.
  1094. log(" Predators:");
  1095. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  1096. {
  1097. // Set up mox world with random fit prey.
  1098. mox = ForagerPopulation[Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE)].mox;
  1099. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1100. moxen = new ArrayList<Mox>(2);
  1101. moxen.add(0, mox);
  1102. mox = PredatorPopulation[i].mox;
  1103. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  1104. moxen.add(1, mox);
  1105. excessCycleTime = 0;
  1106. PredatorPopulation[i].fitness = 0.0;
  1107. for (j = 0; j < moxWorlds.size(); j++)
  1108. {
  1109. moxWorld = moxWorlds.get(j);
  1110. moxWorld.setMoxen(moxen);
  1111. moxWorld.reset();
  1112. // Step world.
  1113. if (Dashboard)
  1114. {
  1115. moxWorld.createDashboard();
  1116. Dashboard = moxWorld.updateDashboard(0, Steps,
  1117. "generation=" + generation +
  1118. ", member=" + i + ", mox=" + mox.id +
  1119. ", world=" + j +
  1120. ", mox food need=" +
  1121. mox.getNeed(moxFoodNeedIdx));
  1122. }
  1123. moxFoodStep = Steps;
  1124. for (step = 0; step < Steps; step++)
  1125. {
  1126. mox.startCycleTimeAccumulation();
  1127. moxWorld.stepMoxen();
  1128. if (mox.getNeed(moxFoodNeedIdx) == 0.0)
  1129. {
  1130. moxFoodStep = step;
  1131. break;
  1132. }
  1133. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  1134. {
  1135. excessCycleTime = mox.getCycleTimeAccumulator();
  1136. break;
  1137. }
  1138. if (StepGameOfLife)
  1139. {
  1140. moxWorld.stepGameOfLife();
  1141. }
  1142. if (Dashboard)
  1143. {
  1144. Dashboard = moxWorld.updateDashboard(step + 1, Steps,
  1145. "generation=" + generation +
  1146. ", member=" + i + ", mox=" + mox.id +
  1147. ", world=" + j +
  1148. ", mox food need=" +
  1149. mox.getNeed(moxFoodNeedIdx));
  1150. }
  1151. }
  1152. PredatorPopulation[i].fitness += (double)moxFoodStep;
  1153. moxWorld.destroyDashboard();
  1154. moxWorld.setMoxen(new ArrayList<Mox>());
  1155. moxWorld.reset();
  1156. }
  1157. logEntry = " member=" + i + ", " + PredatorPopulation[i].getInfo();
  1158. if (excessCycleTime > 0)
  1159. {
  1160. logEntry = logEntry + ", excess cycle time=" + excessCycleTime;
  1161. }
  1162. log(logEntry);
  1163. }
  1164. }
  1165. // Prepare new moxen for evaluation by giving them
  1166. // experience equivalent to existing moxen.
  1167. void prepareEvaluation(int generation)
  1168. {
  1169. int i, j, n, runs, step;
  1170. int blueFoodNeedIdx, moxFoodNeedIdx;
  1171. Mox mox;
  1172. ArrayList<Mox> moxen;
  1173. MoxWorld moxWorld;
  1174. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  1175. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  1176. log(" Preparing new moxen:");
  1177. // Catch up to current generation.
  1178. if (generation < EvolveCommon.MAX_PREPARATION_TRIALS)
  1179. {
  1180. runs = generation;
  1181. }
  1182. else
  1183. {
  1184. runs = EvolveCommon.MAX_PREPARATION_TRIALS;
  1185. }
  1186. for (n = 0; n < runs; n++)
  1187. {
  1188. log(" Run " + (n + 1) + " of " + runs);
  1189. // Run new foragers.
  1190. for (i = EvolveCommon.FORAGER_FIT_POPULATION_SIZE;
  1191. i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  1192. {
  1193. // Set up mox world.
  1194. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1195. {
  1196. mox = ForagerPopulation[i].mox;
  1197. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1198. moxen = new ArrayList<Mox>(1);
  1199. moxen.add(0, mox);
  1200. }
  1201. else
  1202. {
  1203. // Set up mox world with random fit predator.
  1204. mox = PredatorPopulation[Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE)].mox;
  1205. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  1206. moxen = new ArrayList<Mox>(2);
  1207. moxen.add(0, mox);
  1208. mox = ForagerPopulation[i].mox;
  1209. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1210. moxen.add(1, mox);
  1211. }
  1212. // Run mox in all mox worlds.
  1213. ForagerPopulation[i].fitness = 0.0;
  1214. for (j = 0; j < moxWorlds.size(); j++)
  1215. {
  1216. moxWorld = moxWorlds.get(j);
  1217. moxWorld.setMoxen(moxen);
  1218. moxWorld.reset();
  1219. // Step world.
  1220. for (step = 0; step < Steps; step++)
  1221. {
  1222. mox.startCycleTimeAccumulation();
  1223. moxWorld.stepMoxen();
  1224. if (!mox.isAlive)
  1225. {
  1226. break;
  1227. }
  1228. if (mox.getNeed(blueFoodNeedIdx) == 0.0)
  1229. {
  1230. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1231. }
  1232. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  1233. {
  1234. break;
  1235. }
  1236. if (StepGameOfLife)
  1237. {
  1238. moxWorld.stepGameOfLife();
  1239. }
  1240. }
  1241. moxWorld.destroyDashboard();
  1242. moxWorld.setMoxen(new ArrayList<Mox>());
  1243. moxWorld.reset();
  1244. }
  1245. }
  1246. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1247. {
  1248. continue;
  1249. }
  1250. // Run new predators.
  1251. for (i = EvolveCommon.PREDATOR_FIT_POPULATION_SIZE;
  1252. i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  1253. {
  1254. // Set up mox world with random fit prey.
  1255. mox = ForagerPopulation[Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE)].mox;
  1256. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1257. moxen = new ArrayList<Mox>(2);
  1258. moxen.add(0, mox);
  1259. mox = PredatorPopulation[i].mox;
  1260. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  1261. moxen.add(1, mox);
  1262. PredatorPopulation[i].fitness = 0.0;
  1263. for (j = 0; j < moxWorlds.size(); j++)
  1264. {
  1265. moxWorld = moxWorlds.get(j);
  1266. moxWorld.setMoxen(moxen);
  1267. moxWorld.reset();
  1268. // Step world.
  1269. for (step = 0; step < Steps; step++)
  1270. {
  1271. mox.startCycleTimeAccumulation();
  1272. moxWorld.stepMoxen();
  1273. if (mox.getNeed(moxFoodNeedIdx) == 0.0)
  1274. {
  1275. break;
  1276. }
  1277. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  1278. {
  1279. break;
  1280. }
  1281. if (StepGameOfLife)
  1282. {
  1283. moxWorld.stepGameOfLife();
  1284. }
  1285. }
  1286. moxWorld.destroyDashboard();
  1287. moxWorld.setMoxen(new ArrayList<Mox>());
  1288. moxWorld.reset();
  1289. }
  1290. }
  1291. }
  1292. log(" Preparation completed");
  1293. }
  1294. // Prune unfit members.
  1295. void prune()
  1296. {
  1297. double min, max, d;
  1298. int i, j, m;
  1299. EvolveCommon.Member member;
  1300. log("Select:");
  1301. log(" Foragers:");
  1302. EvolveCommon.Member[] fitPopulation =
  1303. new EvolveCommon.Member[EvolveCommon.FORAGER_FIT_POPULATION_SIZE];
  1304. max = 0.0;
  1305. for (i = 0; i < EvolveCommon.FORAGER_FIT_POPULATION_SIZE; i++)
  1306. {
  1307. m = -1;
  1308. for (j = 0; j < EvolveCommon.FORAGER_POPULATION_SIZE; j++)
  1309. {
  1310. member = ForagerPopulation[j];
  1311. if (member == null)
  1312. {
  1313. continue;
  1314. }
  1315. if ((m == -1) || (member.fitness > max))
  1316. {
  1317. m = j;
  1318. max = member.fitness;
  1319. }
  1320. }
  1321. member = ForagerPopulation[m];
  1322. ForagerPopulation[m] = null;
  1323. fitPopulation[i] = member;
  1324. log(" " + member.getInfo());
  1325. }
  1326. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  1327. {
  1328. if (ForagerPopulation[i] != null)
  1329. {
  1330. ForagerPopulation[i].clear();
  1331. ForagerPopulation[i] = null;
  1332. }
  1333. }
  1334. d = 0.0;
  1335. for (i = 0; i < EvolveCommon.FORAGER_FIT_POPULATION_SIZE; i++)
  1336. {
  1337. ForagerPopulation[i] = fitPopulation[i];
  1338. fitPopulation[i] = null;
  1339. d += ForagerPopulation[i].fitness;
  1340. }
  1341. ForagerFittest[Generation] = ForagerPopulation[0].fitness;
  1342. ForagerAverage[Generation] = d / (double)EvolveCommon.FORAGER_FIT_POPULATION_SIZE;
  1343. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1344. {
  1345. return;
  1346. }
  1347. log(" Predators:");
  1348. fitPopulation =
  1349. new EvolveCommon.Member[EvolveCommon.PREDATOR_FIT_POPULATION_SIZE];
  1350. min = 0.0;
  1351. for (i = 0; i < EvolveCommon.PREDATOR_FIT_POPULATION_SIZE; i++)
  1352. {
  1353. m = -1;
  1354. for (j = 0; j < EvolveCommon.PREDATOR_POPULATION_SIZE; j++)
  1355. {
  1356. member = PredatorPopulation[j];
  1357. if (member == null)
  1358. {
  1359. continue;
  1360. }
  1361. if ((m == -1) || (member.fitness < min))
  1362. {
  1363. m = j;
  1364. min = member.fitness;
  1365. }
  1366. }
  1367. member = PredatorPopulation[m];
  1368. PredatorPopulation[m] = null;
  1369. fitPopulation[i] = member;
  1370. log(" " + member.getInfo());
  1371. }
  1372. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  1373. {
  1374. if (PredatorPopulation[i] != null)
  1375. {
  1376. PredatorPopulation[i] = null;
  1377. }
  1378. }
  1379. d = 0.0;
  1380. for (i = 0; i < EvolveCommon.PREDATOR_FIT_POPULATION_SIZE; i++)
  1381. {
  1382. PredatorPopulation[i] = fitPopulation[i];
  1383. d += PredatorPopulation[i].fitness;
  1384. }
  1385. PredatorFittest[Generation] = PredatorPopulation[0].fitness;
  1386. PredatorAverage[Generation] = d / (double)EvolveCommon.PREDATOR_FIT_POPULATION_SIZE;
  1387. }
  1388. // Mutate members.
  1389. void mutate()
  1390. {
  1391. int i, j;
  1392. EvolveCommon.Member member, mutant;
  1393. log("Mutate:");
  1394. log(" Foragers:");
  1395. for (i = 0; i < EvolveCommon.FORAGER_NUM_MUTANTS; i++)
  1396. {
  1397. // Select a fit member to mutate.
  1398. j = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  1399. member = ForagerPopulation[j];
  1400. // Create mutant member.
  1401. mutant = new EvolveCommon.Member(member, member.generation + 1, Randomizer);
  1402. ForagerPopulation[EvolveCommon.FORAGER_FIT_POPULATION_SIZE + i] = mutant;
  1403. log(" member=" + j + ", " + member.getInfo() +
  1404. " -> member=" + (EvolveCommon.FORAGER_FIT_POPULATION_SIZE + i) +
  1405. ", " + mutant.getInfo());
  1406. }
  1407. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1408. {
  1409. return;
  1410. }
  1411. log(" Predators:");
  1412. for (i = 0; i < EvolveCommon.PREDATOR_NUM_MUTANTS; i++)
  1413. {
  1414. // Select a fit member to mutate.
  1415. j = Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE);
  1416. member = PredatorPopulation[j];
  1417. // Create mutant member.
  1418. mutant = new EvolveCommon.Member(member, member.generation + 1, Randomizer);
  1419. PredatorPopulation[EvolveCommon.PREDATOR_FIT_POPULATION_SIZE + i] = mutant;
  1420. log(" member=" + j + ", " + member.getInfo() +
  1421. " -> member=" + (EvolveCommon.PREDATOR_FIT_POPULATION_SIZE + i) +
  1422. ", " + mutant.getInfo());
  1423. }
  1424. }
  1425. // Produce offspring by melding parent parameters.
  1426. void mate()
  1427. {
  1428. int i, j, k;
  1429. EvolveCommon.Member member1, member2, offspring;
  1430. log("Mate:");
  1431. if (EvolveCommon.FORAGER_FIT_POPULATION_SIZE > 1)
  1432. {
  1433. log(" Foragers:");
  1434. for (i = 0; i < EvolveCommon.FORAGER_NUM_OFFSPRING; i++)
  1435. {
  1436. // Select a pair of fit members to mate.
  1437. j = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  1438. member1 = ForagerPopulation[j];
  1439. while ((k = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE)) == j) {}
  1440. member2 = ForagerPopulation[k];
  1441. // Create offspring.
  1442. offspring = new EvolveCommon.Member(member1, member2,
  1443. (member1.generation > member2.generation ?
  1444. member1.generation : member2.generation) + 1, Randomizer);
  1445. ForagerPopulation[EvolveCommon.FORAGER_FIT_POPULATION_SIZE +
  1446. EvolveCommon.FORAGER_NUM_MUTANTS + i] = offspring;
  1447. log(" member=" + j + ", " + member1.getInfo() + " + member=" +
  1448. k + ", " + member2.getInfo() +
  1449. " -> member=" + (EvolveCommon.FORAGER_FIT_POPULATION_SIZE +
  1450. EvolveCommon.FORAGER_NUM_MUTANTS + i) +
  1451. ", " + offspring.getInfo());
  1452. }
  1453. }
  1454. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1455. {
  1456. return;
  1457. }
  1458. if (EvolveCommon.PREDATOR_FIT_POPULATION_

Large files files are truncated, but you can click here to view the full file