Changeset 53 for profile


Ignore:
Timestamp:
12/18/24 13:28:59 (3 weeks ago)
Author:
ruud
Message:

All TimeDependent parties now support the nonlinear SumOfGroupsUtilitySpace. Example Nonlinear space in the computer domain

Location:
profile
Files:
5 added
9 edited

Legend:

Unmodified
Added
Removed
  • profile/pom.xml

    r52 r53  
    66        <groupId>geniusweb</groupId>
    77        <artifactId>profile</artifactId>
    8         <version>2.1.6</version>
     8        <version>2.2.1</version>  <!-- equals the geniusweb version -->
    99        <packaging>jar</packaging>
    1010
     
    4242                        <groupId>tudelft.utilities</groupId>
    4343                        <artifactId>utilities</artifactId>
    44                         <version>1.2.1</version>
     44                        <version>1.3.1</version>
    4545                </dependency>
    4646
  • profile/src/main/java/geniusweb/profile/DefaultPartialOrdering.java

    r52 r53  
    11package geniusweb.profile;
    22
     3import java.io.IOException;
    34import java.util.ArrayList;
    45import java.util.Arrays;
    5 import java.util.HashMap;
    66import java.util.HashSet;
    77import java.util.LinkedList;
     
    1010import java.util.Set;
    1111
     12import com.fasterxml.jackson.annotation.JsonAutoDetect;
     13import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
    1214import com.fasterxml.jackson.annotation.JsonCreator;
    13 import com.fasterxml.jackson.annotation.JsonGetter;
    1415import com.fasterxml.jackson.annotation.JsonProperty;
     16import com.fasterxml.jackson.core.JsonGenerator;
     17import com.fasterxml.jackson.databind.DeserializationContext;
     18import com.fasterxml.jackson.databind.JsonSerializer;
     19import com.fasterxml.jackson.databind.KeyDeserializer;
     20import com.fasterxml.jackson.databind.ObjectMapper;
     21import com.fasterxml.jackson.databind.SerializerProvider;
     22import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
     23import com.fasterxml.jackson.databind.annotation.JsonSerialize;
    1524
    1625import geniusweb.issuevalue.Bid;
    1726import geniusweb.issuevalue.Domain;
     27
     28/**
     29 * Strange that we need to do this. Bid is completely standard. The complication
     30 * that this solves is that the keys are places as STRING in the json code
     31 * because json allows only strings as key.
     32 */
     33@SuppressWarnings("serial")
     34class BidDeserializer extends KeyDeserializer {
     35        private ObjectMapper jackson = new ObjectMapper();
     36
     37        @Override
     38        public Bid deserializeKey(String key, DeserializationContext ctxt)
     39                        throws IOException {
     40                return jackson.readValue(key, Bid.class);
     41        }
     42
     43}
     44
     45/**
     46 * Serializes a Bid to string. Unfortunately by default jackson uses
     47 * key.toString() for serializing (rather than
     48 * {@link ObjectMapper#writeValueAsString(Object)}).
     49 *
     50 */
     51class BidSerializer extends JsonSerializer<Bid> {
     52        private ObjectMapper jackson = new ObjectMapper();
     53
     54        @Override
     55        public void serialize(Bid bid, JsonGenerator gen,
     56                        SerializerProvider serializers) throws IOException {
     57                gen.writeFieldName(jackson.writeValueAsString(bid));
     58        }
     59
     60}
    1861
    1962/**
     
    2669 * limited anyway.
    2770 */
     71@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE, isGetterVisibility = Visibility.NONE)
    2872public class DefaultPartialOrdering extends DefaultProfile
    2973                implements PartialOrdering {
     
    3377         * other bid.
    3478         */
    35         private final Map<Bid, Set<Bid>> isBetter;
     79        @JsonDeserialize(keyUsing = BidDeserializer.class)
     80        @JsonSerialize(keyUsing = BidSerializer.class)
     81        private final Map<Bid, Set<Bid>> better;
    3682
    3783        /**
    38          *
    39          * @param name           name of the profile
    40          * @param domain         the {@link Domain}
    41          * @param reservationbid the reservation bid, this is the minimum acceptable
    42          *                       bid
    43          * @param bids           a list of bids that this ordering contains
    44          *                       comparisons for
    45          * @param isbetterList   a list of tuples [bid1index, bid2index]. It
    46          *                       indicates that bids[bid1index] isbetterthan
    47          *                       bids[bid2index].
     84         * @param name           the name for the profile
     85         * @param domain         the {@link Domain} description
     86         * @param reservationbid the reservation {@link Bid}
     87         * @param better         a map with keys = a better bid and value=a less
     88         *                       good bid.
    4889         */
    4990        @JsonCreator
     
    5192                        @JsonProperty("domain") Domain domain,
    5293                        @JsonProperty("reservationBid") Bid reservationbid,
    53                         @JsonProperty("bids") List<Bid> bids,
    54                         @JsonProperty("better") List<List<Integer>> isbetterList) {
    55                 this(name, domain, reservationbid, makeBidMap(bids, isbetterList));
    56         }
    57 
    58         /**
    59          * @param name           the name for the profile
    60          * @param domain         the {@link Domain} description
    61          * @param reservationbid the reservation {@link Bid}
    62          * @param isBetterMap    a map with keys = a better bid and value=a less
    63          *                       good bid.
    64          */
    65         public DefaultPartialOrdering(String name, Domain domain,
    66                         Bid reservationbid, Map<Bid, Set<Bid>> isBetterMap) {
     94                        @JsonProperty("better") Map<Bid, Set<Bid>> better) {
    6795                super(name, domain, reservationbid);
    68                 this.isBetter = isBetterMap;
     96                this.better = better;
    6997        }
    7098
    7199        @Override
    72100        public boolean isPreferredOrEqual(Bid bid1, Bid bid2) {
    73                 if (!isBetter.containsKey(bid1))
     101                if (!better.containsKey(bid1))
    74102                        return false;
    75                 return isBetter.get(bid1).contains(bid2);
     103                return better.get(bid1).contains(bid2);
    76104        }
    77105
     
    81109         *         or as worse than another bid
    82110         */
    83         @JsonGetter
    84111        public List<Bid> getBids() {
    85112                // FIXME the iteration order may not be guaranteed!
    86113                Set<Bid> bids = new HashSet<>();
    87                 for (Bid bid : isBetter.keySet()) {
     114                for (Bid bid : better.keySet()) {
    88115                        bids.add(bid);
    89                         bids.addAll(isBetter.get(bid));
     116                        bids.addAll(better.get(bid));
    90117                }
    91118                return new ArrayList<Bid>(bids);
    92119        }
    93120
    94         @JsonGetter
    95121        /**
    96122         *
     
    103129
    104130                for (Bid bid : bidslist) {
    105                         if (isBetter.containsKey(bid)) {
    106                                 for (Bid worsebid : isBetter.get(bid)) {
     131                        if (better.containsKey(bid)) {
     132                                for (Bid worsebid : better.get(bid)) {
    107133                                        betterlist.add(Arrays.asList(bidslist.indexOf(bid),
    108134                                                        bidslist.indexOf(worsebid)));
     
    116142        @Override
    117143        public String toString() {
    118                 return "DefaultPartialOrdering[" + getValuesString() + "," + isBetter
     144                return "DefaultPartialOrdering[" + getValuesString() + "," + better
    119145                                + "]";
    120         }
    121 
    122         private static Map<Bid, Set<Bid>> makeBidMap(List<Bid> bids,
    123                         List<List<Integer>> isBetterList) {
    124                 Map<Bid, Set<Bid>> betterMap = new HashMap<>();
    125 
    126                 for (List<Integer> tuple : isBetterList) {
    127                         if (tuple.size() != 2) {
    128                                 throw new IllegalArgumentException("Expected tuple but found "
    129                                                 + tuple + "in " + isBetterList);
    130                         }
    131                         Bid betterbid = bids.get(tuple.get(0));
    132                         Set<Bid> map = betterMap.get(betterbid);
    133                         if (map == null) {
    134                                 map = new HashSet<>();
    135                                 betterMap.put(betterbid, map);
    136                         }
    137                         map.add(bids.get(tuple.get(1)));
    138                 }
    139 
    140                 return betterMap;
    141146        }
    142147
     
    145150                final int prime = 31;
    146151                int result = super.hashCode();
    147                 result = prime * result
    148                                 + ((isBetter == null) ? 0 : isBetter.hashCode());
     152                result = prime * result + ((better == null) ? 0 : better.hashCode());
    149153                return result;
    150154        }
     
    159163                        return false;
    160164                DefaultPartialOrdering other = (DefaultPartialOrdering) obj;
    161                 if (isBetter == null) {
    162                         if (other.isBetter != null)
     165                if (better == null) {
     166                        if (other.better != null)
    163167                                return false;
    164                 } else if (!isBetter.equals(other.isBetter))
     168                } else if (!better.equals(other.better))
    165169                        return false;
    166170                return true;
  • profile/src/main/java/geniusweb/profile/utilityspace/LinearAdditiveUtilitySpace.java

    r52 r53  
    4949         * @param domain  the {@link Domain} in which this profile is defined.
    5050         * @param name    the name of this profile. Must be simple name (a-Z, 0-9)
    51          * @param utils   a map with key: issue names (String) and value: the values
     51         * @param issueUtilities   a map with key: issue names (String) and value: the values
    5252         *                for that issue. There MUST NOT be a null issue. All values
    5353         *                MUST NOT be null.
    54          * @param weights the weight of each issue in the computation of the
     54         * @param issueWeights the weight of each issue in the computation of the
    5555         *                weighted sum. The issues must be the same as those in the
    5656         *                utils map. All weights MUST NOT be null. The weights MUST
    5757         *                sum to 1.
    58          * @param resBid  the reservation bid. Only bids that are
     58         * @param reservationBid  the reservation bid. Only bids that are
    5959         *                {@link #isPreferredOrEqual(Bid, Bid)} should be accepted.
    6060         *                Can be null, meaning that there is no reservation bid and
     
    6666        public LinearAdditiveUtilitySpace(@JsonProperty("domain") Domain domain,
    6767                        @JsonProperty("name") String name,
    68                         @JsonProperty("issueUtilities") Map<String, ValueSetUtilities> utils,
    69                         @JsonProperty("issueWeights") Map<String, BigDecimal> weights,
    70                         @JsonProperty("reservationBid") Bid resBid) {
    71                 this.domain = domain;
    72                 this.name = name;
    73                 this.reservationBid = resBid;
    74                 this.issueUtilities.putAll(utils);
    75                 this.issueWeights.putAll(weights);
     68                        @JsonProperty("issueUtilities") Map<String, ValueSetUtilities> issueUtilities,
     69                        @JsonProperty("issueWeights") Map<String, BigDecimal> issueWeights,
     70                        @JsonProperty("reservationBid") Bid reservationBid) {
    7671
    7772                if (domain == null) {
    7873                        throw new NullPointerException("domain=null");
    7974                }
    80                 if (utils == null) {
     75                if (issueUtilities == null) {
    8176                        throw new NullPointerException("utils=null");
    8277                }
    83                 if (weights == null) {
     78                if (issueWeights == null) {
    8479                        throw new NullPointerException("weights=null");
    8580                }
    86                 if (utils.values().contains(null)) {
     81                if (issueUtilities.values().contains(null)) {
    8782                        throw new NullPointerException(
    8883                                        "One of the ValueSetUtilities in issueUtilitiesis null:"
    89                                                         + utils);
    90                 }
    91                 if (weights.values().contains(null)) {
     84                                                        + issueUtilities);
     85                }
     86                if (issueWeights.values().contains(null)) {
    9287                        throw new NullPointerException("One of the weights is null");
    9388                }
    94                 if (utils.keySet().contains(null)) {
     89                if (issueUtilities.keySet().contains(null)) {
    9590                        throw new NullPointerException("One of the issue names is null");
    9691                }
     
    9994                                        "Name must be simple (a-Z, 0-9) but got " + name);
    10095                }
    101                 if (!(utils.keySet().equals(domain.getIssues()))) {
     96                if (!(issueUtilities.keySet().equals(domain.getIssues()))) {
    10297                        throw new IllegalArgumentException(
    10398                                        "The issues in  utilityspace and domain do not match: utilityspace has issues "
    104                                                         + utils.keySet() + " but domain contains "
     99                                                        + issueUtilities.keySet() + " but domain contains "
    105100                                                        + domain.getIssues());
    106101                }
    107                 if (!(weights.keySet().equals(domain.getIssues()))) {
     102                if (!(issueWeights.keySet().equals(domain.getIssues()))) {
    108103                        throw new IllegalArgumentException(
    109104                                        "The issues in weights and domain do not match: weights has "
    110                                                         + weights.keySet() + " but domain contains "
     105                                                        + issueWeights.keySet() + " but domain contains "
    111106                                                        + domain.getIssues());
    112107                }
     
    118113                }
    119114
    120                 BigDecimal sum = weights.values().stream().reduce(BigDecimal.ZERO,
     115                BigDecimal sum = issueWeights.values().stream().reduce(BigDecimal.ZERO,
    121116                                BigDecimal::add);
    122117                if (BigDecimal.ONE.compareTo(sum) != 0) { // equals does NOT work for
    123118                                                                                                        // comparing BigDecimals!!
    124119                        throw new IllegalArgumentException("The sum of the weights ("
    125                                         + weights.values() + ") must be 1");
    126                 }
    127                 if (resBid != null) {
    128                         String message = domain.isFitting(resBid);
     120                                        + issueWeights.values() + ") must be 1");
     121                }
     122                if (reservationBid != null) {
     123                        String message = domain.isFitting(reservationBid);
    129124                        if (message != null)
    130125                                throw new IllegalArgumentException(
    131126                                                "reservationbid is not fitting domain: " + message);
    132127                }
     128
     129                this.domain = domain;
     130                this.name = name;
     131                this.reservationBid = reservationBid;
     132                this.issueUtilities.putAll(issueUtilities);
     133                this.issueWeights.putAll(issueWeights);
     134
    133135        }
    134136
  • profile/src/main/java/geniusweb/profile/utilityspace/PartsUtilities.java

    r52 r53  
    77import java.util.List;
    88import java.util.Map;
     9import java.util.stream.Collectors;
    910
    1011import com.fasterxml.jackson.annotation.JsonAutoDetect;
     
    1314import com.fasterxml.jackson.annotation.JsonProperty;
    1415
     16import geniusweb.issuevalue.Domain;
    1517import geniusweb.issuevalue.Value;
    1618import geniusweb.issuevalue.ValueSet;
     19import tudelft.utilities.immutablelist.ImmutableList;
     20import tudelft.utilities.immutablelist.Outer;
    1721
    1822/**
     
    4145         *
    4246         * @param issues list of issues
    43          * @param utils  with keys: list of values and value: utility value for that
    44          *               list of values. All list-of-values missing from the map are
    45          *               assumed to have utility 0. This includes partial bids where
    46          *               list-of-values contain null objects.
     47         * @param utils  with keys: list of values, one for each issue in issues (in
     48         *               the order of the list of issues) and value: utility value
     49         *               for that list of values. All list-of-values missing from
     50         *               the map are assumed to have utility 0. This includes
     51         *               partial bids where list-of-values contain null objects.
    4752         */
    4853        public PartsUtilities(List<String> issues,
    4954                        Map<ProductOfValue, BigDecimal> utils) {
    50                 if (issues == null || utils == null) {
     55                if (issues == null || utils == null || issues.isEmpty()) {
    5156                        throw new IllegalArgumentException(
    52                                         "issues and utils must be not null");
     57                                        "issues and utils must be not null or empty");
    5358                }
    5459
     
    149154        }
    150155
     156        /**
     157         * Check that all needed values have been set to a utility.
     158         *
     159         * @param domain the domain for which this should be parts. We need this to
     160         *               check that the values used are actually from the dmoain
     161         * @throws IllegalArgumentException if a problem is found
     162         */
     163        public void checkComplete(Domain domain) {
     164
     165                final List<ImmutableList<Value>> valuesofissues = issues.stream()
     166                                .map(iss -> domain.getValues(iss)).collect(Collectors.toList());
     167
     168                // check that all possible value combinations are handled
     169                for (ImmutableList<Value> vals : new Outer<Value>(valuesofissues)) {
     170                        ProductOfValue expected = ProductOfValue.create(vals);
     171                        if (!utilities.containsKey(expected))
     172                                throw new IllegalArgumentException(
     173                                                "Values " + vals + " must be assigned a utility");
     174                }
     175        }
     176
    151177        @Override
    152178        public boolean equals(Object obj) {
     
    176202        }
    177203
     204        /**
     205         * Check that the set of utilities is complete and no weird utility values
     206         * were used
     207         *
     208         */
    178209        private void checkUtilities() {
    179                 if (utilities.values().stream()
    180                                 .anyMatch(v -> v == null || v.compareTo(BigDecimal.ZERO) < 0
    181                                                 || v.compareTo(BigDecimal.ONE) > 0)) {
    182                         throw new IllegalArgumentException(
    183                                         "part weights must all be in [0,1]");
     210                for (BigDecimal value : utilities.values()) {
     211                        if (value == null || value.compareTo(BigDecimal.ZERO) < 0
     212                                        || value.compareTo(BigDecimal.ONE) > 0)
     213                                throw new IllegalArgumentException(
     214                                                "part weights must all be in [0,1] but found " + value);
    184215                }
    185216        }
     
    196227
    197228        /**
    198          *
    199229         * @return the max utility of all values contained here.
    200230         */
  • profile/src/main/java/geniusweb/profile/utilityspace/ProductOfValue.java

    r52 r53  
    22
    33import java.util.ArrayList;
     4import java.util.LinkedList;
    45import java.util.List;
    56
     
    1011
    1112import geniusweb.issuevalue.Value;
     13import tudelft.utilities.immutablelist.ImmutableList;
    1214
    1315/**
    14  * A {@link Value} that is the product of some existing values
     16 * A {@link Value} that is a list of a number of values in the space
    1517 */
    1618@JsonDeserialize(using = JsonDeserializer.None.class)
     
    2426        public ProductOfValue(List<Value> newvals) {
    2527                values.addAll(newvals);
     28        }
     29
     30        public static ProductOfValue create(ImmutableList<Value> vals) {
     31                List<Value> list = new LinkedList<>();
     32                for (Value val : vals) {
     33                        list.add(val);
     34                }
     35                return new ProductOfValue(list);
    2636        }
    2737
  • profile/src/main/java/geniusweb/profile/utilityspace/SumOfGroupsUtilitySpace.java

    r52 r53  
    33import java.math.BigDecimal;
    44import java.util.Arrays;
     5import java.util.Collections;
    56import java.util.HashMap;
    67import java.util.HashSet;
     
    5152         * @param partutils a map with key: part names (String) and value: the
    5253         *                  {@link PartsUtilities} for that part. There MUST NOT be
    53          *                  a null part name. All values MUST NOT be null. The
    54          *                  PartsUtilities must match the
     54         *                  a null part name. The PartsUtilities must be complete:
     55         *                  all possible combinations of all parts must cover all
     56         *                  combinations of issue values and assign a proper utility
     57         *                  in [0,1].
    5558         * @param resBid    the reservation bid. Only bids that are
    5659         *                  {@link #isPreferredOrEqual(Bid, Bid)} should be
    5760         *                  accepted. Can be null, meaning that there is no
    5861         *                  reservation bid and any agreement is better than no
    59          *                  agreement.
     62         *                  agreement. Read the note about partial bids in
     63         *                  {@link #getUtility(Bid)}.
    6064         * @throws NullPointerException     if values are incorrectly null.
    6165         * @throws IllegalArgumentException if preconditions not met.
     
    6973                this.partUtilities.putAll(partutils);
    7074
    71                 String err = checkParts();
    72                 if (err != null) {
    73                         throw new IllegalArgumentException(err);
    74                 }
    75         }
    76 
    77         /**
    78          * Copy settings in las. This will have the exact same utilities as the las
    79          * but this then gives you the power to change it into a non-linear space by
    80          * grouping.
     75                checkParts();
     76        }
     77
     78        /**
     79         * Copy settings in las. This will have the exact same utilities as the
     80         * {@link LinearAdditive} space but this then gives you the power to change
     81         * it into a non-linear space by grouping.
    8182         *
    8283         * @param las the {@link LinearAdditive} to be converted/copied.
    8384         *
    8485         */
    85         public SumOfGroupsUtilitySpace(LinearAdditive las) {
    86                 this(las.getDomain(), las.getName(), las2parts(las),
    87                                 las.getReservationBid());
    88         }
    89 
     86        public static SumOfGroupsUtilitySpace create(LinearAdditive las) {
     87                return new SumOfGroupsUtilitySpace(las.getDomain(), las.getName(),
     88                                las2parts(las), las.getReservationBid());
     89        }
     90
     91        /**
     92         *
     93         * @return all partsutilities
     94         */
     95        public Map<String, PartsUtilities> getPartsUtilities() {
     96                return Collections.unmodifiableMap(partUtilities);
     97        }
     98
     99        /**
     100         *
     101         * Note: If bid is partial for a group, the utility of that group can not be
     102         * evaluated and is set to 0.
     103         *
     104         */
    90105        @Override
    91106        public BigDecimal getUtility(Bid bid) {
    92                 return partUtilities.keySet().stream()
    93                                 .map(partname -> util(partname, bid))
    94                                 .reduce(BigDecimal.ZERO, BigDecimal::add);
     107                BigDecimal sum = BigDecimal.ZERO;
     108                for (String partname : partUtilities.keySet()) {
     109                        sum = sum.add(util(partname, bid));
     110                }
     111                return sum;
    95112        }
    96113
    97114        @Override
    98115        public String toString() {
    99                 return "PartialAdditive[" + partUtilities + "," + getReservationBid()
    100                                 + "]";
     116                return "SumOfGroupsUtilitySpace[" + getName() + "," + partUtilities
     117                                + "," + getReservationBid() + "]";
    101118        }
    102119
     
    235252         * @return error string, or null if no error (all parts seem fine)
    236253         */
    237         private String checkParts() {
     254        private void checkParts() throws IllegalArgumentException {
    238255
    239256                Set<String> collectedIssues = new HashSet<>();
     
    241258                        PartsUtilities part = partUtilities.get(partname);
    242259                        if (part == null) {
    243                                 return "partUtilities " + partname + " contains null value";
     260                                throw new IllegalArgumentException(
     261                                                "partUtilities " + partname + " contains null value");
    244262                        }
    245263                        List<String> issues = part.getIssues();
     
    247265                        intersection.retainAll(issues);
    248266                        if (!intersection.isEmpty()) {
    249                                 return "issues " + intersection + " occur multiple times";
    250                         }
     267                                throw new IllegalArgumentException(
     268                                                "issues " + intersection + " occur multiple times");
     269                        }
     270                        part.checkComplete(getDomain());
    251271                        collectedIssues.addAll(issues);
    252272                }
    253273
    254274                if (!collectedIssues.equals(getDomain().getIssues())) {
    255                         return "parts must cover the domain issues "
    256                                         + getDomain().getIssues() + " but cover " + collectedIssues;
     275                        throw new IllegalArgumentException(
     276                                        "parts must cover the domain issues "
     277                                                        + getDomain().getIssues() + " but cover "
     278                                                        + collectedIssues);
    257279                }
    258280                if (getMaxUtility().compareTo(BigDecimal.ONE) > 0) {
    259                         return "Max utility of the space exceedds 1";
    260                 }
    261                 return null;
     281                        throw new IllegalArgumentException(
     282                                        "Max utility of the space exceedds 1");
     283                }
    262284
    263285        }
  • profile/src/test/java/geniusweb/profile/DefaultPartialOrderingTest.java

    r52 r53  
    2727import tudelft.utilities.junit.GeneralTests;
    2828
    29 public class DefaultPartialOrderingTest extends GeneralTests<DefaultPartialOrdering> {
     29public class DefaultPartialOrderingTest
     30                extends GeneralTests<DefaultPartialOrdering> {
    3031
    31         private final String serialized = "{\"DefaultPartialOrdering\":{" + "\"name\":\"ordering1\","
     32        private final String serialized = "{\"DefaultPartialOrdering\":{"
     33                        + "\"name\":\"ordering1\","
    3234                        + "\"domain\":{\"name\":\"dom1\",\"issuesValues\":{\"iss1\":{\"values\":[\"1\",\"2\",\"3\"]}}},"
    33                         + "\"reservationBid\":{\"issuevalues\":{\"iss1\":\"1\"}},"
    34                         + "\"bids\":[{\"issuevalues\":{\"iss1\":\"1\"}},{\"issuevalues\":{\"iss1\":\"3\"}},{\"issuevalues\":{\"iss1\":\"2\"}}],"
    35                         + "\"better\":[[0,2],[1,2]]}}";
     35                        + "\"better\":{\"{\\\"issuevalues\\\":{\\\"iss1\\\":\\\"1\\\"}}\":[{\"issuevalues\":{\"iss1\":\"2\"}}],\"{\\\"issuevalues\\\":{\\\"iss1\\\":\\\"3\\\"}}\":[{\"issuevalues\":{\"iss1\":\"2\"}}]},"
     36                        + "\"reservationbid\":{\"issuevalues\":{\"iss1\":\"1\"}}}}";
    3637
    3738        // we need real (not mock) values otherwise serializer crashes..
    3839        private String issue1 = "iss1";
    39         private DefaultPartialOrdering ordering1, ordering1b, ordering2, ordering3, ordering4, ordering5;
     40        private DefaultPartialOrdering ordering1, ordering1b, ordering2, ordering3,
     41                        ordering4, ordering5;
    4042
    4143        private Bid bid1, bid2, bid3;
     
    4749                DiscreteValue val2 = new DiscreteValue("2");
    4850                DiscreteValue val3 = new DiscreteValue("3");
    49                 issues.put(issue1, new DiscreteValueSet(new HashSet<>(Arrays.asList(val1, val2, val3))));
     51                issues.put(issue1, new DiscreteValueSet(
     52                                new HashSet<>(Arrays.asList(val1, val2, val3))));
    5053                Domain domain1 = new Domain("dom1", issues);
    5154                Domain domain2 = new Domain("dom2", issues);
     
    6265                map2.put(bid3, new HashSet<Bid>(Arrays.asList(bid1)));
    6366
    64                 ordering1 = new DefaultPartialOrdering("ordering1", domain1, bid1, map1);
    65                 ordering1b = new DefaultPartialOrdering("ordering1", domain1, bid1, map1);
    66                 ordering2 = new DefaultPartialOrdering("ordering2", domain1, bid1, map1);
    67                 ordering3 = new DefaultPartialOrdering("ordering1", domain2, bid1, map1);
    68                 ordering4 = new DefaultPartialOrdering("ordering1", domain1, bid2, map1);
    69                 ordering5 = new DefaultPartialOrdering("ordering1", domain1, bid1, map2);
     67                ordering1 = new DefaultPartialOrdering("ordering1", domain1, bid1,
     68                                map1);
     69                ordering1b = new DefaultPartialOrdering("ordering1", domain1, bid1,
     70                                map1);
     71                ordering2 = new DefaultPartialOrdering("ordering2", domain1, bid1,
     72                                map1);
     73                ordering3 = new DefaultPartialOrdering("ordering1", domain2, bid1,
     74                                map1);
     75                ordering4 = new DefaultPartialOrdering("ordering1", domain1, bid2,
     76                                map1);
     77                ordering5 = new DefaultPartialOrdering("ordering1", domain1, bid1,
     78                                map2);
    7079
    7180        }
     
    7382        @Override
    7483        public List<List<DefaultPartialOrdering>> getGeneralTestData() {
    75                 return Arrays.asList(Arrays.asList(ordering1, ordering1b), Arrays.asList(ordering2), Arrays.asList(ordering3),
     84                return Arrays.asList(Arrays.asList(ordering1, ordering1b),
     85                                Arrays.asList(ordering2), Arrays.asList(ordering3),
    7686                                Arrays.asList(ordering4), Arrays.asList(ordering5));
    7787        }
     
    7989        @Override
    8090        public List<String> getGeneralTestStrings() {
    81                 return Arrays.asList("DefaultPartialOrdering.*", "DefaultPartialOrdering.*", "DefaultPartialOrdering.*",
     91                return Arrays.asList("DefaultPartialOrdering.*",
     92                                "DefaultPartialOrdering.*", "DefaultPartialOrdering.*",
    8293                                "DefaultPartialOrdering.*", "DefaultPartialOrdering.*");
    8394        }
  • profile/src/test/java/geniusweb/profile/utilityspace/LinearAdditiveTest.java

    r52 r53  
    2222
    2323import com.fasterxml.jackson.databind.ObjectMapper;
     24import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
    2425
    2526import geniusweb.issuevalue.Bid;
     
    309310        }
    310311
     312        /**
     313         * This should throw because computersell-domainmismatch has a mismatch: it
     314         * has "high 32G" as graphics option, but the utilities have no value for
     315         * that. Instead it talks about "high 24G"
     316         */
     317        @Test(expected = ValueInstantiationException.class)
     318        public void testIsFitting() throws IOException {
     319                String profile = new String(
     320                                Files.readAllBytes(Paths.get(
     321                                                "src/test/resources/computersell-domainmismatch.json")),
     322                                StandardCharsets.UTF_8);
     323                UtilitySpace space = jackson.readValue(profile, UtilitySpace.class);
     324
     325        }
     326
    311327}
  • profile/src/test/java/geniusweb/profile/utilityspace/SumOfGroupsUtilitySpaceTest.java

    r52 r53  
    2121import org.junit.Test;
    2222
     23import com.fasterxml.jackson.core.JsonParseException;
    2324import com.fasterxml.jackson.core.JsonProcessingException;
     25import com.fasterxml.jackson.databind.JsonMappingException;
    2426import com.fasterxml.jackson.databind.ObjectMapper;
     27import com.fasterxml.jackson.databind.exc.ValueInstantiationException;
    2528
    2629import geniusweb.issuevalue.Bid;
     
    3437import tudelft.utilities.immutablelist.ImmutableList;
    3538import tudelft.utilities.immutablelist.Outer;
    36 
    37 public class SumOfGroupsUtilitySpaceTest {
     39import tudelft.utilities.junit.GeneralTests;
     40
     41public class SumOfGroupsUtilitySpaceTest
     42                extends GeneralTests<SumOfGroupsUtilitySpace> {
    3843        private final ObjectMapper jackson = new ObjectMapper();
    3944        private SumOfGroupsUtilitySpace pa1;
     
    4954
    5055        private Domain domain;
    51         private PartsUtilities putils12, putils3;
     56        private PartsUtilities putils12, putils3, putils3b;
    5257        private String serialized = "{\"SumOfGroupsUtilitySpace\":{\"domain\":{\"name\":\"domain\",\"issuesValues\":{\"issue3\":{\"values\":[\"low\",\"high\"]},\"issue2\":{\"values\":[\"low\",\"high\"]},\"issue1\":{\"values\":[\"low\",\"high\"]}}},\"name\":\"testspace\",\"partUtilities\":{\"1and2\":{\"PartsUtilities\":{\"issues\":[\"issue1\",\"issue2\"],\"utilslist\":[{\"values\":[\"low\",\"low\"],\"util\":0.16},{\"values\":[\"high\",\"high\"],\"util\":0.72},{\"values\":[\"low\",\"high\"],\"util\":0.16},{\"values\":[\"high\",\"low\"],\"util\":0.16}]}},\"3\":{\"PartsUtilities\":{\"issues\":[\"issue3\"],\"utilslist\":[{\"values\":[\"low\"],\"util\":0.16},{\"values\":[\"high\"],\"util\":0.14}]}}},\"reservationbid\":{\"issuevalues\":{\"issue1\":\"high\"}}}}";
     58        private SumOfGroupsUtilitySpace sog1, sog1a, sog2, sog3;
    5359
    5460        @Before
     
    7884                putils3 = new PartsUtilities(Arrays.asList(iss3), utils3);
    7985
     86                Map<ProductOfValue, BigDecimal> utils3b = new HashMap<>();
     87                utils3b.put(new ProductOfValue(Arrays.asList(lo)), N07.multiply(N02));
     88                utils3b.put(new ProductOfValue(Arrays.asList(hi)), N08.multiply(N02));
     89                putils3b = new PartsUtilities(Arrays.asList(iss3), utils3b);
     90
     91                HashMap<String, PartsUtilities> partutils = new HashMap<>();
     92                partutils.put("1and2", putils12);
     93                partutils.put("3", putils3);
     94
     95                sog1 = new SumOfGroupsUtilitySpace(domain, "testspace", partutils,
     96                                resBid);
     97                sog1a = new SumOfGroupsUtilitySpace(domain, "testspace", partutils,
     98                                resBid);
     99                sog2 = new SumOfGroupsUtilitySpace(domain, "testspace2", partutils,
     100                                resBid);
     101
     102                // reuse partutils. Also checks that the values have been copied
     103                partutils = new HashMap<>();
     104                partutils.put("1and2", putils12);
     105                partutils.put("3", putils3b);
     106                sog3 = new SumOfGroupsUtilitySpace(domain, "testspace", partutils,
     107                                resBid);
     108
     109        }
     110
     111        @Override
     112        public List<List<SumOfGroupsUtilitySpace>> getGeneralTestData() {
     113                return Arrays.asList(Arrays.asList(sog1, sog1a), Arrays.asList(sog2),
     114                                Arrays.asList(sog3));
     115        }
     116
     117        @Override
     118        public List<String> getGeneralTestStrings() {
     119                return Arrays.asList(
     120                                "SumOfGroupsUtilitySpace.*testspace.*1and2.*PartsUtilities.*issue1.*issue2.*3.*PartsUtilities.*Bid.*issue1.*high.*",
     121                                "SumOfGroupsUtilitySpace.*testspace2.*1and2.*PartsUtilities.*issue1.*issue2.*3.*PartsUtilities.*Bid.*issue1.*high.*",
     122                                "SumOfGroupsUtilitySpace.*testspace.*1and2.*PartsUtilities.*issue1.*issue2.*3.*PartsUtilities.*Bid.*issue1.*high.*");
    80123        }
    81124
     
    161204                LinearAdditiveUtilitySpace las = jackson.readValue(profile,
    162205                                LinearAdditiveUtilitySpace.class);
    163                 SumOfGroupsUtilitySpace pas = new SumOfGroupsUtilitySpace(las);
     206                SumOfGroupsUtilitySpace pas = SumOfGroupsUtilitySpace.create(las);
    164207                checkUtilitiesAllEqual(las, pas);
    165208                System.out.println("Generated partial profile:\n" + pas);
     
    178221                LinearAdditiveUtilitySpace las = jackson.readValue(profile,
    179222                                LinearAdditiveUtilitySpace.class);
    180                 SumOfGroupsUtilitySpace pas = new SumOfGroupsUtilitySpace(las);
     223                SumOfGroupsUtilitySpace pas = SumOfGroupsUtilitySpace.create(las);
    181224                pas = pas.group(Arrays.asList("Food", "Drinks"), "food&drinks");
    182225                checkUtilitiesAllEqual(las, pas);
     
    235278        }
    236279
     280        @Test
     281        public void loadComputerBuy() throws IOException {
     282                UtilitySpace space = jackson.readValue(
     283                                getClass().getResourceAsStream("/computerbuy.json"),
     284                                UtilitySpace.class);
     285                assertTrue(space instanceof SumOfGroupsUtilitySpace);
     286
     287        }
     288
     289        @Test
     290        public void loadComputerSell() throws IOException {
     291                UtilitySpace space = jackson.readValue(
     292                                getClass().getResourceAsStream("/computersell.json"),
     293                                UtilitySpace.class);
     294                assertTrue(space instanceof LinearAdditiveUtilitySpace);
     295
     296        }
     297
     298        @Test(expected = ValueInstantiationException.class)
     299        public void loadComputerBuyIncomplete() throws IOException {
     300                UtilitySpace space = jackson.readValue(
     301                                getClass().getResourceAsStream("/computerbuyincomplete.json"),
     302                                UtilitySpace.class);
     303                assertTrue(space instanceof LinearAdditiveUtilitySpace);
     304
     305        }
     306
     307        @Test
     308        public void loadComputerBuyNumbers() throws IOException {
     309                UtilitySpace space = jackson.readValue(
     310                                getClass().getResourceAsStream("/computerbuynumbers.json"),
     311                                UtilitySpace.class);
     312                assertTrue(space instanceof SumOfGroupsUtilitySpace);
     313
     314        }
     315
     316        @Test
     317        public void testComputerBuyUtility()
     318                        throws JsonParseException, JsonMappingException, IOException {
     319                SumOfGroupsUtilitySpace space = jackson.readValue(
     320                                getClass().getResourceAsStream("/computerbuy.json"),
     321                                SumOfGroupsUtilitySpace.class);
     322                Bid bid = space.getReservationBid();
     323                assertEquals(new BigDecimal("0.625"), space.getUtility(bid));
     324        }
     325
    237326        /************************ PRIVATE FUNCTIONS *******************/
    238327
Note: See TracChangeset for help on using the changeset viewer.