PageRenderTime 64ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/mona/projects/mox/src/EvolveMoxenSystem.java

#
Java | 1330 lines | 1095 code | 144 blank | 91 comment | 206 complexity | 53bca48c8caf565b6356447d29d5a681 MD5 | raw file
  1. /*
  2. * Evolve a system of mox foragers and predators
  3. * by mutating and recombining parameters.
  4. */
  5. import java.util.*;
  6. import java.io.*;
  7. import mona.NativeFileDescriptor;
  8. public class EvolveMoxenSystem
  9. {
  10. // Usage.
  11. public static final String Usage =
  12. "Usage:\n" +
  13. " New run:\n" +
  14. " java EvolveMoxenSystem\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. " -loadCells <file name>\n" +
  21. " -output <evolution output file name>\n" +
  22. " [-mutationRate <mutation rate>]\n" +
  23. " [-randomMutationRate <random mutation rate>]\n" +
  24. " [-maxSensorRange <maximum sensor range>]\n" +
  25. " [-randomSeed <random seed> (for new run)]\n" +
  26. " [-logfile <log file name>]\n" +
  27. " [-dashboard (run with mox world dashboard)]\n" +
  28. " Resume run:\n" +
  29. " java EvolveMoxenSystem\n" +
  30. " -generations <evolution generations>\n" +
  31. " -steps <moxen steps>\n" +
  32. " [-stepGameOfLife]\n" +
  33. " -input <evolution input file name>\n" +
  34. " -output <evolution output file name>\n" +
  35. " [-mutationRate <mutation rate>]\n" +
  36. " [-randomMutationRate <random mutation rate>]\n" +
  37. " [-maxSensorRange <maximum sensor range>]\n" +
  38. " [-randomSeed <random seed> (for new run)]\n" +
  39. " [-logfile <log file name>]\n" +
  40. " [-dashboard (run with mox world dashboard)]\n" +
  41. " Extract into mox_world_forager|predator_<mox id>.mw files:\n" +
  42. " java EvolveMoxenSystem\n" +
  43. " -extract\n" +
  44. " -input <evolution input file name>\n" +
  45. " Print evolved property values:\n" +
  46. " java EvolveMoxenSystem\n" +
  47. " -print\n" +
  48. " -input <evolution input file name>";
  49. // Generations.
  50. int Generation;
  51. int Generations;
  52. // Steps.
  53. int Steps;
  54. // Step Game of Life?
  55. boolean StepGameOfLife;
  56. // Mox populations.
  57. EvolveCommon.MOX_POPULATIONS MoxPopulations;
  58. // File names.
  59. String CellsFileName;
  60. String InputFileName;
  61. String OutputFileName;
  62. String LogFileName;
  63. PrintWriter LogWriter;
  64. // Random numbers.
  65. Random Randomizer;
  66. // Run with dashboard.
  67. boolean Dashboard;
  68. // Extract moxen files.
  69. boolean Extract;
  70. // Print moxen property values.
  71. boolean PrintProperties;
  72. // Maximum mox cycle time.
  73. long MaxMoxCycleTime;
  74. // Mox world.
  75. MoxWorld moxWorld;
  76. // Populations.
  77. EvolveCommon.Member[] ForagerPopulation;
  78. EvolveCommon.Member[] PredatorPopulation;
  79. // Constructor.
  80. public EvolveMoxenSystem(String[] args)
  81. {
  82. int i;
  83. // Get options.
  84. Generation = 0;
  85. Generations = -1;
  86. Steps = -1;
  87. StepGameOfLife = false;
  88. boolean gotStepGameOfLife = false;
  89. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  90. boolean gotMoxPopulations = false;
  91. CellsFileName = null;
  92. InputFileName = OutputFileName = LogFileName = null;
  93. LogWriter = null;
  94. boolean gotMutationRate = false;
  95. boolean gotRandomMutationRate = false;
  96. boolean gotMaxSensorRange = false;
  97. boolean gotRandomSeed = false;
  98. Extract = false;
  99. PrintProperties = false;
  100. Dashboard = false;
  101. for (i = 0; i < args.length; i++)
  102. {
  103. if (args[i].equals("-generations"))
  104. {
  105. i++;
  106. if (i >= args.length)
  107. {
  108. System.err.println(Usage);
  109. System.exit(1);
  110. }
  111. Generations = Integer.parseInt(args[i]);
  112. if (Generations < 0)
  113. {
  114. System.err.println(Usage);
  115. System.exit(1);
  116. }
  117. continue;
  118. }
  119. if (args[i].equals("-steps"))
  120. {
  121. i++;
  122. if (i >= args.length)
  123. {
  124. System.err.println(Usage);
  125. System.exit(1);
  126. }
  127. Steps = Integer.parseInt(args[i]);
  128. if (Steps < 0)
  129. {
  130. System.err.println(Usage);
  131. System.exit(1);
  132. }
  133. continue;
  134. }
  135. if (args[i].equals("-stepGameOfLife"))
  136. {
  137. StepGameOfLife = true;
  138. gotStepGameOfLife = true;
  139. continue;
  140. }
  141. if (args[i].equals("-moxPopulations"))
  142. {
  143. i++;
  144. if (i >= args.length)
  145. {
  146. System.err.println(Usage);
  147. System.exit(1);
  148. }
  149. if (args[i].equals(EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getName()))
  150. {
  151. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  152. }
  153. else if (args[i].equals(EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getName()))
  154. {
  155. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS;
  156. }
  157. else
  158. {
  159. System.err.println(Usage);
  160. System.exit(1);
  161. }
  162. gotMoxPopulations = true;
  163. continue;
  164. }
  165. if (args[i].equals("-loadCells"))
  166. {
  167. i++;
  168. if (i >= args.length)
  169. {
  170. System.err.println(Usage);
  171. System.exit(1);
  172. }
  173. if (CellsFileName == null)
  174. {
  175. CellsFileName = new String(args[i]);
  176. }
  177. else
  178. {
  179. System.err.println(Usage);
  180. System.exit(1);
  181. }
  182. continue;
  183. }
  184. if (args[i].equals("-input"))
  185. {
  186. i++;
  187. if (i >= args.length)
  188. {
  189. System.err.println(Usage);
  190. System.exit(1);
  191. }
  192. InputFileName = new String(args[i]);
  193. continue;
  194. }
  195. if (args[i].equals("-output"))
  196. {
  197. i++;
  198. if (i >= args.length)
  199. {
  200. System.err.println(Usage);
  201. System.exit(1);
  202. }
  203. OutputFileName = new String(args[i]);
  204. continue;
  205. }
  206. if (args[i].equals("-mutationRate"))
  207. {
  208. i++;
  209. if (i >= args.length)
  210. {
  211. System.err.println(Usage);
  212. System.exit(1);
  213. }
  214. EvolveCommon.MutationRate = Double.parseDouble(args[i]);
  215. if ((EvolveCommon.MutationRate < 0.0) || (EvolveCommon.MutationRate > 1.0))
  216. {
  217. System.err.println(Usage);
  218. System.exit(1);
  219. }
  220. gotMutationRate = true;
  221. continue;
  222. }
  223. if (args[i].equals("-randomMutationRate"))
  224. {
  225. i++;
  226. if (i >= args.length)
  227. {
  228. System.err.println(Usage);
  229. System.exit(1);
  230. }
  231. EvolveCommon.RandomMutationRate = Double.parseDouble(args[i]);
  232. if ((EvolveCommon.RandomMutationRate < 0.0) || (EvolveCommon.RandomMutationRate > 1.0))
  233. {
  234. System.err.println(Usage);
  235. System.exit(1);
  236. }
  237. gotRandomMutationRate = true;
  238. continue;
  239. }
  240. if (args[i].equals("-maxSensorRange"))
  241. {
  242. i++;
  243. if (i >= args.length)
  244. {
  245. System.err.println(Usage);
  246. System.exit(1);
  247. }
  248. EvolveCommon.MaxSensorRange = Float.parseFloat(args[i]);
  249. if (EvolveCommon.MaxSensorRange < 0.0f)
  250. {
  251. System.err.println(Usage);
  252. System.exit(1);
  253. }
  254. gotMaxSensorRange = true;
  255. continue;
  256. }
  257. if (args[i].equals("-randomSeed"))
  258. {
  259. i++;
  260. if (i >= args.length)
  261. {
  262. System.err.println(Usage);
  263. System.exit(1);
  264. }
  265. EvolveCommon.RandomSeed = Integer.parseInt(args[i]);
  266. gotRandomSeed = true;
  267. continue;
  268. }
  269. if (args[i].equals("-logfile"))
  270. {
  271. i++;
  272. if (i >= args.length)
  273. {
  274. System.err.println(Usage);
  275. System.exit(1);
  276. }
  277. LogFileName = new String(args[i]);
  278. continue;
  279. }
  280. if (args[i].equals("-dashboard"))
  281. {
  282. Dashboard = true;
  283. continue;
  284. }
  285. if (args[i].equals("-extract"))
  286. {
  287. Extract = true;
  288. continue;
  289. }
  290. if (args[i].equals("-print"))
  291. {
  292. PrintProperties = true;
  293. continue;
  294. }
  295. System.err.println(Usage);
  296. System.exit(1);
  297. }
  298. // Extract moxen files or print properties?
  299. if (Extract || PrintProperties)
  300. {
  301. if ((Generations != -1) || (Steps != -1) || gotStepGameOfLife ||
  302. gotMoxPopulations || (InputFileName == null) ||
  303. (OutputFileName != null) || (CellsFileName != null) ||
  304. (LogFileName != null) || gotMutationRate || gotRandomMutationRate ||
  305. gotMaxSensorRange || gotRandomSeed || Dashboard)
  306. {
  307. System.err.println(Usage);
  308. System.exit(1);
  309. }
  310. if (Extract && PrintProperties)
  311. {
  312. System.err.println(Usage);
  313. System.exit(1);
  314. }
  315. }
  316. else
  317. {
  318. if (Generations == -1)
  319. {
  320. System.err.println("Generations option required");
  321. System.err.println(Usage);
  322. System.exit(1);
  323. }
  324. if (Steps == -1)
  325. {
  326. System.err.println("Steps option required");
  327. System.err.println(Usage);
  328. System.exit(1);
  329. }
  330. if (OutputFileName == null)
  331. {
  332. System.err.println("Output file required");
  333. System.err.println(Usage);
  334. System.exit(1);
  335. }
  336. if (InputFileName != null)
  337. {
  338. if (gotMoxPopulations || (CellsFileName != null))
  339. {
  340. System.err.println(Usage);
  341. System.exit(1);
  342. }
  343. }
  344. else
  345. {
  346. if (!gotMoxPopulations || (CellsFileName == null))
  347. {
  348. System.err.println(Usage);
  349. System.exit(1);
  350. }
  351. }
  352. }
  353. // Set maximum sensor range.
  354. ForagerMox.MAX_SENSOR_RANGE = EvolveCommon.MaxSensorRange;
  355. PredatorMox.MAX_SENSOR_RANGE = EvolveCommon.MaxSensorRange;
  356. // Seed random numbers.
  357. Randomizer = new Random(EvolveCommon.RandomSeed);
  358. // Open log file?
  359. if (LogFileName != null)
  360. {
  361. try
  362. {
  363. LogWriter = new PrintWriter(new FileOutputStream(new File(LogFileName)));
  364. }
  365. catch (Exception e) {
  366. System.err.println("Cannot open log file " + LogFileName +
  367. ":" + e.getMessage());
  368. System.exit(1);
  369. }
  370. }
  371. }
  372. // Start evolve.
  373. public void start()
  374. {
  375. // Initialize populations?
  376. if (InputFileName == null)
  377. {
  378. init();
  379. }
  380. else
  381. {
  382. // Load populations.
  383. load();
  384. }
  385. // Log run.
  386. log("Initializing evolve:");
  387. log(" Options:");
  388. log(" generations=" + Generations);
  389. log(" steps=" + Steps);
  390. if (StepGameOfLife)
  391. {
  392. log(" stepGameOfLife=true");
  393. }
  394. else
  395. {
  396. log(" stepGameOfLife=false");
  397. }
  398. if (InputFileName == null)
  399. {
  400. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  401. {
  402. log(" MoxPopulations=" + EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getName());
  403. }
  404. else
  405. {
  406. log(" MoxPopulations=" + EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getName());
  407. }
  408. log(" loadCells=" + CellsFileName);
  409. }
  410. else
  411. {
  412. log(" input=" + InputFileName);
  413. }
  414. log(" output=" + OutputFileName);
  415. log(" MutationRate=" + EvolveCommon.MutationRate);
  416. log(" RandomMutationRate=" + EvolveCommon.RandomMutationRate);
  417. log(" MaxSensorRange=" + EvolveCommon.MaxSensorRange);
  418. log(" RandomSeed=" + EvolveCommon.RandomSeed);
  419. log(" Parameters:");
  420. log(" FORAGER_FIT_POPULATION_SIZE=" + EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  421. log(" FORAGER_NUM_MUTANTS=" + EvolveCommon.FORAGER_NUM_MUTANTS);
  422. log(" FORAGER_NUM_OFFSPRING=" + EvolveCommon.FORAGER_NUM_OFFSPRING);
  423. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  424. {
  425. log(" PREDATOR_FIT_POPULATION_SIZE=" + EvolveCommon.PREDATOR_FIT_POPULATION_SIZE);
  426. log(" PREDATOR_NUM_MUTANTS=" + EvolveCommon.PREDATOR_NUM_MUTANTS);
  427. log(" PREDATOR_NUM_OFFSPRING=" + EvolveCommon.PREDATOR_NUM_OFFSPRING);
  428. }
  429. // Extract moxen files?
  430. if (Extract)
  431. {
  432. extract();
  433. return;
  434. }
  435. // Print moxen properties?
  436. if (PrintProperties)
  437. {
  438. printProperties();
  439. return;
  440. }
  441. // Set maximum mox cycle time according to current running conditions.
  442. MaxMoxCycleTime = Mox.getMaxCycleTime();
  443. // Evolution loop.
  444. log("Begin evolve:");
  445. for (Generations += Generation; Generation < Generations; Generation++)
  446. {
  447. log("Generation=" + Generation);
  448. evolve(Generation);
  449. // Save populations?
  450. if ((Generation % EvolveCommon.SAVE_FREQUENCY) == 0)
  451. {
  452. save(Generation);
  453. }
  454. }
  455. // Save populations.
  456. save(Generation - 1);
  457. log("End evolve");
  458. }
  459. // Initialize evolution.
  460. void init()
  461. {
  462. int i;
  463. try
  464. {
  465. moxWorld = new MoxWorld();
  466. moxWorld.loadCells(CellsFileName);
  467. }
  468. catch (Exception e) {
  469. System.err.println("Cannot load cells file " +
  470. CellsFileName +
  471. ":" + e.getMessage());
  472. System.exit(1);
  473. }
  474. ForagerPopulation = new EvolveCommon.Member[EvolveCommon.FORAGER_POPULATION_SIZE];
  475. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  476. {
  477. if (i == 0)
  478. {
  479. ForagerPopulation[i] =
  480. new EvolveCommon.Member(Mox.SPECIES.FORAGER.getValue(), 0,
  481. 0, 0, Mox.DIRECTION.NORTH.getValue(), Randomizer);
  482. }
  483. else
  484. {
  485. // Mutate parameters.
  486. ForagerPopulation[i] =
  487. new EvolveCommon.Member(ForagerPopulation[0], 0, Randomizer);
  488. }
  489. }
  490. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  491. {
  492. PredatorPopulation = new EvolveCommon.Member[EvolveCommon.PREDATOR_POPULATION_SIZE];
  493. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  494. {
  495. if (i == 0)
  496. {
  497. PredatorPopulation[i] =
  498. new EvolveCommon.Member(Mox.SPECIES.PREDATOR.getValue(), 0,
  499. moxWorld.getWidth() - 1,
  500. moxWorld.getHeight() - 1,
  501. Mox.DIRECTION.SOUTH.getValue(), Randomizer);
  502. }
  503. else
  504. {
  505. // Mutate parameters.
  506. PredatorPopulation[i] =
  507. new EvolveCommon.Member(PredatorPopulation[0], 0, Randomizer);
  508. }
  509. }
  510. }
  511. }
  512. // Load evolution.
  513. void load()
  514. {
  515. int i;
  516. FileInputStream input = null;
  517. NativeFileDescriptor fd = null;
  518. DataInputStream reader = null;
  519. // Open the file.
  520. try
  521. {
  522. input = new FileInputStream(new File(InputFileName));
  523. reader = new DataInputStream(input);
  524. fd = new NativeFileDescriptor(InputFileName, "r");
  525. fd.open();
  526. }
  527. catch (Exception e) {
  528. System.err.println("Cannot open input file " + InputFileName +
  529. ":" + e.getMessage());
  530. }
  531. try
  532. {
  533. Generation = Utility.loadInt(reader);
  534. Generation++;
  535. }
  536. catch (Exception e) {
  537. System.err.println("Cannot load from file " + InputFileName +
  538. ":" + e.getMessage());
  539. System.exit(1);
  540. }
  541. // Load mox world.
  542. try
  543. {
  544. moxWorld = new MoxWorld();
  545. moxWorld.load(input, fd);
  546. }
  547. catch (Exception e) {
  548. System.err.println("Cannot load mox world from file " + InputFileName +
  549. ":" + e.getMessage());
  550. System.exit(1);
  551. }
  552. // Load populations.
  553. try
  554. {
  555. if (Utility.loadInt(reader) == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getValue())
  556. {
  557. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY;
  558. }
  559. else
  560. {
  561. MoxPopulations = EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS;
  562. }
  563. ForagerPopulation = new EvolveCommon.Member[EvolveCommon.FORAGER_POPULATION_SIZE];
  564. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  565. {
  566. ForagerPopulation[i] =
  567. new EvolveCommon.Member(Mox.SPECIES.FORAGER.getValue(), 0, 0, 0, 0, Randomizer);
  568. ForagerPopulation[i].load(input, fd);
  569. }
  570. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  571. {
  572. PredatorPopulation = new EvolveCommon.Member[EvolveCommon.PREDATOR_POPULATION_SIZE];
  573. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  574. {
  575. PredatorPopulation[i] =
  576. new EvolveCommon.Member(Mox.SPECIES.PREDATOR.getValue(), 0, 0, 0, 0, Randomizer);
  577. PredatorPopulation[i].load(input, fd);
  578. }
  579. }
  580. input.close();
  581. fd.close();
  582. }
  583. catch (Exception e) {
  584. System.err.println("Cannot load populations from file " + InputFileName +
  585. ":" + e.getMessage());
  586. System.exit(1);
  587. }
  588. }
  589. // Save evolution.
  590. void save(int generation)
  591. {
  592. int i;
  593. FileOutputStream output = null;
  594. NativeFileDescriptor fd = null;
  595. PrintWriter writer = null;
  596. try
  597. {
  598. output = new FileOutputStream(new File(OutputFileName));
  599. writer = new PrintWriter(output);
  600. fd = new NativeFileDescriptor(OutputFileName, "w");
  601. fd.open();
  602. }
  603. catch (Exception e) {
  604. System.err.println("Cannot open output file " + OutputFileName +
  605. ":" + e.getMessage());
  606. System.exit(1);
  607. }
  608. try
  609. {
  610. Utility.saveInt(writer, generation);
  611. writer.flush();
  612. }
  613. catch (Exception e) {
  614. System.err.println("Cannot save to file " + OutputFileName +
  615. ":" + e.getMessage());
  616. System.exit(1);
  617. }
  618. // Save mox world.
  619. try
  620. {
  621. moxWorld.save(output, fd);
  622. }
  623. catch (Exception e) {
  624. System.err.println("Cannot save mox world to file " + OutputFileName +
  625. ":" + e.getMessage());
  626. System.exit(1);
  627. }
  628. // Save populations.
  629. try
  630. {
  631. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  632. {
  633. Utility.saveInt(writer, EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY.getValue());
  634. }
  635. else
  636. {
  637. Utility.saveInt(writer, EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS.getValue());
  638. }
  639. writer.flush();
  640. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  641. {
  642. ForagerPopulation[i].save(output, fd);
  643. }
  644. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  645. {
  646. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  647. {
  648. PredatorPopulation[i].save(output, fd);
  649. }
  650. }
  651. output.close();
  652. fd.close();
  653. }
  654. catch (Exception e) {
  655. System.err.println("Cannot save populations to file " + OutputFileName +
  656. ":" + e.getMessage());
  657. System.exit(1);
  658. }
  659. }
  660. // Evolution generation.
  661. void evolve(int generation)
  662. {
  663. // Evaluate member fitness.
  664. evaluate(generation);
  665. // Prune unfit members.
  666. prune();
  667. // Create new members by mutation.
  668. mutate();
  669. // Create new members by mating.
  670. mate();
  671. }
  672. // Evaluate member fitnesses.
  673. void evaluate(int generation)
  674. {
  675. int i, step;
  676. int blueFoodNeedIdx, moxFoodNeedIdx;
  677. Mox mox;
  678. ArrayList<Mox> moxen;
  679. log("Evaluate:");
  680. // Prepare for evaluation.
  681. prepareEvaluation();
  682. // Set up mox world.
  683. moxen = new ArrayList<Mox>();
  684. populateMoxen(moxen);
  685. moxWorld.setMoxen(moxen);
  686. moxWorld.reset();
  687. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  688. {
  689. ForagerPopulation[i].fitness = 0.0;
  690. }
  691. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  692. {
  693. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  694. {
  695. PredatorPopulation[i].fitness = 0.0;
  696. }
  697. }
  698. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  699. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  700. // Step world.
  701. if (Dashboard)
  702. {
  703. moxWorld.createDashboard();
  704. Dashboard = moxWorld.updateDashboard(0, Steps);
  705. }
  706. for (step = 0; step < Steps; step++)
  707. {
  708. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  709. {
  710. mox = ForagerPopulation[i].mox;
  711. mox.startCycleTimeAccumulation();
  712. }
  713. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  714. {
  715. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  716. {
  717. mox = PredatorPopulation[i].mox;
  718. mox.startCycleTimeAccumulation();
  719. }
  720. }
  721. // Step the moxen.
  722. moxWorld.stepMoxen();
  723. // Update forager fitness.
  724. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  725. {
  726. mox = ForagerPopulation[i].mox;
  727. if (mox.isAlive)
  728. {
  729. // Increase fitness when food found.
  730. if (mox.getNeed(blueFoodNeedIdx) == 0.0)
  731. {
  732. ForagerPopulation[i].fitness += 1.0;
  733. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  734. }
  735. // Kill sluggish mox?
  736. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  737. {
  738. mox.isAlive = false;
  739. }
  740. }
  741. }
  742. // Update predator fitness.
  743. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  744. {
  745. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  746. {
  747. mox = PredatorPopulation[i].mox;
  748. if (mox.isAlive)
  749. {
  750. // Increase fitness when food found.
  751. if (mox.getNeed(moxFoodNeedIdx) == 0.0)
  752. {
  753. PredatorPopulation[i].fitness += 1.0;
  754. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  755. }
  756. // Kill sluggish mox?
  757. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  758. {
  759. mox.isAlive = false;
  760. }
  761. }
  762. }
  763. }
  764. // Step the Game of Life.
  765. if (StepGameOfLife)
  766. {
  767. moxWorld.stepGameOfLife();
  768. }
  769. // Update dashboard?
  770. if (Dashboard)
  771. {
  772. Dashboard = moxWorld.updateDashboard(step + 1, Steps);
  773. }
  774. }
  775. moxWorld.destroyDashboard();
  776. moxWorld.setMoxen(new ArrayList<Mox>());
  777. moxWorld.reset();
  778. log(" Foragers:");
  779. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  780. {
  781. log(" member=" + i + ", " + ForagerPopulation[i].getInfo());
  782. }
  783. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  784. {
  785. log(" Predators:");
  786. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  787. {
  788. log(" member=" + i + ", " + PredatorPopulation[i].getInfo());
  789. }
  790. }
  791. }
  792. // Populate moxen.
  793. void populateMoxen(ArrayList<Mox> moxen)
  794. {
  795. int i, x, y, direction;
  796. int blueFoodNeedIdx, moxFoodNeedIdx;
  797. Mox mox;
  798. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  799. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  800. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  801. {
  802. mox = ForagerPopulation[i].mox;
  803. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  804. x = Randomizer.nextInt(moxWorld.getWidth());
  805. y = Randomizer.nextInt(moxWorld.getHeight());
  806. direction = Randomizer.nextInt(4);
  807. mox.setSpacialProperties(x, y, direction);
  808. moxen.add(mox);
  809. }
  810. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  811. {
  812. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  813. {
  814. mox = PredatorPopulation[i].mox;
  815. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  816. x = Randomizer.nextInt(moxWorld.getWidth());
  817. y = Randomizer.nextInt(moxWorld.getHeight());
  818. direction = Randomizer.nextInt(4);
  819. mox.setSpacialProperties(x, y, direction);
  820. moxen.add(mox);
  821. }
  822. }
  823. }
  824. // Prepare new moxen for evaluation by giving them
  825. // some experience before competing with existing moxen.
  826. void prepareEvaluation()
  827. {
  828. int i, step;
  829. int blueFoodNeedIdx, moxFoodNeedIdx;
  830. Mox mox;
  831. ArrayList<Mox> moxen;
  832. log(" Preparing new moxen");
  833. // Set up mox world.
  834. moxen = new ArrayList<Mox>();
  835. populateMoxen(moxen);
  836. moxWorld.setMoxen(moxen);
  837. moxWorld.reset();
  838. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  839. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  840. // Step world.
  841. for (step = 0; step < Steps; step++)
  842. {
  843. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  844. {
  845. mox = ForagerPopulation[i].mox;
  846. mox.startCycleTimeAccumulation();
  847. }
  848. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  849. {
  850. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  851. {
  852. mox = PredatorPopulation[i].mox;
  853. mox.startCycleTimeAccumulation();
  854. }
  855. }
  856. // Step the moxen.
  857. moxWorld.stepMoxen();
  858. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  859. {
  860. mox = ForagerPopulation[i].mox;
  861. if (mox.isAlive)
  862. {
  863. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  864. {
  865. mox.isAlive = false;
  866. }
  867. else
  868. {
  869. if (mox.getNeed(blueFoodNeedIdx) == 0.0)
  870. {
  871. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  872. }
  873. }
  874. }
  875. }
  876. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_AND_PREDATORS)
  877. {
  878. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  879. {
  880. mox = PredatorPopulation[i].mox;
  881. if (mox.isAlive)
  882. {
  883. if (mox.getCycleTimeAccumulator() > MaxMoxCycleTime)
  884. {
  885. mox.isAlive = false;
  886. }
  887. else
  888. {
  889. if (mox.getNeed(moxFoodNeedIdx) == 0.0)
  890. {
  891. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  892. }
  893. }
  894. }
  895. }
  896. }
  897. // Step the Game of Life.
  898. if (StepGameOfLife)
  899. {
  900. moxWorld.stepGameOfLife();
  901. }
  902. }
  903. moxWorld.setMoxen(new ArrayList<Mox>());
  904. moxWorld.reset();
  905. log(" Preparation completed");
  906. }
  907. // Prune unfit members.
  908. void prune()
  909. {
  910. double max;
  911. int i, j, m;
  912. EvolveCommon.Member member;
  913. log("Select:");
  914. log(" Foragers:");
  915. EvolveCommon.Member[] fitPopulation =
  916. new EvolveCommon.Member[EvolveCommon.FORAGER_FIT_POPULATION_SIZE];
  917. max = 0.0;
  918. for (i = 0; i < EvolveCommon.FORAGER_FIT_POPULATION_SIZE; i++)
  919. {
  920. m = -1;
  921. for (j = 0; j < EvolveCommon.FORAGER_POPULATION_SIZE; j++)
  922. {
  923. member = ForagerPopulation[j];
  924. if (member == null)
  925. {
  926. continue;
  927. }
  928. if ((m == -1) || (member.fitness > max))
  929. {
  930. m = j;
  931. max = member.fitness;
  932. }
  933. }
  934. member = ForagerPopulation[m];
  935. ForagerPopulation[m] = null;
  936. fitPopulation[i] = member;
  937. log(" " + member.getInfo());
  938. }
  939. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  940. {
  941. if (ForagerPopulation[i] != null)
  942. {
  943. ForagerPopulation[i].clear();
  944. ForagerPopulation[i] = null;
  945. }
  946. }
  947. for (i = 0; i < EvolveCommon.FORAGER_FIT_POPULATION_SIZE; i++)
  948. {
  949. ForagerPopulation[i] = fitPopulation[i];
  950. fitPopulation[i] = null;
  951. }
  952. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  953. {
  954. return;
  955. }
  956. log(" Predators:");
  957. fitPopulation =
  958. new EvolveCommon.Member[EvolveCommon.PREDATOR_FIT_POPULATION_SIZE];
  959. for (i = 0; i < EvolveCommon.PREDATOR_FIT_POPULATION_SIZE; i++)
  960. {
  961. m = -1;
  962. for (j = 0; j < EvolveCommon.PREDATOR_POPULATION_SIZE; j++)
  963. {
  964. member = PredatorPopulation[j];
  965. if (member == null)
  966. {
  967. continue;
  968. }
  969. if ((m == -1) || (member.fitness > max))
  970. {
  971. m = j;
  972. max = member.fitness;
  973. }
  974. }
  975. member = PredatorPopulation[m];
  976. PredatorPopulation[m] = null;
  977. fitPopulation[i] = member;
  978. log(" " + member.getInfo());
  979. }
  980. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  981. {
  982. if (PredatorPopulation[i] != null)
  983. {
  984. PredatorPopulation[i] = null;
  985. }
  986. }
  987. for (i = 0; i < EvolveCommon.PREDATOR_FIT_POPULATION_SIZE; i++)
  988. {
  989. PredatorPopulation[i] = fitPopulation[i];
  990. }
  991. }
  992. // Mutate members.
  993. void mutate()
  994. {
  995. int i, j;
  996. EvolveCommon.Member member, mutant;
  997. log("Mutate:");
  998. log(" Foragers:");
  999. for (i = 0; i < EvolveCommon.FORAGER_NUM_MUTANTS; i++)
  1000. {
  1001. // Select a fit member to mutate.
  1002. j = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  1003. member = ForagerPopulation[j];
  1004. // Create mutant member.
  1005. mutant = new EvolveCommon.Member(member, member.generation + 1, Randomizer);
  1006. ForagerPopulation[EvolveCommon.FORAGER_FIT_POPULATION_SIZE + i] = mutant;
  1007. log(" member=" + j + ", " + member.getInfo() +
  1008. " -> member=" + (EvolveCommon.FORAGER_FIT_POPULATION_SIZE + i) +
  1009. ", " + mutant.getInfo());
  1010. }
  1011. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1012. {
  1013. return;
  1014. }
  1015. log(" Predators:");
  1016. for (i = 0; i < EvolveCommon.PREDATOR_NUM_MUTANTS; i++)
  1017. {
  1018. // Select a fit member to mutate.
  1019. j = Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE);
  1020. member = PredatorPopulation[j];
  1021. // Create mutant member.
  1022. mutant = new EvolveCommon.Member(member, member.generation + 1, Randomizer);
  1023. PredatorPopulation[EvolveCommon.PREDATOR_FIT_POPULATION_SIZE + i] = mutant;
  1024. log(" member=" + j + ", " + member.getInfo() +
  1025. " -> member=" + (EvolveCommon.PREDATOR_FIT_POPULATION_SIZE + i) +
  1026. ", " + mutant.getInfo());
  1027. }
  1028. }
  1029. // Produce offspring by melding parent parameters.
  1030. void mate()
  1031. {
  1032. int i, j, k;
  1033. EvolveCommon.Member member1, member2, offspring;
  1034. log("Mate:");
  1035. if (EvolveCommon.FORAGER_FIT_POPULATION_SIZE > 1)
  1036. {
  1037. log(" Foragers:");
  1038. for (i = 0; i < EvolveCommon.FORAGER_NUM_OFFSPRING; i++)
  1039. {
  1040. // Select a pair of fit members to mate.
  1041. j = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE);
  1042. member1 = ForagerPopulation[j];
  1043. while ((k = Randomizer.nextInt(EvolveCommon.FORAGER_FIT_POPULATION_SIZE)) == j) {}
  1044. member2 = ForagerPopulation[k];
  1045. // Create offspring.
  1046. offspring = new EvolveCommon.Member(member1, member2,
  1047. (member1.generation > member2.generation ?
  1048. member1.generation : member2.generation) + 1, Randomizer);
  1049. ForagerPopulation[EvolveCommon.FORAGER_FIT_POPULATION_SIZE +
  1050. EvolveCommon.FORAGER_NUM_MUTANTS + i] = offspring;
  1051. log(" member=" + j + ", " + member1.getInfo() + " + member=" +
  1052. k + ", " + member2.getInfo() +
  1053. " -> member=" + (EvolveCommon.FORAGER_FIT_POPULATION_SIZE +
  1054. EvolveCommon.FORAGER_NUM_MUTANTS + i) +
  1055. ", " + offspring.getInfo());
  1056. }
  1057. }
  1058. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1059. {
  1060. return;
  1061. }
  1062. if (EvolveCommon.PREDATOR_FIT_POPULATION_SIZE > 1)
  1063. {
  1064. log(" Predators:");
  1065. for (i = 0; i < EvolveCommon.PREDATOR_NUM_OFFSPRING; i++)
  1066. {
  1067. // Select a pair of fit members to mate.
  1068. j = Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE);
  1069. member1 = PredatorPopulation[j];
  1070. while ((k = Randomizer.nextInt(EvolveCommon.PREDATOR_FIT_POPULATION_SIZE)) == j) {}
  1071. member2 = PredatorPopulation[k];
  1072. // Create offspring.
  1073. offspring = new EvolveCommon.Member(member1, member2,
  1074. (member1.generation > member2.generation ?
  1075. member1.generation : member2.generation) + 1, Randomizer);
  1076. PredatorPopulation[EvolveCommon.PREDATOR_FIT_POPULATION_SIZE +
  1077. EvolveCommon.PREDATOR_NUM_MUTANTS + i] = offspring;
  1078. log(" member=" + j + ", " + member1.getInfo() + " + member=" +
  1079. k + ", " + member2.getInfo() +
  1080. " -> member=" + (EvolveCommon.PREDATOR_FIT_POPULATION_SIZE +
  1081. EvolveCommon.PREDATOR_NUM_MUTANTS + i) +
  1082. ", " + offspring.getInfo());
  1083. }
  1084. }
  1085. }
  1086. // Extract moxen files.
  1087. void extract()
  1088. {
  1089. int i;
  1090. int blueFoodNeedIdx, moxFoodNeedIdx;
  1091. Mox mox;
  1092. String filename;
  1093. // Extract foragers.
  1094. blueFoodNeedIdx = ForagerMox.NEED_TYPE.BLUE_FOOD.getValue();
  1095. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  1096. {
  1097. // Set up mox world.
  1098. mox = ForagerPopulation[i].mox;
  1099. mox.setNeed(blueFoodNeedIdx, ForagerMox.BLUE_FOOD_NEED_VALUE);
  1100. ArrayList<Mox> moxen = new ArrayList<Mox>(1);
  1101. moxen.add(0, mox);
  1102. // Save mox world.
  1103. filename = "mox_world_forager_" + mox.id + ".mw";
  1104. moxWorld.setMoxen(moxen);
  1105. moxWorld.reset();
  1106. try
  1107. {
  1108. moxWorld.save(filename);
  1109. }
  1110. catch (Exception e) {
  1111. System.err.println("Cannot save mox world to file " + filename +
  1112. ":" + e.getMessage());
  1113. System.exit(1);
  1114. }
  1115. }
  1116. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1117. {
  1118. return;
  1119. }
  1120. // Extract predators.
  1121. moxFoodNeedIdx = PredatorMox.NEED_TYPE.MOX_FOOD.getValue();
  1122. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  1123. {
  1124. // Set up mox world.
  1125. mox = PredatorPopulation[i].mox;
  1126. mox.setNeed(moxFoodNeedIdx, PredatorMox.MOX_FOOD_NEED_VALUE);
  1127. ArrayList<Mox> moxen = new ArrayList<Mox>(1);
  1128. moxen.add(0, mox);
  1129. // Save mox world.
  1130. filename = "mox_world_predator_" + mox.id + ".mw";
  1131. moxWorld.setMoxen(moxen);
  1132. moxWorld.reset();
  1133. try
  1134. {
  1135. moxWorld.save(filename);
  1136. }
  1137. catch (Exception e) {
  1138. System.err.println("Cannot save mox world to file " + filename +
  1139. ":" + e.getMessage());
  1140. System.exit(1);
  1141. }
  1142. }
  1143. }
  1144. // Print moxen properties.
  1145. void printProperties()
  1146. {
  1147. int i;
  1148. System.out.println("Moxen properties:");
  1149. // Print foragers.
  1150. System.out.println("=============================");
  1151. System.out.println("Foragers:");
  1152. for (i = 0; i < EvolveCommon.FORAGER_POPULATION_SIZE; i++)
  1153. {
  1154. System.out.println("-----------------------------");
  1155. ForagerPopulation[i].printProperties();
  1156. }
  1157. if (MoxPopulations == EvolveCommon.MOX_POPULATIONS.FORAGERS_ONLY)
  1158. {
  1159. return;
  1160. }
  1161. // Print predators.
  1162. System.out.println("=============================");
  1163. System.out.println("Predators:");
  1164. for (i = 0; i < EvolveCommon.PREDATOR_POPULATION_SIZE; i++)
  1165. {
  1166. System.out.println("-----------------------------");
  1167. PredatorPopulation[i].printProperties();
  1168. }
  1169. }
  1170. // Logging.
  1171. void log(String message)
  1172. {
  1173. if (LogWriter != null)
  1174. {
  1175. LogWriter.println(message);
  1176. LogWriter.flush();
  1177. }
  1178. }
  1179. // Main.
  1180. public static void main(String[] args)
  1181. {
  1182. EvolveMoxenSystem evolveMoxenSystem = new EvolveMoxenSystem(args);
  1183. evolveMoxenSystem.start();
  1184. System.exit(0);
  1185. }
  1186. }