/* ********************************** * FinishAgent.java * Finish a given Raw Material * **********************************/ package player.playeragent; import player.*; import edu.neu.ccs.demeterf.demfgen.lib.*; import edu.neu.ccs.demeterf.*; import gen.*; /** Class for finishing a list of derivatives */ public class FinishAgent implements PlayerI.FinishAgentI{ static Sign pos = new Pos(), neg = new Neg(); static int NUM_ASSIGNS = 60; /** Calculate the finished product for a given Derivative */ public FinishedProduct finishDerivative(Derivative d){ Best best = bestAssign(d); double profit = hidden.Tools.payback(d,best.quality) - d.price.val; Util.display(Util.color("Finishing","green")+" : "+ Util.color(Util.tag(((profit > 0)?"Profit":"Loss")+" = "+Util.format(profit),"b"), (profit > 0)?"green":"red")); return new FinishedProduct(new IntermediateProduct(best.assign), new Quality(best.quality)); } /** Helps to collect the Best assignment */ public static class Best{ public double quality; public Assignment assign; Best(){ this(-1.0, null); } Best(double q, Assignment a){ quality = q; assign = a; } } /** Find the best random assignment for a delivered derivative */ public static Best bestAssign(Derivative d){ return bestAssign(d.optraw.inner().instance, NUM_ASSIGNS); } /** Find the best random assignment for a rawMaterial */ public static Best bestAssign(final RawMaterialInstance rm, int attempts){ final Set<ident> ids = usedVars(rm); List<Assignment> assigns = List.buildlist(new List.Build<Assignment>(){ public Assignment build(int i){ return new Assignment(randomAssign(ids, Util.random())); } }, attempts); return bestAssign(assigns, rm); } /** Select the best (highest wuality) assignment from the list */ private static Best bestAssign(List<Assignment> assigns, final RawMaterialInstance rmi){ return assigns.fold(new List.Fold<Assignment, Best>(){ public Best fold(Assignment a, Best b){ double qual = hidden.Tools.quality(rmi, a); if(qual < b.quality)return b; return new Best(qual,a); } }, new Best()); } /** Create a random assignment using the given set of idents, with a fair coin */ private static List<Literal> randomAssign(Set<ident> ids){ return randomAssign(ids,0.5); } /** Create a random assignment using the given set of idents, with a biased coin */ private static List<Literal> randomAssign(Set<ident> ids, final double bias){ return ids.toList().map(new List.Map<ident, Literal>(){ public Literal map(ident id){ return new Literal((Util.coinFlip(bias)?pos:neg),new Variable(id)); } }); } /** Find the set of all variables used in the given dirivative's raw material */ private static Set<ident> usedVars(RawMaterialInstance rmi){ return new StaticTrav(new TUCombiner<Set<ident>>(){ public Set<ident> combine(){ return Set.<ident>create(); } public Set<ident> fold(Set<ident> a, Set<ident> b){ return a.union(b); } Set<ident> combine(ident id){ return Set.<ident>create(List.create(id)); } }).traverseRawMaterialInstance(rmi); } }