Modeling Utility Functions of Consumers and Generators

Story Description
As a consumer or generator (both are modeled as part of the the TAC Energy Server environment) I need to be able to rank-order different tariff offers of energy brokers (modeled by competition participants) according to one or more tariff attributes (e.g. signup-price, hourly consumption price, compatibility with my technical environment, broker reputation, satisfaction with existing tariff, etc.) in order to be able to sign-up to the most favorable tariff(s) in terms of my utility.


 * Note: Consumer and Generator behavior is modeled based on real historic or artificially generated time series from the time series data store. The challenge here is to assign a profile (or parts of it, say two thirds) to a broker where the assignment has to be based on tariff offers.

Modeling a tariff offer
Technically a tariff offer will be modeled as a Java / Groovy HashMap (note, in the following the groovy List and Map notations will be used as they are more concise than their Java counterparts).

Example tariff "Tariff 1" for consumers published by "Broker 1": [ name: "Tariff 1", broker: "Broker 1", signupFee: 10.0, consumptionFee: [0: 0.15, 6: 0.18, 8: 0.21, 10: 0.19, 13: 0.34, 17: 0.18] ]

Rank ordering tariff offers according to individual consumer's (generator's) preferences
Technically a Java Comparator class will have to be implemented for each single Consumer or Generator that is part of a competition. A comparator c is a special comparison function, which imposes a total ordering (i.e. $$\{(x, y) \; such \; that \; c.compare(x, y) \leq 0\}$$) on some collection of objects. In this particular case the Utility Function Comparator will be able to compare to HashMaps each containing a particular tariff offer.

Below is a simple example for a utility function impementation that considers the the tariff attribute "signupFee" (see sample tariff above) only to impose a total ordering on the different HashMaps (i.e. tariff offers): class SimpleUtilityFunction extends Comparator implements Serializable { int compare(HashMap tariff1, HashMap tariff2) { def tariff1SignupFee = tariff1?.signupFee ?: 0 def tariff2SignupFee = tariff2?.signupFee ?: 0 return tariff1SignupFee.compareTo(tariff2SignupFee); }  boolean equals(Object otherComparator) { return otherComparator instanceof SimpleUtilityFunction } } With such a comparator in place, an individual consumer / generator is able to impose a total order on a set of incoming tariff offers, e.g.:

public void testCompareTariffOffers { def tariff1 = [name: "Tariff 1", broker: "Broker 1", signupFee: 12.0, consumptionFee: [0: 0.15, 6: 0.18, 8: 0.21, 10: 0.19, 13: 0.34, 17: 0.18]] def tariff2 = [name: "Tariff 2", broker: "Broker 2", signupFee: 10.0, consumptionFee: [0: 0.15, 6: 0.18, 8: 0.21, 10: 0.19, 13: 0.34, 17: 0.18]] def tariffList = [tariff1, tariff2] Collections.sort (tariffList, new SimpleUtilityFunction) assertEquals (tariff2, tariffList[0]) assertEquals (tariff1, tariffList[1]) }

Single Consumer / Generator assigns partial (or full) profile load / capacity to one or more tariff offers
With a sorted tariffList at hand, a consumer (generator) can then decide on how much of its overall demand (capacity) he might want to assign to each of the tariffs. The rationale in behind is that a single consumer in TAC Energy might represent a population of 100 or 1000 individual households that all expose the same behavior. Like this large consumer / generator populations can be simulated at limited computational effort.

