package csp.smart; import edu.neu.ccs.demeterf.lib.*; import java.util.Random; import scg.Agreement; import scg.AvatarI; import scg.Claim; import scg.Config; import scg.InstanceI; import scg.OpposeAction; import scg.ProtocolI; import scg.Refuting; import scg.SolutionI; import scg.SolveRequest; import scg.Strengthening; import scg.Util; import scg.protocol.*; import csp.*; /** Representation of CSPAvatarSmart */ public class CSPAvatarSmart implements AvatarI{ /** Construct a(n) CSPAvatarSmart Instance */ public CSPAvatarSmart() { } /** Is the given object Equal to this CSPAvatarSmart? */ public boolean equals(Object o) { if (!(o instanceof CSPAvatarSmart)) return false; if (o == this) return true; return true; } /** Parse an instance of CSPAvatarSmart from the given String */ public static CSPAvatarSmart parse(String inpt) throws csp.avatar.ParseException { return new csp.avatar.TheParser(new java.io.StringReader(inpt)) .parse_CSPAvatarSmart(); } /** Parse an instance of CSPAvatarSmart from the given Stream */ public static CSPAvatarSmart parse(java.io.InputStream inpt) throws csp.avatar.ParseException { return new csp.avatar.TheParser(inpt).parse_CSPAvatarSmart(); } /** Parse an instance of CSPAvatarSmart from the given Reader */ public static CSPAvatarSmart parse(java.io.Reader inpt) throws csp.avatar.ParseException { return new csp.avatar.TheParser(inpt).parse_CSPAvatarSmart(); } private Config config; /** Constructor to be called during registration where you supply config */ public CSPAvatarSmart(Config cfg) { config = cfg; } /** * proposing claims by using our preferences which are not in the forbidden * list */ public List propose(List forbiddenClaims) { List claims = List.create(); Claim claim = null; ListSet base = ListSet. create(2); int m = 1; int n = 2; for (int i = 0; i < config.getScgCfg().getMaxProposals(); i++) { if (m < 255 && n < 255){ base = ListSet. create(m*2, n*2); Random rand = new Random(); boolean nextBoolean = rand.nextBoolean(); // while (base.size() <= 2) { // Try the preferences... for (Entry> pr : Tools.PREFS_MAP) { CSPInstanceSet instanceSet = new CSPInstanceSet(base.add(pr .getKey())); double quality = 1; double confidence = 1; claim = new Claim(instanceSet, nextBoolean ? PositiveSecret .getInstance() : NegativeSecret.getInstance(), quality, confidence); if (!forbiddenClaims.contains(claim)) { claim = new Claim(instanceSet, nextBoolean ? PositiveSecret.getInstance() : NegativeSecret.getInstance(), pr .getVal().getZ() - 0.01, pr.getVal() .getZ() - 0.01); } // } //base = base.add(2 + 2 * base.size()); } // Otherwise, settle for a random one while (forbiddenClaims.contains(claim)) { claim = generateRandomClaim(); } m++; n += 2; } else { while (forbiddenClaims.contains(claim)) { claim = generateRandomClaim(); } } claims = claims.append(claim); } return claims; } /** get claims */ private static List getClaims(List claims, java.util.List l, int i) { List cs = List.create(); if (i == l.size()-1) { return cs = claims.append(l.get(i)); } else { getClaims(claims.append(l.get(i)), l, ++i); } return cs; } private double minStrengthening = 0.05; /** Smart oppose method - try to refutes or strengthens, then agree */ public List oppose(List claimsToBeOpposed) { return claimsToBeOpposed.map(new List.Map() { public OpposeAction map(Claim claim) { double quality = claim.getQuality(); ListSet relNums = ((CSPInstanceSet) claim .getInstanceSet()).getType(); if (isRefutableRelNums(relNums)) return new Refuting(); else if (isStrengthenable(relNums, claim.getProtocol())) { // strengthen claim by a little step within [0,1] if (claim.getProtocol() instanceof PositiveSecret) { return strengthenPosClaim(quality, minStrengthening); } else { return strengthenNegClaim(quality, minStrengthening); } } else return new Agreement(); } }); } /** is the given instance set refutable? */ private boolean isRefutableRelNums(ListSet relNums) { return (isRelNumsOver127(relNums)) || (isRelNumsOdd(relNums)); } private boolean isRelNumsOver127(ListSet relNumsSet) { List relNums = relNumsSet.toList(); for (int i = 0; i < relNums.length(); i++) { if (isRelNumsOver127(((Integer) relNums.lookup(i)).intValue())) return true; } return false; } private boolean isRelNumsOdd(ListSet relNumsSet) { List relNums = relNumsSet.toList(); for (int i = 0; i < relNums.length(); i++) { if (isRelNumsOdd(((Integer) relNums.lookup(i)).intValue())) return true; } return false; } private boolean isRelNumsOver127(int relNum) { return relNum > 127; } private boolean isRelNumsOdd(int relNum) { return relNum % 2 == 1; } /** Is the given instance set strengthenable? */ private boolean isStrengthenable(ListSet relNums, ProtocolI protocol) { if (protocol instanceof PositiveSecret) { } else if (protocol instanceof NegativeSecret) { } return false; } /** * The minimumStrengthen will be halved when the new quality is out of range * [0,1] */ private OpposeAction strengthenPosClaim(double q, double min) { if (q > min) { return new Strengthening(q - min); } else return strengthenPosClaim(q, min / (double) 2); } private OpposeAction strengthenNegClaim(double q, double min) { if ((q + min) < 1) { return new Strengthening(q + min); } else return strengthenNegClaim(q, min / (double) 2); } /** * providing instance method - provides symmetric Instance of given * instanceSet */ public InstanceI provide(Claim claimToBeProvided) { CSPInstanceSet cspInstanceSet = (CSPInstanceSet) claimToBeProvided .getInstanceSet(); CSPConfig cfg = (CSPConfig) config.getDomainConfig(); int numVars = cfg.getMaxVariables(); List vars = List. create(); /** bug found here, fixed by vars = vars.append... and ident("v"... */ for (int i = 1; i <= numVars; i++) { vars = vars.append(new Var(new ident("v" + i))); } CSPInstance cspInstance = new CSPInstance(vars, Tools.symmetric( cspInstanceSet.getType().toList(), numVars, 3)); return cspInstance; } static final int NUM_ASSIGNS = 20; /** solve using random assignment of values to all the variables */ public SolutionI solve(SolveRequest solveRequest) { CSPInstance i = (CSPInstance) solveRequest.getInstance(); Claim claim = solveRequest.getClaim().inner(); double confidence = claim.getConfidence(); double quality = claim.getQuality(); Best best = findBest(i); double prof = Tools.payback(confidence, best.quality, quality) - confidence; if (prof < 0) { Tools.updatePreferences(i, best.quality); } CSPSolution solution = new CSPSolution(ListMap.create(best.assign)); return solution; } public static class Best { public double quality; public List> assign; Best() { this(-1.0, null); } Best(double q, List> a) { quality = q; assign = a; } } /** Solve the given Problem Instance */ Best findBest(final CSPInstance i) { long t1 = System.currentTimeMillis(); int turnDuration = config.getScgCfg().getTurnDuration(); long timeAllowed = turnDuration * 1000; return findBest(i, NUM_ASSIGNS, timeAllowed, t1); } /** Solve the given Problem Instance, using "times" random asssginments */ public static Best findBest(final CSPInstance p, int times, long timeAllowed, long t1) { final List vars = usedVars(p); Best temp = new Best(); for (int i = 0; i < times; i++) { long t2 = System.currentTimeMillis(); long timeLeft = t2 -t1; if (timeLeft < timeAllowed - 20000) { Best best = List.buildlist( new List.Build>>() { public List> build(int i) { return randomAssign(vars, Util.random());// PARTITIONS)/(double)PARTITIONS); } }, times).fold( new List.Fold>, Best>() { public Best fold(List> s, Best b) { if (b.quality == 1.0) return b; double qual = Tools.quality(p, s); if (qual < b.quality) return b; return new Best(qual, s); } }, new Best()); if (best.quality > temp.quality) temp = best; } else { return temp; } } return temp; } /** Used Variables from a Problem Instance */ static List usedVars(CSPInstance p) { return p.getVars(); } /** Random Assignment to each of the variables */ public static List> randomAssign(List vs, final double bias) { return vs.map(new List.Map>() { public Entry map(Var v) { return Entry.create(v, Util.coinFlip(bias)); } }); } private Random random = new Random(); private Claim generateRandomClaim() { Random rand = new Random(); boolean nextBoolean = rand.nextBoolean(); ListSet type = ListSet.create(); CSPConfig cfg = (CSPConfig) config.getDomainConfig(); if (cfg.getMaxRelNum() >= 127) type = type.add(127); type = type.add(rand.nextInt(cfg.getMaxRelNum())); CSPInstanceSet instanceSet = new CSPInstanceSet(type); return new Claim(instanceSet, nextBoolean ? PositiveSecret .getInstance() : NegativeSecret.getInstance(), random.nextDouble(), random.nextDouble()); } /** N choose K, the dynamic programming way! ;) */ public static List> combs(int n, int k, List.Build b){ List>[][] tbl = new List[n+1][k+1]; for(int ik = 0; ik <= k; ik++) for(int in = 0; in <= n; in++){ List> newlst; if(ik == 0) newlst = List.>create(List.create()); else if(in < ik)newlst = List.create(); else newlst = tbl[in-1][ik].append(tbl[in-1][ik-1].map(new PushN(b.build(in)))); tbl[in][ik] = newlst; } return tbl[n][k]; } /** Sort the relations to find the most important one... */ public static int importantRelation(CSPInstanceSet t){ int rel = t.getType().toList().sort(new List.Comp(){ public boolean comp(Integer ra, Integer rb){ return (// Implied ((ra & rb) == ra) || // A is even, B is odd (ra%2 == 0 && rb%2 == 1) || // Both even or both odd ((ra%2 == rb%2) && bitsSet(ra) < bitsSet(rb))); } }).top(); return rel; } /** Determin the number of bits set in the given relation number */ public static int bitsSet(int i){ int c = 0; while(i > 0){ if((i&1) > 0)c++; i >>= 1; } return c; } /** Push the given number onto the front of each list */ private static class PushN extends List.Map,List>{ X x; public PushN(X xx){ x = xx; } public List map(List l){ return l.push(x); } } /** DGP method from Class Display */ public String display(){ return csp.avatar.Display.DisplayM(this); } /** DGP method from Class Print */ public String print(){ return csp.avatar.Print.PrintM(this); } /** DGP method from Class ToStr */ public String toStr(){ return csp.avatar.ToStr.ToStrM(this); } /** DGP method from Class PrintToString */ public String toString(){ return csp.avatar.PrintToString.PrintToStringM(this); } }