environment_XXX.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008, Maxim Likhachev
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions are met:
00007  * 
00008  *     * Redistributions of source code must retain the above copyright
00009  *       notice, this list of conditions and the following disclaimer.
00010  *     * Redistributions in binary form must reproduce the above copyright
00011  *       notice, this list of conditions and the following disclaimer in the
00012  *       documentation and/or other materials provided with the distribution.
00013  *     * Neither the name of the University of Pennsylvania nor the names of its
00014  *       contributors may be used to endorse or promote products derived from
00015  *       this software without specific prior written permission.
00016  * 
00017  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00018  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00021  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00022  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00023  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00024  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00025  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00026  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00027  * POSSIBILITY OF SUCH DAMAGE.
00028  */
00029 #include <iostream>
00030 using namespace std;
00031 
00032 #include "../../sbpl/headers.h"
00033 
00034 
00035 
00036 //extern clock_t time3_addallout;
00037 //extern clock_t time_gethash;
00038 //extern clock_t time_createhash;
00039 
00040 
00041 //function prototypes
00042 
00043 
00044 //-------------------problem specific and local functions---------------------
00045 
00046 
00047 static unsigned int inthash(unsigned int key)
00048 {
00049   key += (key << 12);
00050   key ^= (key >> 22);
00051   key += (key << 4);
00052   key ^= (key >> 9);
00053   key += (key << 10);
00054   key ^= (key >> 2);
00055   key += (key << 7);
00056   key ^= (key >> 12);
00057   return key;
00058 }
00059 
00060 //examples of hash functions: map state coordinates onto a hash value
00061 //#define GETHASHBIN(X, Y) (Y*WIDTH_Y+X) 
00062 //here we have state coord: <X1, X2, X3, X4>
00063 unsigned int EnvironmentXXX::GETHASHBIN(unsigned int X1, unsigned int X2, 
00064                                                 unsigned int X3, unsigned int X4)
00065 {
00066 
00067         return inthash((inthash(X1)+(inthash(X2)<<1)+(inthash(X3)<<2)+(inthash(X4)<<3))) & (EnvXXX.HashTableSize-1);
00068 }
00069 
00070 
00071 
00072 void EnvironmentXXX::PrintHashTableHist()
00073 {
00074         int s0=0, s1=0, s50=0, s100=0, s200=0, s300=0, slarge=0;
00075 
00076         for(int  j = 0; j < (int)EnvXXX.HashTableSize; j++)
00077         {
00078                 if((int)EnvXXX.Coord2StateIDHashTable[j].size() == 0)
00079                         s0++;
00080                 else if((int)EnvXXX.Coord2StateIDHashTable[j].size() < 50)
00081                         s1++;
00082                 else if((int)EnvXXX.Coord2StateIDHashTable[j].size() < 100)
00083                         s50++;
00084                 else if((int)EnvXXX.Coord2StateIDHashTable[j].size() < 200)
00085                         s100++;
00086                 else if((int)EnvXXX.Coord2StateIDHashTable[j].size() < 300)
00087                         s200++;
00088                 else if((int)EnvXXX.Coord2StateIDHashTable[j].size() < 400)
00089                         s300++;
00090                 else
00091                         slarge++;
00092         }
00093         SBPL_PRINTF("hash table histogram: 0:%d, <50:%d, <100:%d, <200:%d, <300:%d, <400:%d >400:%d\n",
00094                 s0,s1, s50, s100, s200,s300,slarge);
00095 }
00096 
00097 void EnvironmentXXX::ReadConfiguration(FILE* fCfg)
00098 {
00099         //read in the configuration of environment and initialize  EnvCfg structure
00100 
00101 }
00102 
00103 
00104 void EnvironmentXXX::InitializeEnvConfig()
00105 {
00106         //aditional to configuration file initialization of EnvCfg if necessary
00107 
00108 }
00109 
00110 
00111 EnvXXXHashEntry_t* EnvironmentXXX::GetHashEntry(unsigned int X1, unsigned int X2, 
00112                                                                         unsigned int X3, unsigned int X4)
00113 {
00114         //clock_t currenttime = clock();
00115 
00116         int binid = GETHASHBIN(X1, X2, X3, X4);
00117         
00118 #if DEBUG
00119         if ((int)EnvXXX.Coord2StateIDHashTable[binid].size() > 500)
00120         {
00121                 SBPL_PRINTF("WARNING: Hash table has a bin %d (X1=%d X2=%d X3=%d X4=%d) of size %d\n", 
00122                         binid, X1, X2, X3, X4, EnvXXX.Coord2StateIDHashTable[binid].size());
00123                 
00124                 PrintHashTableHist();           
00125         }
00126 #endif
00127 
00128         //iterate over the states in the bin and select the perfect match
00129         for(int ind = 0; ind < (int)EnvXXX.Coord2StateIDHashTable[binid].size(); ind++)
00130         {
00131                 if( EnvXXX.Coord2StateIDHashTable[binid][ind]->X1 == X1 
00132                         && EnvXXX.Coord2StateIDHashTable[binid][ind]->X2 == X2
00133                         && EnvXXX.Coord2StateIDHashTable[binid][ind]->X3 == X3 
00134                         && EnvXXX.Coord2StateIDHashTable[binid][ind]->X4 == X4)
00135                 {
00136                         //time_gethash += clock()-currenttime;
00137                         return EnvXXX.Coord2StateIDHashTable[binid][ind];
00138                 }
00139         }
00140         
00141         //time_gethash += clock()-currenttime;
00142 
00143         return NULL;      
00144 }
00145 
00146 
00147 EnvXXXHashEntry_t* EnvironmentXXX::CreateNewHashEntry(unsigned int X1, unsigned int X2, 
00148                                                                                                 unsigned int X3, unsigned int X4)
00149 {
00150         int i;
00151         
00152         //clock_t currenttime = clock();
00153 
00154         EnvXXXHashEntry_t* HashEntry = new EnvXXXHashEntry_t;
00155 
00156         HashEntry->X1 = X1;
00157         HashEntry->X2 = X2;
00158         HashEntry->X3 = X3;
00159         HashEntry->X4 = X4;
00160 
00161         HashEntry->stateID = EnvXXX.StateID2CoordTable.size();
00162 
00163         //insert into the tables
00164         EnvXXX.StateID2CoordTable.push_back(HashEntry);
00165 
00166 
00167         //get the hash table bin
00168         i = GETHASHBIN(HashEntry->X1, HashEntry->X2, 
00169                 HashEntry->X3, HashEntry->X4);
00170 
00171         //insert the entry into the bin
00172         EnvXXX.Coord2StateIDHashTable[i].push_back(HashEntry);
00173 
00174         //insert into and initialize the mappings
00175         int* entry = new int [NUMOFINDICES_STATEID2IND];
00176         StateID2IndexMapping.push_back(entry);
00177         for(i = 0; i < NUMOFINDICES_STATEID2IND; i++)
00178         {
00179                 StateID2IndexMapping[HashEntry->stateID][i] = -1;
00180         }
00181 
00182         if(HashEntry->stateID != (int)StateID2IndexMapping.size()-1)
00183         {
00184                 SBPL_ERROR("ERROR in Env... function: last state has incorrect stateID\n");
00185                 throw new SBPL_Exception();     
00186         }
00187 
00188 
00189         //time_createhash += clock()-currenttime;
00190 
00191         return HashEntry;
00192 }
00193 
00194 
00195 void EnvironmentXXX::CreateStartandGoalStates()
00196 {
00197         EnvXXXHashEntry_t* HashEntry;
00198 
00199         //create start state 
00200         unsigned int X1 = 0;
00201         unsigned int X2 = 0;
00202         unsigned int X3 = 0;
00203         unsigned int X4 = 0;
00204         HashEntry = CreateNewHashEntry(X1, X2, X3, X4);
00205         EnvXXX.startstateid = HashEntry->stateID;
00206 
00207         //create goal state 
00208         X1 = X2 = X3 = X4 = 1;
00209         HashEntry = CreateNewHashEntry(X1, X2, X3, X4);
00210         EnvXXX.goalstateid = HashEntry->stateID;
00211 }
00212 
00213 
00214 void EnvironmentXXX::InitializeEnvironment()
00215 {
00216 
00217         //initialize the map from Coord to StateID
00218         EnvXXX.HashTableSize = 32*1024; //should be power of two
00219         EnvXXX.Coord2StateIDHashTable = new vector<EnvXXXHashEntry_t*>[EnvXXX.HashTableSize];
00220         
00221         //initialize the map from StateID to Coord
00222         EnvXXX.StateID2CoordTable.clear();
00223 
00224         //create start and goal states
00225         CreateStartandGoalStates();
00226 }
00227 
00228 
00229 void EnvironmentXXX::AddAllOutcomes(unsigned int SourceX1, unsigned int SourceX2, unsigned int SourceX3,
00230                                         unsigned int SourceX4, CMDPACTION* action, int cost)
00231 {
00232         EnvXXXHashEntry_t* OutHashEntry;
00233         int i;
00234         float CumProb = 0.0;
00235 
00236         //iterate over outcomes
00237         for(i = 0; i < 2; i++)
00238         {
00239                 unsigned int newX1 = SourceX1+i;
00240                 unsigned int newX2 = SourceX2+i;
00241                 unsigned int newX3 = SourceX3+i;
00242                 unsigned int newX4 = SourceX4+i;
00243 
00244                 //add the outcome
00245                 if((OutHashEntry = GetHashEntry(newX1, newX2, 
00246                                                                                 newX3, newX4)) == NULL)
00247                 {
00248                         //have to create a new entry
00249                         OutHashEntry = CreateNewHashEntry(newX1, newX2, 
00250                                                                           newX3, newX4);
00251                 }
00252                 float Prob = 0.5; //probability of the outcome
00253                 action->AddOutcome(OutHashEntry->stateID, cost, Prob); 
00254                 CumProb += Prob;
00255 
00256         } //while
00257 
00258         if(CumProb != 1.0)
00259         {
00260                 SBPL_ERROR("ERROR in EnvXXX... function: prob. of all action outcomes=%f\n", CumProb);
00261                 throw new SBPL_Exception();
00262         }
00263 
00264 }
00265 
00266 
00267 //------------------------------------------------------------------------------
00268 
00269 //------------------------------Heuristic computation--------------------------
00270 
00271 void EnvironmentXXX::ComputeHeuristicValues()
00272 {
00273         //whatever necessary pre-computation of heuristic values is done here 
00274         SBPL_PRINTF("Precomputing heuristics\n");
00275         
00276 
00277 
00278         SBPL_PRINTF("done\n");
00279 
00280 }
00281 
00282 //-----------interface with outside functions-----------------------------------
00283 bool EnvironmentXXX::InitializeEnv(const char* sEnvFile)
00284 {
00285 
00286         FILE* fCfg = fopen(sEnvFile, "r");
00287         if(fCfg == NULL)
00288         {
00289                 SBPL_ERROR("ERROR: unable to open %s\n", sEnvFile);
00290                 throw new SBPL_Exception();
00291         }
00292         ReadConfiguration(fCfg);
00293   fclose(fCfg);
00294 
00295         //Initialize other parameters of the environment
00296         InitializeEnvConfig();
00297 
00298         //initialize Environment
00299         InitializeEnvironment();
00300 
00301         //pre-compute heuristics
00302         ComputeHeuristicValues();
00303 
00304         return true;
00305 }
00306 
00307 
00308 bool EnvironmentXXX::InitializeMDPCfg(MDPConfig *MDPCfg)
00309 {
00310         //initialize MDPCfg with the start and goal ids 
00311         MDPCfg->goalstateid = EnvXXX.goalstateid;
00312         MDPCfg->startstateid = EnvXXX.startstateid;
00313 
00314         return true;
00315 }
00316 
00317 
00318 
00319 int EnvironmentXXX::GetFromToHeuristic(int FromStateID, int ToStateID)
00320 {
00321 #if USE_HEUR==0
00322         return 0;
00323 #endif
00324 
00325 
00326 #if DEBUG
00327         if(FromStateID >= (int)EnvXXX.StateID2CoordTable.size() 
00328                 || ToStateID >= (int)EnvXXX.StateID2CoordTable.size())
00329         {
00330                 SBPL_ERROR("ERROR in EnvXXX... function: stateID illegal\n");
00331                 throw new SBPL_Exception();
00332         }
00333 #endif
00334 
00335         //define this function if it is used in the planner 
00336 
00337         SBPL_ERROR("ERROR in EnvXXX.. function: FromToHeuristic is undefined\n");
00338         throw new SBPL_Exception();
00339 
00340         return 0;       
00341 
00342 }
00343 
00344 
00345 int EnvironmentXXX::GetGoalHeuristic(int stateID)
00346 {
00347 #if USE_HEUR==0
00348         return 0;
00349 #endif
00350 
00351 #if DEBUG
00352         if(stateID >= (int)EnvXXX.StateID2CoordTable.size())
00353         {
00354                 SBPL_ERROR("ERROR in EnvXXX... function: stateID illegal\n");
00355                 throw new SBPL_Exception();
00356         }
00357 #endif
00358 
00359 
00360         //define this function if it used in the planner (heuristic forward search would use it)
00361 
00362         SBPL_ERROR("ERROR in EnvXXX..function: GetGoalHeuristic is undefined\n");
00363         throw new SBPL_Exception();
00364 }
00365 
00366 
00367 int EnvironmentXXX::GetStartHeuristic(int stateID)
00368 {
00369 #if USE_HEUR==0
00370         return 0;
00371 #endif
00372 
00373 
00374 #if DEBUG
00375         if(stateID >= (int)EnvXXX.StateID2CoordTable.size())
00376         {
00377                 SBPL_ERROR("ERROR in EnvXXX... function: stateID illegal\n");
00378                 throw new SBPL_Exception();
00379         }
00380 #endif
00381 
00382         //define this function if it used in the planner (heuristic backward search would use it)
00383 
00384         SBPL_ERROR("ERROR in EnvXXX.. function: GetStartHeuristic is undefined\n");
00385         throw new SBPL_Exception();
00386 
00387         return 0;       
00388 
00389 
00390 }
00391 
00392 
00393 
00394 void EnvironmentXXX::SetAllActionsandAllOutcomes(CMDPSTATE* state)
00395 {
00396 
00397 
00398 #if DEBUG
00399         if(state->StateID >= (int)EnvXXX.StateID2CoordTable.size())
00400         {
00401                 SBPL_ERROR("ERROR in EnvXXX... function: stateID illegal\n");
00402                 throw new SBPL_Exception();
00403         }
00404 
00405         if((int)state->Actions.size() != 0)
00406         {
00407                 SBPL_ERROR("ERROR in Env_setAllActionsandAllOutcomes: actions already exist for the state\n");
00408                 throw new SBPL_Exception();
00409         }
00410 #endif
00411         
00412         //if it is goal then no successors
00413         if(state->StateID == EnvXXX.goalstateid)
00414                 return;
00415 
00416         //get values for the state
00417         EnvXXXHashEntry_t* HashEntry = EnvXXX.StateID2CoordTable[state->StateID];
00418 
00419         //iterate through the actions for the state
00420         for (int aind = 0; aind < XXX_MAXACTIONSWIDTH; aind++)
00421         {
00422                 int cost = 1;
00423 
00424                 //Add Action
00425                 CMDPACTION* action = state->AddAction(aind);
00426 
00427                 //clock_t currenttime = clock();
00428                 //add all the outcomes to the action
00429                 AddAllOutcomes(HashEntry->X1, HashEntry->X2, HashEntry->X3, HashEntry->X4, action, cost); 
00430 
00431                 //you can break if the number of actual actions is smaller than the maximum possible
00432 
00433                 //time3_addallout += clock()-currenttime;
00434         }
00435 }
00436 
00437 
00438 
00439 void EnvironmentXXX::SetAllPreds(CMDPSTATE* state)
00440 {
00441         //implement this if the planner needs access to predecessors
00442         
00443         SBPL_ERROR("ERROR in EnvXXX... function: SetAllPreds is undefined\n");
00444         throw new SBPL_Exception();
00445 }
00446 
00447 
00448 void EnvironmentXXX::GetSuccs(int SourceStateID, vector<int>* SuccIDV, vector<int>* CostV)
00449 {
00450 
00451         SBPL_ERROR("ERROR in EnvXXX... function: GetSuccs is undefined\n");
00452         throw new SBPL_Exception();
00453 }
00454 
00455 void EnvironmentXXX::GetPreds(int TargetStateID, vector<int>* PredIDV, vector<int>* CostV)
00456 {
00457 
00458         SBPL_ERROR("ERROR in EnvXXX... function: GetPreds is undefined\n");
00459         throw new SBPL_Exception();
00460 }
00461 
00462 
00463 int EnvironmentXXX::SizeofCreatedEnv()
00464 {
00465         return (int)EnvXXX.StateID2CoordTable.size();
00466         
00467 }
00468 
00469 void EnvironmentXXX::PrintState(int stateID, bool bVerbose, FILE* fOut /*=NULL*/)
00470 {
00471 #if DEBUG
00472         if(stateID >= (int)EnvXXX.StateID2CoordTable.size())
00473         {
00474                 SBPL_ERROR("ERROR in EnvXXX... function: stateID illegal (2)\n");
00475                 throw new SBPL_Exception();
00476         }
00477 #endif
00478 
00479         if(fOut == NULL)
00480                 fOut = stdout;
00481 
00482         EnvXXXHashEntry_t* HashEntry = EnvXXX.StateID2CoordTable[stateID];
00483 
00484         if(stateID == EnvXXX.goalstateid)
00485         {
00486                 SBPL_FPRINTF(fOut, "the state is a goal state\n");
00487         }
00488 
00489         SBPL_FPRINTF(fOut, "X1=%d X2=%d X3=%d X4=%d\n", 
00490                 HashEntry->X1, HashEntry->X2,
00491                 HashEntry->X3, HashEntry->X4);
00492 
00493 
00494 }
00495 
00496 
00497 void EnvironmentXXX::PrintEnv_Config(FILE* fOut)
00498 {
00499 
00500         //implement this if the planner needs to print out EnvXXX. configuration
00501         
00502         SBPL_ERROR("ERROR in EnvXXX... function: PrintEnv_Config is undefined\n");
00503         throw new SBPL_Exception();
00504 
00505 }
00506 //------------------------------------------------------------------------------
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


sbpl
Author(s): Maxim Likhachev/maximl@seas.upenn.edu
autogenerated on Fri Jan 18 2013 13:41:53