For the following example we assume that the consumer representes the energy demand of 100 households. The consumer then receives a list of tariffs as described above, brings all tariffs into a total order according to his preferences (i.e. using his individually assigned Comparator) and finally assigns certain shares of his overall demand to one or more of the available tariffs. In this particular case the best ranked tariff will receive 100% of the demand if it is the only tariff on offer. If there is more than one tariff on offer, the best ranked tariff will be assigned 75% of the overall demand (in this case equalling the load of 75 households), the second best ranked tariff will receive 25% (e.g. 25 households) and all other tariffs will receive 0% of the consumer's overall energy demand. public List getTariffShares(List tariffs) { //rank order tariff offers according to the consumers personal utility /comparator function Collections.sort (tariffs, new SimpleUtilityFunction) //assign a certain share of the consumer's overall energy demand to some of the tariffs def tariffCount = tariffs.size def resultList = [] if (tariffCount >= 2) { resultList.add(])''' resultList.add(])''' } else if (tariffCount == 1) { resultList.add(])''' }    return resultList }

Profile Store / Market Intelligence Service returns all consumer / generator responses to the TAC Energy Server
For a new competition, a new competition user is created in the profile store (= market intelligence service) and assigned one or more load and / or generation profiles from its database. Once the TAC Energy server submits a list of tariff offers (as defined by the the brokers playing in the competition), the profile store will forward the tariff list to each of the profiles that were assigned to the particular competition user. Afterwards it collects the responses from all profiles and returns the aggregated response list to the TAC energy server. This response list might look likes this: , ],      [...]  ],  ], ] Note: The tariff names need not to be mutually exclusive only per broker.

Open Questions
--> I would argue that all this aggregation and statistics compilation functionality could / should go into the profile store / market intelligence service in order to reduce load on the TAC Energy server.
 * CBL: Should the complete profile data be transferred to the TAC Energy server for further usage or should the TAC Energy server make specific requests to the profiles store / market intelligence, e.g. to access the cumulated load profile (or its descriptive statistics) for a particular broker (which might consist of (0.25 * consumerProfile1 + 0.xx * consumerProfileX + ...)
 * CBL: Where do we put the "profile adaptation" functionality. Example: A broker changes his tariff conditions (in particular the consumption price) and one or more of the assigned consumers reacts with load shedding / load shifting as response. Should this functionality also go into the profile store?
 * JEC: I'm not sure what the technical/programming environment is for the profile store, but there are other issues to be considered, such as
 * Researchers need to be able to set up and run complete server environments in order to do experimental work. There cannot be just one profile store; it needs to be somehow "bundled" with a server code distribution, and individual groups need to be able to load it with their own profiles, or perhaps replace it with statistical profile generators.
 * CBL: good point. The profile store (as the server itself) can be provided as a single java WAR file that runs out of the box on any Tomcat 6 Application Server. A newly created profile store is empty by default, but already today it comes attached with a "profile generator" functionality for creating artificial driving profiles. A household load profile generator (as originally designed by Sebastian) should follow as a second artificial profile generator but is not implemented yet. Besides this users can upload csv files with historic time series data to "feed" the store. In short, somebody who wants to run a local TAC environment, needs to download and deploy two war files to a tomcat 6 server (that's exactly how the ibwmarkets server runs right now). Both applications use an hsqldb database by default, which needs no further setup but can be replaced with other db's for performance improvement.
 * The process of modeling new types of consumers needs to be as open and accessible as possible, because this ability will be a major element in the research value of TAC Energy. Ideally, it will be possible to create these models with REPAST. Andreas and his group are looking into this; so we should ask them about how such models might be integrated into the server environment.
 * Asymeon: We have been working a bit on modeling Consumers and have started discussing our candidate architectures. With respect to the Profile store, we see two alternatives:
 * Provide the ability to build a number of different profile stores (depending on the needs of the user) and then generate REPAST models that can connect to more that one profile stores
 * Generate a distributed profile store, containing different (levels of) information in different "chunks" of the profile store, and (maybe) provide different access levels to users to connect to the information.
 * Options 1 and 2 can be combined if considered necessary.


 * CBL: Good. Looking into REPAST and programming a demo app is on my todo list though I'm behind my schedule for family reasons... ;-)
 * Implementing the behavior of the various customer models will be a major element of the server environment, of course, and it will be a performance issue no matter where it resides. If the architecture involves multiple servers running from a single profile store (that is my assumption), then the performance argument might favor implementing this behavior in the server
 * Implementing the behavior of the various customer models will be a major element of the server environment, of course, and it will be a performance issue no matter where it resides. If the architecture involves multiple servers running from a single profile store (that is my assumption), then the performance argument might favor implementing this behavior in the server


 * CBL: Good point. Still, if this turns out to be a real bottleneck, we could set-up several profile stores (maybe one profile store and one tac server per machine) and use standard database replication mechanisms to synchronize the profile stores once a day (or so).
 * Asymeon: In this case, we have to be sure everything is working smoothly.


 * CBL: How about Intellectual property rights issues? I think separating the profile store and the server like this allows us to run different competions with different access rights for different profiles. Though in that case we need to implement our own "IP aware" replication. I realized such a REST-ful data replication mechanism already for the agent based simulation run time environment I developed as part of my PhD thesis. That could probably be adapted without too much extra work for our case