The purpose of this project is to create a "primordial soup" with only a few fixed parameters from which economic behavior may emerge. Agents learn what to produce, who to trade with, what to trade and how much all at the same time. Knowledge of any of these enables knowledge of the others, so that division of labor, money, social networks of trade, ideal types, prices and production efforts all push each other in positive feedback, just as the first life self-organized. As these things push each other, society goes through stages from individual production of most needs to barter of a few goods, to barter of many as their trade networks mature. The fuel behind this self organization is not natural selection, but symbolic interactionism. As agents read and display signs, the structures of society unfold. They socially construct their world through their schema: through self-fulfilling prophecy they form ideal types. Even though natural selection was used as the inductive method on a lower level of description, the higher level symbolic interactionism is a method of self organization which is distinct from natural selection, is more cooperative does not depend on death.
This project is encoded in Smalltalk on top of Kevin Lacobie's Agora. This program takes about three days to do 200 cycles on an IBM486 DX75 when only ten agents are used. In each cycle, agents produce according to their production plans, trade according to their trade plans, and evaluate their plans 100 times, or once for each chromosome in their genetic algorithm. Each agent is given a limited number of efforts which his genetic algorithm tells him how to spend. He can spend efforts on producing or trading one or more of the goods. The goods are defined by the fixed parameters of how much effort each takes to produce and by their utility function coefficient. I did not always use the utility function coefficient: I used to define them by how many are needed to satisfy in relation to each other instead, and this should eventually be put back into the program as an emergent rather than a fixed parameter. Eventually, how many goods are needed to satisfy should come to differ as a division of labor emerges, and efforts required to make each good should change as technology emerges. For now, these fixed parameters may be changed to see what happens to the price of the goods, and to see which is more likely to become money.
Agents may do what they wish with their efforts, but if they choose to concentrate their efforts on production of fewer of the goods they will be able to make more of them. This is to model economies of scale: for now I resorted to raising the goods to a fixed parameter exponent, but again we should emerge the "why" behind the economies of scale in the future. I thought that economies of scale combined with the principle of complementation should explain trade: the agents would be more satisfied if they concentrated their efforts on one of the goods and traded them away then if they made all the goods on their own.
Part of their learning of economic behavior is learning who to trade with, so I had each agent display a sign to represent himself, and each agent form in its mind the type of sign it might look for to perform a particular kind of trade. With this sign they would develop concepts of people, or ideal types. They would see each other only through the signs, and would learn to behave with each other in understandable ways in self-fulfilling prophecy because of the signs. Agents find it to their utility to expect others to do what they need and to act as others expect: from this emerges a synchronous division of labor. It will be interesting to see where the producers and traders might be in relation to each other: I plan to simulate this by increasing the cost of trade with distance needed to trade. It would also be very interesting to see the dialects of signs that would evolve over distance. For now, the cost of trade is a fixed parameter for all trade, but it should be changed later with distance and the type of good.
The chromosomes are long, containing encodings for what activities an agent is to put his efforts into ( production or trade), encodings for trade plans, and encodings for signs. Class Chromosome contains these encodings in class ChromosomeSection, with inheritance classes ProductionSection, TradeSection and SignSection for each type of encoding. Having these chromosome sections facilitates varying numbers of trades, goods and signs. The bits of each unit of encoding must fit into a 16 bit integer.
The agents each have a limited number of efforts to put into their activities in every cycle. The ProductionSections represent the efforts, with 4 efforts per section in the most recent version. This allows 4 bits to tell what to devote each effort to. In the most recent version of the program, the first of the four bits indicate whether the effort is devoted to production or trade. If it is devoted to production, the remaining 3 bits are used to denote which one of the (maximum 8) goods to produce. If the effort is devoted to trade, the remaining 3 bits tell which of the (maximum 8) trade sections that this effort was devoted to. The more efforts devoted to a trade the more it may performed in a cycle, and the more distant traders may be used (this is not yet implemented).
The TradeSections encode a good and an amount to trade for a good and an amount, and a sign to look for in another agent to ask to trade it with. I thought it was intuitive to have what someone would accept in trade be the same thing as what someone might offer in trade so that the offer and the offeree strategies are the same. The only nonsymetry between offerer and offeree is that the offerer spends his effort to make the trade and looks for the sign in the trade while an offeree accepts a trade if it is in his trade plans regardless of sign. What is given and what is received is the same regardless of whether it is offered to or an offer from another agent. To fit this into 16 bits, 3 are used for each good and 3 for each amount, and 4 for the sign to look for. As for the sign sections, as of this time only the last four bits are used for displaying to others to attract offers of trade.
A chromosome is more fit if, in the consumption stage, it has a combination of goods of a higher utility. At first I wrote my own utility function, which I likened to a game of tetras. Agents would be rewarded only if they had a certain amount of each good - for example, with the four food groups, it would be 4, 4, 3 and 2. They would be rewarded more for more complete packets - for example, 8, 8, 6 and 4 units of goods, but they would not be rewarded for partial packets. This is to simulate the nonlinearity of goods, that because they affect each other, the whole is the greater than the sum of the parts. However, it turns out that not rewarding a little for partial packets makes a function which is more difficult for the GA to learn. I wanted to help it along by giving it a little hard coded foresight that if you have a partial packet, you might more easily get an entire packet later. Not that GA's or other mechanisms can not display foresight: it probably can but I don't want to wait weeks to find out.
In pursuit upon a smoother, GA-easy version of the tetras game I realized that Kevin Lacobie's Cobb-Douglas utility function is precisely the one needed. In this discovery I learned a little Economics 101: a utility function tells us that there are interactions between goods without telling us what they are. It explains trade because every type of good is needed in certain amounts to make a different interaction, and different utility coefficients among agents represent different interactions between the goods. It would eventually be better to simulate the interactions of the goods themselves, coming from the division of labor, rather than using the mathematical model of it which the utility function is. For example, someone who produces software needs diskettes more than he needs a tractor, but it is better to simulate this by the process of production than by assigning a higher utility coefficient for diskettes than for tractors. One good reason for doing it this way is that an emergent utility function can change: the parameters would not be fixed.
This project uses a method of coevolution which I developed to evaluate the fitness of the chromosomes. In the latest version of the program, each agent has 100 chromosomes. In every cycle, all of the first chromosomes interact together and are given their fitness values through their interaction, then all of the second chromosomes interact, independently of the first, and so on through the 100th set. Only after all of the fitnesses are evaluated does the reproduction occur. Offspring are replaced arbitrarily back into the slots so that the results of interactions are combined in each agent. My coevolutionary method of fitness evaluation is similar to that of classifier systems in that many "moves" are made before a reproduction occurs, but it is different in that every chromosome is evaluated the same number of times before their worlds are combined. In fact, Mike Goodloe in our class actually did use a classifier-system method for fitness evaluation with my trade section knowledge representation, even though my representation does not have the alleles for default hierarchy or if-then portions. The only differences between Mike's program and mine are the fitness evaluation method and its integration with Agora. Mike's program uses the cellular automata for knowing who to trade with and Agora's method of production, while my requirement of being a "primordial soup" where all emerges together made integration difficult.
I did not integrate into Agora more because I wanted to be very careful about the apportionment of credit in the fitness evaluation. At this time, agents must begin each cycle with producing something, then make a limited number of trades ( usually 8), and then consume all goods at the end of the cycle. This is so that chromosomes are rewarded only for what they are responsible for: if the chromosome did not cause the inventory by itself then it should not be rewarded for it. At one time I thought of scraping my design and changing to a true classifier system with competing if-then rules, a default hierarchy, a bucket brigade and a blackboard system solely for the purpose of looking into the inventory. This would facilitate inventory accumulation which is important because without it there will be no pure distributors. With a classifier system, the chromosome would not have to be responsible for the inventory, but could just look at its state. This would allow more encapsulation and integration, while hopefully still retaining the "all evolving together" qualities of a "primordial soup". This program would certainly benefit from integration with Agora in the future, particularly when it is time to add spatial factors in.
This program uses DeJong's even point crossover, to unbias the chromosome. For most of my runs I used 4 points because of the length of the chromosome. Crossover was not done inside alleles for type of good: I thought that this would cause an unnecessary epistasis. Crossover was allowed inside amounts and signs, which are all gray coded to make them easier for the GA to learn. Mutation was set at a low 0.002 most of the time, and was allowed on any bit in the string. In the future alleles should be considered in the mutation function to unbias it. Although keeping diversity is important in coevolution, particularly in a simulation with stages where what is fit always changes, I did not use the operators such as diploidy which Hillis used in his coevolutionary programs (see Alife II). Instead, I used a long gene string with many unused portions that are switched on by other parts of the gene string. In most runs I used 8 trade sections, but only three or four of them were used by the agents at any one time. Invariably, those that were used would lose their diversity while those that were unused would gain it through mutation. The switching occurred through the effort encodings in the ProductionSection. This "gene switching" method is like diploidy, but good for varying the number of possible moves, in this case, varying the number of trades.
Who may reproduce is controlled by the choice function described in my Master's thesis. This reproduction method augments the annealing that naturally emerges from genetic algorithms. The ChoiceDistribution class anneals choices of who can reproduce. Which chromosomes reproduce in the beginning of the run is less dependent on fitness and are chosen more by random than chromosomes later in the run. This performs the same function as DeJong's linearization of reproduction (Goldberg) : it ensures that diversity is not destroyed early on by chromosomes that are by chance much more fit, and also differentiates chromosomes that are about the same fitness later in the simulation. This method looks at linearization in a different way: of the methods I have introduced with this simulation, this is the most unsure, and must be tested. The danger of it is the loss of diversity towards the "end". Of course with coevolution there is not supposed to be an "end", so I may replace this with DeJong's linearization function.
This is a description of a run with the following parameter settings: 10 agents, 100 chromosomes each, 4 goods, 4 different amounts of those goods to learn, 8 efforts given to each agent , 0 efforts required to trade, 1 effort required to make each good, utility coefficient of .25 for each good (all goods are the same), 8 trades possible in the chromosomes, 4 point crossover, 0.002 mutation rate, annealing of choice function from 1.0 to -1.0 in increments of 0.001. The number of goods are cubed in the production process, to simulate economies of scale, and the possible amounts to trade of the goods are 12, 24, 36, and 48. I will try to depict the developments of symbols that take place every 25 runs, although record of the entire run may be found in file success5.dat. These descriptions contain averages which are based on scenarios. A scenario is the interactions of the traders coming from just 1 of their 100 genes. There are 100 scenarios per cycle.
Cycle 1. The random genes made an average production of 71.6 goods per scenario, with even distribution among goods. The corresponding trade plans were close to their expected value of 0.5, meaning that only half of the agents had a plan which was the same as a plan in another agent (In the agents that looked like they would have that plan, to be exact). The average trade was at .02, meaning that there was a trade about every 5 scenarios. By chance, what little trade there was increased the average utility by 0.1 in this utility function. post trade utility was 6.44, with this function, which I state for comparative purposes. There are no trades, trade plans, signs or production plans that happened over 20 cycles per scenario to be of any significance.
Cycle 25. Production has actually decreased to an average of 68.8 goods per scenario, even though the average post trade utility has increased to 7.95. This is because the individual farmers, in the absence of knowledge of who to trade with, have found it in their benefit to produce all of their goods themselves. Concentrating their efforts on a few goods, in the absence of trade, does them no good. Although they make less goods when they make them all themselves, they are more satisfied. About 4 of them had the majority of their chromosomes indicating 4 efforts concentrated on 1 good, and 6 had 3 at the most concentrated. They learned to take advantage of a the way this utility function was implemented: if there is none of one of the goods, it defaults to having one of the good. 7 agents have 0 of one of the good. The amount of trade and corresponding plans is the same as it was in cycle 1, that expected by chance.
Cycle 50. The trend towards learning not to trade continues as production decreases to 67.84 goods per scenario and post trade utility increases to 8.45, for the same reasons. Every agent has 0 of one of the goods. There is no increase in trade, utility attributed to trade, or corresponding plans.
Cycle 75. The agents are just beginning to learn to trade. Post trade utility has increased to 8.75, with trade accounting for 0.35 of that. One trade, with a fair price according to the utility ratios has occurred more than 20 times. A little more than half of the scenarios have a trade. Production is down to 66.68, because the agents have maximally spread out their efforts over production of the 4 goods. Every agent produces 0 of one good 2 of one good, and 3 of 2 goods to give them the maximal utility under no trade. There seems to be more zeros in goods 1 and 3 than in 2 and 4 by coincidence.
Cycle 100. As trade becomes more important, production rises to 69.12 goods per scenario. There is now about a trade and a half every scenario. Post trade utility is up to 9.67 with 1.35 of this attributed to trade. Corresponding plans are up to 0.6, above what is expected by chance as they are selected for. Of the 4 trade plans occurring in more than 20 chromosomes ( in three different agents), all contained 24 units of 4 in the trade. Two of the agents who had trade chromosomes selected for trade concentrated 4 of their efforts on one of the goods, something which would give them lower utility had they not had a trade. The use of the unit 4 and the package of 24 that it comes in is a symbol in the environment, because 3 different agents found it useful synchronously, yet it is not money because it is not used for trade but consumption. It would be money if someone traded something for the good 4, then good 4 for something else.
Cycle 125. Production is up to 79.73 goods per scenario, but half of that is devoted to producing good 4. There are 3 trades every scenario, meaning that about 6 of the 10 agents participate in a trade. Just about everyone has a corresponding trade plan with someone else ( but some of these did not have the inventory to make the trade). Every one of these trades involves good 4. Yet the agents were able to increase their utility by trading in good 4: the average post trade utility is now 12.2, with 4.3 of this attributed to trade. Of the 5 trades that were recorded as having occurred more than 20 times, 4 were even trades according to the utility parameters. This is no artifact of the simulation, but an actual emergent price: there is only one chance in 4 that a single trade would be the same price. Of those 5 trades, 4 involved good 1. It is significant that the agents have now adapted to each other, adopting a common behavior, in order to increase their utility.
Cycle 150. Average post trade utility is up to 15.24, with 7.74 (half) of that attributed to trade. Agents engage in a trade or two each scenario, and have a 1 or 2 corresponding plans with another agent. Yet they are still trading mostly goods 4 and 1, with some of good 2 in there. Of the 14 trades recorded as having occurred more than 20 times, 13 involved good 4, 13 involved good 1, and 2 involved good 2. Only one of these trades was uneven, meaning this model is very good at emerging price. Again, these trades do not involve money because the goods always contribute to immediate utility. Production is up to 101.18, with over 2/3 of this devoted to producing goods 1 and 4. One tenth of this production is devoted to good 3, which is not involved in trade. There have come to be, on the whole, two types of agents: those that trade 4 for 1 and those that trade 1 for 4. 8 out of 10 agents have either 4 or 5 efforts devoted on one of these two goods, which would be against their utility in the absence of trade. However, agent 8 has become an entrepreneur, and has decided to concentrate his production on good 2 and approach both producers of 4 and 1 with offers to augment their lack of 2, getting back either 1 or 4. To get both kinds of goods, he even accepted an uneven amount of good 1, giving 24 of 2 for 12 of 1. This agent, although an entrepreneur, is not more creative than the other agents, nor did he have greater vision, nor do the other agents copy more than he: he was just lucky. All agents do what is best for themselves under their circumstance.
These traders identify each other through signs. I have set it up so that this is the only way they can know each other, but I myself can not read their signs. There is no homomorphism in these signs: they are extremely fuzzy and unknowable like the weights inside a neural network. If they were not, then there could never be any new trade: for example, if there was a sign that meant only " I give away 4" or "I give away 1" , then trader 8 couldn't find agents who did either yet still had deficits in good 2. This fuzzy knowledge representation enables change. Because I used hamming distance, the signs are a compromise of what is significant to tell for each individual agent.
Cycle 175. Average post trade utility is 16.29, 8.92 of which is attributed to trade. Trade and corresponding plans have increased a little bit, to an average of 1.347 corresponding plans per agent per scenario, and actual trades of 0.737 per agent per scenario. and production is up to 111.884. Agent 8 has found yet another customer for his good 2's, yet we still have a 1 and 4 world. Out of 14 trades, good 1 was involved in 11 of them, good 4 was involved in 12 of them, and good 2 was involved in 3 of them. There was only one uneven trade.
Cycle 200. Strangely, trade decreased in this cycle to 0.636 per agent per scenario, and 1.347 corresponding plans per agent per scenario. Yet utility increased to 16.89, and production increased to 135.1 as the traders evened out their types of trade. Of the 8 trades that occurred more than 20 times in a cycle, good 2 was in 4 of them, good 4 was in 6 of them, and good 1 was in 6 of them. It seems that more effort is put into making good 3, which means that it is more part of the environment to trade, and may have become part of the trading had this file not ended at cycle 207. File success4.dat, with 243 cycles, has an evolution of trading types from 2 types of trade to all 4.
Presented with the difficult task of developing synchronous trade plans, certain types of trade become established and common. A type of trade becomes possible by a process like this: Two agents who happen to have an idea for a trade in their plans and happen to have the goods in the inventory to make it, and it happens to benefit the two. This section of their chromosome thus increases in frequency, for these two, yet this trade is not private between them. This is because the trade is in their trade plan for another agent to offer to. As another agent happens to have the same plan and offers it, and if it is good for him and he keeps it, the trade will become more popular. However, the trade does not only become popular because it is good for the agents. In a sense it becomes more popular because it is there. It's existence as part of the environment makes it something agents must adjust to, the more popular it becomes. Because it is there, it is in the best interests of the agents to make it good for them, if it is not already. The more popular a type of trade gets, the more people change their other production and trade plans around it, making it even more popular. Symbols are annealed into popularity this way, initially coming to be because of their referent utility, continuing because of their popularity, declining at the loss of their referent utility. Change of symbols and culture depends on the certainty with which the signs predict their referent utility: what is more thoroughly ingrained changes more slowly than that which is more arbitrary ( for example, asset markets).
We have described an emergent interplay of conformity and utility. This leads us to ask to what extent are symbols arbitrary and to what extent are they somehow grounded? When I put all the goods at the same utility function coefficient, all the same effort to make and all the same effort to trade, one or two still stand out as the common means of trade. This is because people are ignorant: their cognitive limitations make them seek a "Schelling point", a place to meet, to master their world. What good becomes the money is necessarily accidental and arbitrary when all else is the same. However, we can change the parameters of cost of trade, effort to make, and number needed to satisfy and influence which good becomes the money. In fact, we do not even need to change parameters because some of them are emergent: in these simulations, the production of the popular good to trade always increases as it becomes popular, and although all the goods started out "all else the same", adaptation occurred on top of accident, so that production of the good and its popularity are not fixed but processes that cause each other. So, there is reason behind symbols as well as arbitrariness.
There are many symbols in this simulation. They include the good traded ( the money), the amount traded ( the commonly used "chunk" of a good, for example, a box of cereal that is always the same size), the relative amounts traded ( the price) , and the sign of the person the trade was made with ( the person schema). The signs of people, or ideal types allow agents to find strength in numbers and become a stable part of the environment that other agents can adapt to. Agents with the same signs will trade similarly, and come to behave more similarly as people adapt to them in the same way. The structures of society come from accident and adaptation to accident.
In their book Understanding Computers and Cognition, Winograd and Flores challenged AI's foundation in logic. They put forth the argument that there can be no homomorphism between the our perception of the environment and the "real world", as logic assumes. This simulation is a work from which symbols emerge that does not assume knowledge, but ignorance. Agents come to behave in synchrony not through copying, but through their individual understanding of signs based on their own utility with no necessary homomorphism to the world, but only correlations with sensory experiences of satisfaction. The agents speak to each other, but their speech is only understood by those with similar concepts emergent from their experiences in the same world. They are part of the world, adapted to the world, created by the world, creating the world, coevoling with their world and understanding their world. They are unable to copy and can only understand signs through the associations encoded in their minds, which are different in everybody but more similar in people of the same class. Their understanding is experiential: they socially construct their world as they interpret it, in the tradition of symbolic interactionism. Their actions linearize the world as they come to know, their world is made as they come to know. Without the symbols they make together, they know nothing and can not act in synchrony. They create each other, but they do not have a true understanding of each other: their groupings of people are fuzzy and pragmatic, their predictors always only partially accurate. Agents in this simulation learn their institutions as a child learns a language, not by direct copying of textbook grammar rules as adults do. Children invent the rules of language for themselves, creating their language through experience. The agents of my simulation do the same: they make their world all together, not by an entrepreneur that is copied. They are all entrepreneurs in a changing world where utility and conformity are dynamically intertwined. Only that which is ever being created can ever change.
This principle of the emergence of symbols has much to offer not only for social science simulation, but for artificial intelligence as well. Until now, artificial intelligence has ignored the social aspects of symbols, and in doing so they have ignored their creation and change. With static symbolic methods, they only have the weakest learning methods (such as constructive induction), with no truly new representations involved. With the use of simulation and process, we can now evolve knowledge representations along with their operations, to achieve something that is truly new and living. In this "artificial social intelligence" program, the symbols we have emerged ( the ideal types, etc.) are really concepts and a division of labor which could be used to create self-organizing objects in object oriented programming, or to emerge the tags of classifier systems. There is an intrinsic difference between something which might be described with the word "soup" and the highly structured object environment. Natural evolution, being based on accident and side effect, needs a mess to work with. It is more likely to make something that looks like a "spaghetti program" than small or crisply defined objects which our perceptions impose: Koza's genetic programming is an example of this. Yet just as the modern regulator wants to interfere with the living economy, so are programmers apt to blend a higher order reasoning with evolutionary programs, to understand them if not to change them. To translate from an evolutionary program to a rational one, all that is needed is an observer. As fuzzy ideal types linearize, crisp objects could be defined to document their existence, if not to modify it. In the future, programming could become a mixture of reasoning and evolution, with simcity like environments to work with.
Goldberg, David. Genetic Algorithms in Search, Optimization, and Machine Learning. Addison-Wesley, New York, 1989.
Hillis, Daniel. "Co-Evolving Parasites Improve Simulated Evolution as an Optimization Procedure" in Artificial Life II, Christopher Langton et al, eds. Addison-Wesley, New York, 1992.
Winograd, Terry and Fernando Flores. Understanding Computers and Cognition. Ablex, Norwood, 1987.