public Solution copy() { double []newArray = new double[m_card]; Array.Copy(m_data, 0, newArray, 0, m_card); Solution s = new Solution(newArray, this.m_state); s.m_through = this.m_through; return s; }
public void add(Solution a_element) { //Additions are (asc) ordered by the value of the first element of the array. bool here = false; int i = 0; while(!here && i < m_members.Count) { Solution m = m_members[i]; if(a_element.m_data[0] < m.m_data[0]) { here = true; m_members.Insert(i,a_element); } ++i; } if(!here) { //add at the end: m_members.Add(a_element); } }
public bool add(Solution a_sol) { //Check if the new entry is dominated by any in the set: bool dominated = false; bool dominatesAny = false; bool crowded = false; int i = 0; while (!dominated && i < m_members.size()) { Solution member = m_members.get(i); int dom = Utils.dominates(member.m_data, a_sol.m_data); //if(dom == -1) if (dom == -1) { //if(crowded) // System.out.println("OUT ["+m_members.size()+"]"); dominated = true; } else if (dom == 1) { //This one is dominated. It must be out. m_members.remove(i); m_hvClean = false; dominatesAny = true; //And keep the index in place: --i; } else if (dom == 2) //Use this line to allow any distance between points in pareto. //}else if(dom == 2 || crowded) //Use this line to avoid crowded fronts (min. distance: EPSILON). { //There is another identical member in the set. Do NOT include: return false; } else if (dom == 0) { //crowded |= Utils.crowded(member.m_data, a_sol.m_data, EPSILON); } ++i; } if (dominatesAny) crowded = false; if (!dominated && !crowded) { /*double[] newOne = new double[a_candidate.length]; System.arraycopy(a_candidate, 0, newOne, 0, a_candidate.length); Solution newSol = new Solution(newOne); */ //Helpfunctions.Instance.logg("Yes added sol:" + a_sol.m_data[0] + ", " + a_sol.m_data[1] + ", " + a_sol.m_data[2]); //a_sol.m_state.printLastTurnActions(); m_members.add(a_sol); m_hvClean = false; return true; } else { //Helpfunctions.Instance.logg("No added sol:" + a_sol.m_data[0] + ", " + a_sol.m_data[1]); } return false; }
//public void advance(Playfield st, int action) //{ // bool gameOver = false; // for(int singleAction = 0; !gameOver && singleAction < ParetoMCTSParameters.MACRO_ACTION_LENGTH; ++singleAction) // { // //((ParetoMCTSPlayer)m_player).m_heightMap[(int)st.getShip().s.x][(int)st.getShip().s.y]++; // st.tick(action); // NEXT_TICKS++; // gameOver = st.isEnded(); // } //} //public bool finishRollout(Game rollerState, int depth, int action) //{ // if(depth >= ParetoMCTSParameters.ROLLOUT_DEPTH) //rollout end condition. // return true; // if(action == -1) //end // return true; // if(rollerState.isEnded()) //end of game // { // //Console.WriteLine("End Reached!"); // return true; // } // return false; //} public void backUp(double[] result, Solution sol, bool Added, int cI) { /*nVisits++; Added = pa.Add(result); int comingFrom = cI; for(int i = 0; i < result.Length; ++i) totValue[i] += result[i]; */ //for(ParetoTreeNode pn : m_runList) int comingFrom = -1; int numNodes = m_runList.Count; for(int i = 0; i < numNodes; ++i) { ParetoTreeNode pn = m_runList[i]; //Helpfunctions.Instance.logg("node: " + pn.parent.nodeNum + ", children exhasuted: " + pn.parent.numExhaustedChildren + "/" + pn.parent.children.Length); if (pn.isTerminal || (pn.children != null && pn.numExhaustedChildren == pn.children.Length)) { pn.isExhausted = true; if (pn.parent != null) { pn.parent.numExhaustedChildren++; } } pn.nVisits++; if(Added) Added = pn.pa.add(sol); for(int j = 0; j < result.Length; ++j) pn.totValue[j] += result[j]; if(i+1 < numNodes) { //ParetoTreeNode parentNode = m_runList.get(i+1); //parentNode.m_childCount[pn.childIndex]++; //for Nsa in one of the tree policies (see TransParetoTreePolicy). comingFrom = pn.childIndex; } else if(i+1 == numNodes) { if(pn.parent != null) throw new Exception("This should be the root... and it's not."); if(Added) { //Console.WriteLine("AddING (" + result[0] + "," + result[1] + ") to child " + comingFrom + " from " + pn.parent); if(comingFrom != -1) { sol.m_through = comingFrom; pn.valueRoute[comingFrom].Add(sol); } } } } }
public void mctsSearch(long a_timeDue) { //TODO: prune bad boards: 1. we will die next turn, 2. we will die this turn long remaining = a_timeDue - DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; NEXT_TICKS=0; int numIters = 500; double invIters = 0.0; //if(treePolicy is ParetoEGreedyTreePolicy) //{ // ((ParetoEGreedyTreePolicy) treePolicy).epsilon = 0.1; // invIters = 0.1/numIters; //} for (int i = 0; i < numIters; i++) { //while(remaining > 10) { //while(remaining > 0) { m_runList.Clear(); m_runList.Add(this); //root always in. //m_pi.reset(this.state); if (this.isExhausted) { //Helpfunctions.Instance.logg("exit at num: " + i); break; //if all exhausted, then return } ParetoTreeNode selected = treePolicy(); AddPlayoutInfoTree(); //double[] delta = selected.rollOut(); Playfield endTurnState = selected.rollOut(); //double[] delta = m_player.getHeuristic().value(endTurnState); double[] delta = null; switch (m_player.heuristicType) { case HeuristicType.Boardvalue: delta = new double[] { endTurnState.getBoardValue(), -endTurnState.getEnemyBoardValue(), endTurnState.getHandMinionValue() }; break; case HeuristicType.LethalCheck: delta = new double[] { endTurnState.getLethalScore()}; break; } //double[] delta = new double[] {endTurnState.getBoardValue(), -endTurnState.getEnemyBoardValue(), endTurnState.getHandMinionValue()}; //endTurnState.printBoard(); Solution deltaSol = new Solution(delta, endTurnState); selected.backUp(delta, deltaSol, true, selected.childIndex); m_numIters++; remaining = a_timeDue - DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; //if(treePolicy is ParetoEGreedyTreePolicy) //{ // ((ParetoEGreedyTreePolicy) treePolicy).epsilon -= invIters; //} if (m_player.heuristicType == HeuristicType.LethalCheck && (deltaSol.m_data[0] == 1.0 || deltaSol.m_data[0] == 0)) //we got lethal { int debug = 1; return; } } //Helpfunctions.Instance.logg("normal exit: 500"); }