You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
855 lines
22 KiB
855 lines
22 KiB
//==============================================================================
|
|
//
|
|
// Copyright (c) 2004-2005, Andrew Hinton
|
|
//
|
|
// This file is part of PRISM.
|
|
//
|
|
// PRISM is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation; either version 2 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// PRISM is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with PRISM; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
//==============================================================================
|
|
|
|
#include "simpath.h"
|
|
#include "simpctl.h"
|
|
#include "simupdater.h"
|
|
#include "simreasoning.h"
|
|
#include "simmodel.h"
|
|
#include "simutil.h"
|
|
#include <stdio.h>
|
|
#include <iostream>
|
|
|
|
using std::cout;
|
|
using std::endl;
|
|
|
|
//============================================================================
|
|
// Description
|
|
//============================================================================
|
|
|
|
/*
|
|
* This interface provides the means to explore the state space of the
|
|
* current model. It remembers a path through the state space by storing
|
|
* all relevant information about it in a vector of CPathState objects.
|
|
* The path can be generated either manually (by selecting an update from
|
|
* the update set for the current state or by requesting that the simulator
|
|
* engine make a number of random updates.
|
|
*/
|
|
|
|
//============================================================================
|
|
// Local Data
|
|
//============================================================================
|
|
|
|
vector<CPathState*> stored_path; // the path itself
|
|
CPathLoopDetectionHandler* loop_detection; //loop detection for paths
|
|
int current_index; //refers to the current index
|
|
double path_timer; //the time taken to execute this path
|
|
double *path_cost; //the total costs accumulated for this path
|
|
double *total_state_cost; //the total state costs for this path
|
|
double *total_transition_cost; //the total transition costs for this path
|
|
|
|
//=============================================================================
|
|
// Class Definitions
|
|
//=============================================================================
|
|
|
|
CPathLoopDetectionHandler::CPathLoopDetectionHandler()
|
|
{
|
|
exploring_deterministically = false;
|
|
start_loop = -1;
|
|
end_loop = -1;
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
deadlock = false;
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Reset()
|
|
{
|
|
exploring_deterministically = false;
|
|
start_loop = -1;
|
|
end_loop = -1;
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
deadlock = false;
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Start_New_Deterministic_Path()
|
|
{
|
|
exploring_deterministically = true;
|
|
start_loop = current_index;
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Notify_State(int* state_variables)
|
|
{
|
|
}
|
|
|
|
int CPathLoopDetectionHandler::Path_Size()
|
|
{
|
|
if(start_loop == -1) return 0;
|
|
else
|
|
{
|
|
return (current_index-start_loop)+1;
|
|
}
|
|
}
|
|
|
|
int* CPathLoopDetectionHandler::Path_At(int i)
|
|
{
|
|
return stored_path[i+start_loop]->variables;
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Notify_Deterministic_Path_End()
|
|
{
|
|
exploring_deterministically = false;
|
|
start_loop = -1;
|
|
end_loop = -1;
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Backtrack(int step)
|
|
{
|
|
// if there is no current deterministic path, nothing to do
|
|
if (!exploring_deterministically) return;
|
|
|
|
// if we are backtracking further than the start of the current deterministic path,
|
|
// then this path ends
|
|
if (step < start_loop) {
|
|
Notify_Deterministic_Path_End();
|
|
}
|
|
// otherwise we have to re-establish if we are looping
|
|
else {
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
Notify_Deterministic_State(false);
|
|
}
|
|
}
|
|
|
|
void CPathLoopDetectionHandler::Remove_Preceding_States(int step)
|
|
{
|
|
// if there is no current deterministic path, nothing to do
|
|
if (!exploring_deterministically) return;
|
|
|
|
// if the new start of the path falls inside the current deterministic path,
|
|
// adjust start of deterministic path accordingly and re-establish if we are looping
|
|
if (step >= start_loop) {
|
|
start_loop = 0;
|
|
proven_looping = false;
|
|
proven_loop_start = -1;
|
|
Notify_Deterministic_State(false);
|
|
}
|
|
// otherwise just shift start of path
|
|
else {
|
|
start_loop -= step;
|
|
}
|
|
}
|
|
|
|
//============================================================================
|
|
// Local Function Declarations
|
|
//============================================================================
|
|
|
|
/*
|
|
* Function which performs all of the necessary update calculations to add
|
|
* the current state of state_variables to the path.
|
|
*/
|
|
void Add_Current_State_To_Path();
|
|
|
|
int Calculate_Old_Choice_Made(int step);
|
|
|
|
/*
|
|
* Recalculates all of the registered path formulae for the current path.
|
|
*/
|
|
void Recalculate_Path_Formulae();
|
|
|
|
//=============================================================================
|
|
// Functions
|
|
//=============================================================================
|
|
|
|
/*
|
|
* Removes the path from memory.
|
|
*/
|
|
void Deallocate_Path()
|
|
{
|
|
if(&stored_path != NULL)
|
|
{
|
|
for(int i = 0; i < stored_path.size(); i++)
|
|
{
|
|
delete stored_path[i];
|
|
}
|
|
stored_path.clear();
|
|
}
|
|
current_index = -1;
|
|
path_timer = 0.0;
|
|
|
|
if (path_cost != NULL) delete[] path_cost;
|
|
path_cost = NULL;
|
|
if (total_state_cost != NULL) delete[] total_state_cost;
|
|
total_state_cost = NULL;
|
|
if (total_transition_cost != NULL) delete[] total_transition_cost;
|
|
total_transition_cost = NULL;
|
|
|
|
if(loop_detection != NULL)
|
|
delete loop_detection;
|
|
loop_detection = NULL;
|
|
}
|
|
|
|
/*
|
|
* Allocates a new path according to the current model.
|
|
*
|
|
* throws an exception if there is not enough memory.
|
|
*/
|
|
void Allocate_Path()
|
|
{
|
|
if(&stored_path == NULL)
|
|
{
|
|
Report_Error("Out of memory when allocating path.");
|
|
throw "out of memory error: simpath.cc 001";
|
|
}
|
|
else
|
|
{
|
|
if(stored_path.size() > 0) stored_path.clear();
|
|
//16 is the starting length, this will multiply by 2 when needed
|
|
for(int i = 0; i < 16; i++)
|
|
{
|
|
CPathState* ps = new CPathState();
|
|
if(ps == NULL)
|
|
{
|
|
Report_Error("Out of memory when allocating path.");
|
|
throw "out of memory error: simpath.cc 002";
|
|
}
|
|
stored_path.push_back(ps);
|
|
}
|
|
}
|
|
|
|
current_index = -1;
|
|
path_timer = 0.0;
|
|
|
|
path_cost = new double[no_reward_structs];
|
|
total_state_cost = new double[no_reward_structs];
|
|
total_transition_cost = new double[no_reward_structs];
|
|
if(path_cost == NULL || total_state_cost == NULL || total_transition_cost == NULL)
|
|
{
|
|
Report_Error("Out of memory when allocating path.");
|
|
throw "out of memory error: simpath.cc";
|
|
}
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
path_cost[i] = 0.0;
|
|
total_state_cost[i] = 0.0;
|
|
total_transition_cost[i] = 0.0;
|
|
}
|
|
|
|
loop_detection = new CPathLoopDetectionHandler();
|
|
}
|
|
|
|
/*
|
|
* Starts a new path in the path object
|
|
*/
|
|
void Start_Path()
|
|
{
|
|
loop_detection->Reset();
|
|
|
|
current_index = -1;
|
|
path_timer = 0.0;
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
path_cost[i] = 0.0;
|
|
total_state_cost[i] = 0.0;
|
|
total_transition_cost[i] = 0.0;
|
|
}
|
|
|
|
Add_Current_State_To_Path();
|
|
|
|
//Set the first set of updates
|
|
Calculate_Updates(state_variables);
|
|
Calculate_State_Reward(state_variables);
|
|
|
|
if(Are_Updates_Deterministic())
|
|
{
|
|
loop_detection->Notify_Deterministic_State(false);
|
|
}
|
|
else
|
|
{
|
|
loop_detection->Notify_Deterministic_Path_End();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function which handles a choice made by the user from
|
|
* the current update set. The update is made and
|
|
* the path is updated accordingly.
|
|
*/
|
|
void Manual_Update(int index)
|
|
{
|
|
if(model_type == STOCHASTIC)
|
|
{
|
|
Perform_Update(index, -1.0, state_variables); //calculate time_taken
|
|
}
|
|
else
|
|
{
|
|
Perform_Update(index, state_variables);
|
|
}
|
|
stored_path[current_index]->choice_made = index;
|
|
Add_Current_State_To_Path();
|
|
|
|
Calculate_Updates(state_variables);
|
|
Calculate_State_Reward(state_variables);
|
|
|
|
// check for looping
|
|
if(Are_Updates_Deterministic())
|
|
{
|
|
loop_detection->Notify_Deterministic_State(false);
|
|
}
|
|
else
|
|
{
|
|
loop_detection->Notify_Deterministic_Path_End();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Function which handles a choice made by the user from
|
|
* the current update set. The update is made and
|
|
* the path is updated accordingly. This function
|
|
* is specific to ctmcs because is allows the user to enter
|
|
* the time.
|
|
*/
|
|
void Manual_Update(int index, double time_in_state)
|
|
{
|
|
Perform_Update(index, time_in_state, state_variables); //calculate time_taken
|
|
|
|
stored_path[current_index]->choice_made = index;
|
|
Add_Current_State_To_Path();
|
|
|
|
Calculate_Updates(state_variables);
|
|
Calculate_State_Reward(state_variables);
|
|
|
|
// check for looping
|
|
if(Are_Updates_Deterministic())
|
|
{
|
|
loop_detection->Notify_Deterministic_State(false);
|
|
}
|
|
else
|
|
{
|
|
loop_detection->Notify_Deterministic_Path_End();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Make n automatic updates and store the path.
|
|
*/
|
|
void Automatic_Choices(int n){ Automatic_Choices(n, true); }
|
|
|
|
void Automatic_Choices(int n, bool detect)
|
|
{
|
|
for(int i = 0; i < n; i++) {
|
|
if (detect && loop_detection->Is_Proven_Looping()) break;
|
|
if (loop_detection->Is_Deadlock()) break;
|
|
|
|
double probability = 0.0;
|
|
Automatic_Update(loop_detection, probability);
|
|
|
|
// Because we cannot guarantee that we know the selected index, we have to show this.
|
|
stored_path[current_index]->choice_made = PATH_NO_CHOICE_MADE;
|
|
stored_path[current_index]->probability = probability;
|
|
// Unless requested not to (detect==false), this function will stop exploring when a loop is detected.
|
|
// Because Automatic_Update() checks for loops before making a transition, we overshoot.
|
|
// Hence at this point if we are looping we step back a state,
|
|
// i.e. reset state_variables and don't add new state to the path.
|
|
if (detect && loop_detection->Is_Proven_Looping()) {
|
|
stored_path[current_index]->Make_Current_State_This();
|
|
}
|
|
else {
|
|
// Add state to path (unless we have stayed in the same state because of deadlock).
|
|
if (!loop_detection->Is_Deadlock()) Add_Current_State_To_Path();
|
|
}
|
|
Calculate_State_Reward(state_variables);
|
|
}
|
|
|
|
Calculate_Updates(state_variables);
|
|
|
|
// check for looping
|
|
if(Are_Updates_Deterministic())
|
|
{
|
|
loop_detection->Notify_Deterministic_State(false);
|
|
}
|
|
else
|
|
{
|
|
loop_detection->Notify_Deterministic_Path_End();
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Removes all states following the given index from
|
|
* the path and sets the state_variables to that state.
|
|
*/
|
|
void Backtrack(int step)
|
|
{
|
|
if(step > current_index)
|
|
{
|
|
Report_Error("Attempt to backtrack to an invalid index.");
|
|
throw "out of range error: simpath.cc 020";
|
|
}
|
|
|
|
// if go back at least one step, escape deadlock
|
|
if (step < current_index) loop_detection->Set_Deadlock(false);
|
|
|
|
current_index = step;
|
|
|
|
//copy the state stored in this path to model_variables
|
|
stored_path[current_index]->Make_Current_State_This();
|
|
|
|
//recalculate timer and rewards
|
|
path_timer = 0.0;
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
path_cost[i] = 0.0;
|
|
total_state_cost[i] = 0.0;
|
|
total_transition_cost[i] = 0.0;
|
|
}
|
|
|
|
for(int i = 0; i < current_index; i++)
|
|
{
|
|
if(stored_path[i]->time_known)
|
|
path_timer += stored_path[i]->time_spent_in_state;
|
|
|
|
for (int j = 0; j < no_reward_structs; j++) {
|
|
total_state_cost[j] += stored_path[i]->state_cost[j];
|
|
total_transition_cost[j] += stored_path[i]->transition_cost[j];
|
|
}
|
|
}
|
|
for (int j = 0; j < no_reward_structs; j++) {
|
|
path_cost[j] = total_state_cost[j] + total_transition_cost[j];
|
|
}
|
|
|
|
Recalculate_Path_Formulae();
|
|
|
|
Calculate_State_Reward(state_variables);
|
|
|
|
Calculate_Updates(state_variables);
|
|
|
|
loop_detection->Backtrack(step);
|
|
}
|
|
|
|
/*
|
|
* Removes all states preceding the given index from
|
|
* the path.
|
|
*/
|
|
void Remove_Preceding_States(int step)
|
|
{
|
|
if(step > current_index)
|
|
{
|
|
Report_Error("Attempt to remove states before an invalid index.");
|
|
throw "out of range error: simpath.cc 021";
|
|
}
|
|
|
|
// shift later states down path, move unneeded ones to end
|
|
int i;
|
|
CPathState** prefix = new CPathState*[step];
|
|
|
|
for(i = 0; i < step; i++)
|
|
prefix[i] = stored_path[i];
|
|
|
|
for(i = 0; i <= current_index-step; i++)
|
|
stored_path[i] = stored_path[i+step];
|
|
|
|
for(i = current_index-step+1; i <= current_index; i++)
|
|
stored_path[i] = prefix[i-current_index+step-1];
|
|
|
|
delete prefix;
|
|
|
|
current_index -= step;
|
|
|
|
//recalculate timer and rewards
|
|
|
|
path_timer = 0.0;
|
|
for(int i = 0; i < no_reward_structs; i++)
|
|
{
|
|
path_cost[i] = 0.0;
|
|
total_state_cost[i] = 0.0;
|
|
total_transition_cost[i] = 0.0;
|
|
}
|
|
|
|
for(int i = 0; i < current_index; i++)
|
|
{
|
|
if(stored_path[i]->time_known)
|
|
path_timer += stored_path[i]->time_spent_in_state;
|
|
|
|
for (int j = 0; j < no_reward_structs; j++)
|
|
{
|
|
stored_path[i]->cumulative_time_spent_in_state = path_timer;
|
|
|
|
total_state_cost[j] += stored_path[i]->state_cost[j];
|
|
total_transition_cost[j] += stored_path[i]->transition_cost[j];
|
|
|
|
stored_path[i]->cumulative_state_cost[j] = total_state_cost[j];
|
|
stored_path[i]->cumulative_transition_cost[j] = total_transition_cost[j];
|
|
}
|
|
}
|
|
|
|
for (int j = 0; j < no_reward_structs; j++) {
|
|
path_cost[j] = total_state_cost[j] + total_transition_cost[j];
|
|
}
|
|
|
|
Recalculate_Path_Formulae();
|
|
|
|
Calculate_Updates(state_variables);
|
|
|
|
loop_detection->Remove_Preceding_States(step);
|
|
}
|
|
|
|
//========================
|
|
// Querying functions
|
|
//========================
|
|
|
|
CPathState* Get_Path_State(int i)
|
|
{
|
|
return stored_path[i];
|
|
}
|
|
|
|
/*
|
|
* Returns the total cost of the path so far
|
|
*/
|
|
double Get_Path_Cost(int i)
|
|
{
|
|
return path_cost[i];
|
|
}
|
|
|
|
/*
|
|
* Returns the total cost of being in the states stored in the path
|
|
*/
|
|
double Get_Path_State_Cost(int i)
|
|
{
|
|
return total_state_cost[i];
|
|
}
|
|
|
|
/*
|
|
* Returns the total cost of all of the path transitions
|
|
*/
|
|
double Get_Path_Transition_Cost(int i)
|
|
{
|
|
return total_transition_cost[i];
|
|
}
|
|
|
|
/*
|
|
* Returns the path length
|
|
*/
|
|
int Get_Path_Length()
|
|
{
|
|
return current_index+1;
|
|
}
|
|
|
|
/*
|
|
* Returns the value of the variable stored in the state_index
|
|
* at var_index
|
|
*/
|
|
int Get_Path_Data(int var_index, int state_index)
|
|
{
|
|
CPathState* state = stored_path[state_index];
|
|
if(state == NULL)
|
|
{
|
|
Report_Error("Unexpected error: attempt to access state that is not in range of path");
|
|
throw "out of range error simpath.cc 030";
|
|
}
|
|
else
|
|
{
|
|
if(var_index > no_state_variables || var_index < 0)
|
|
{
|
|
Report_Error("Unexpected error: attempt to access state variable that is out of range");
|
|
throw "out of range error simpath.cc 031";
|
|
}
|
|
return state->variables[var_index];
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
* Returns the time spent in the path_state at state_index.
|
|
*/
|
|
double Get_Time_Spent_In_Path_State(int state_index)
|
|
{
|
|
if(state_index == current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
{
|
|
CPathState* ps = stored_path[state_index];
|
|
//cout << ps->To_String() << endl;
|
|
return ps->time_spent_in_state;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns the cumulative time spent in the path_state at state_index.
|
|
*/
|
|
double Get_Cumulative_Time_Spent_In_Path_State(int state_index)
|
|
{
|
|
if(state_index == current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
{
|
|
CPathState* ps = stored_path[state_index];
|
|
//cout << ps->To_String() << endl;
|
|
return ps->cumulative_time_spent_in_state;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Returns the reward accumulated in the path state at
|
|
* state_index.
|
|
*/
|
|
double Get_State_Reward_Of_Path_State(int state_index, int i)
|
|
{
|
|
if(state_index > current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
return stored_path[state_index]->state_instant_cost[i];
|
|
}
|
|
|
|
/*
|
|
* Returns the reward accumulated in the transition from the
|
|
* state at state_index.
|
|
*/
|
|
double Get_Transition_Reward_Of_Path_State(int state_index, int i)
|
|
{
|
|
if(state_index >= current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
return stored_path[state_index]->transition_cost[i];
|
|
}
|
|
|
|
double Get_Total_State_Reward_Of_Path_State(int state_index, int i)
|
|
{
|
|
if(state_index > current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
return stored_path[state_index]->cumulative_state_cost[i];
|
|
}
|
|
|
|
double Get_Total_Transition_Reward_Of_Path_State(int state_index, int i)
|
|
{
|
|
if(state_index > current_index) return UNDEFINED_DOUBLE;
|
|
else
|
|
return stored_path[state_index]->cumulative_transition_cost[i];
|
|
}
|
|
|
|
bool Is_Proven_Looping()
|
|
{
|
|
return loop_detection->Is_Proven_Looping();
|
|
}
|
|
|
|
int Get_Start_Loop()
|
|
{
|
|
return loop_detection->start_loop + loop_detection->Get_Proven_Loop_Start();
|
|
}
|
|
|
|
int Get_End_Loop()
|
|
{
|
|
return current_index;
|
|
}
|
|
|
|
/*
|
|
* Returns the total time for the path.
|
|
*/
|
|
double Get_Total_Path_Time()
|
|
{
|
|
return path_timer;
|
|
}
|
|
|
|
//TODO this
|
|
int Get_Chosen_Index_Of_Old_Updates(int step)
|
|
{
|
|
int chosen = stored_path[step]->choice_made;
|
|
if(chosen >= 0) return chosen;
|
|
else
|
|
{
|
|
//If we get here, we do not have the data, probably because
|
|
//the update was chosen automatically on the fly and so
|
|
//the index was not known.
|
|
//Therefore, we must work it out.
|
|
//cout << "Attempting to recalculate the old_choice_made" << endl;
|
|
stored_path[step]->choice_made = Calculate_Old_Choice_Made(step);
|
|
return stored_path[step]->choice_made;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
// To String helper functions
|
|
//==============================================================================
|
|
|
|
/*
|
|
* Returns a string representation of the path.
|
|
* TODO this
|
|
*/
|
|
string Path_To_String()
|
|
{
|
|
return "";
|
|
/*std::string returner = "Current Path:\n\n";
|
|
if(thePath == NULL) return returner += "No Path Exists";
|
|
else return returner += thePath->To_String(); */
|
|
}
|
|
|
|
|
|
//============================================================================
|
|
// Local Functions
|
|
//============================================================================
|
|
|
|
inline void Add_Current_State_To_Path()
|
|
{
|
|
current_index++;
|
|
|
|
if(current_index >= stored_path.size())
|
|
{
|
|
//need to allocate some more path
|
|
int size;
|
|
if(stored_path.size() > 0) //should never be, but just in case
|
|
{
|
|
size = 16;
|
|
}
|
|
else //double it
|
|
{
|
|
size = stored_path.size();
|
|
}
|
|
for(int i = 0; i < size; i++)
|
|
{
|
|
CPathState* ps = new CPathState();
|
|
if(ps == NULL)
|
|
{
|
|
Report_Error("Out of memory when allocating new path");
|
|
throw "out of memory error: simpath.cc 003";
|
|
}
|
|
stored_path.push_back(ps);
|
|
}
|
|
}
|
|
|
|
CPathState* curr_state = stored_path[current_index];
|
|
curr_state->Make_This_Current_State();
|
|
|
|
Calculate_State_Reward(curr_state->variables);
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
curr_state->state_instant_cost[i] = Get_State_Reward(i);
|
|
}
|
|
|
|
if(current_index > 0)
|
|
{
|
|
CPathState * last_state = stored_path[current_index-1];
|
|
|
|
if(model_type == STOCHASTIC)
|
|
{
|
|
double time_in_state = Get_Sampled_Time();
|
|
|
|
last_state->time_spent_in_state = (time_in_state);
|
|
|
|
if (current_index > 1)
|
|
{
|
|
CPathState * state_before_last_state = stored_path[current_index-2];
|
|
last_state->cumulative_time_spent_in_state = last_state->time_spent_in_state + state_before_last_state->cumulative_time_spent_in_state;
|
|
}
|
|
else
|
|
{
|
|
last_state->cumulative_time_spent_in_state = last_state->time_spent_in_state;
|
|
}
|
|
|
|
last_state->time_known = true;
|
|
path_timer += time_in_state;
|
|
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
last_state->state_cost[i] = (last_state->state_instant_cost[i]*time_in_state);
|
|
last_state->transition_cost[i] = (Get_Transition_Reward(i));
|
|
|
|
total_state_cost[i] += last_state->state_instant_cost[i]*time_in_state;
|
|
total_transition_cost[i] += Get_Transition_Reward(i);
|
|
path_cost[i] = total_state_cost[i] + total_transition_cost[i];
|
|
|
|
last_state->cumulative_state_cost[i] = total_state_cost[i];
|
|
last_state->cumulative_transition_cost[i] = total_transition_cost[i];
|
|
}
|
|
|
|
Notify_Path_Formulae(last_state, state_variables, loop_detection);
|
|
|
|
}
|
|
else
|
|
{
|
|
//current_index++;
|
|
|
|
for(int i = 0; i < no_reward_structs; i++) {
|
|
last_state->state_cost[i] = (last_state->state_instant_cost[i]);
|
|
last_state->transition_cost[i] = (Get_Transition_Reward(i));
|
|
|
|
total_state_cost[i] += last_state->state_instant_cost[i];
|
|
total_transition_cost[i] += Get_Transition_Reward(i);
|
|
path_cost[i] = total_state_cost[i] + total_transition_cost[i];
|
|
|
|
last_state->cumulative_state_cost[i] = total_state_cost[i];
|
|
last_state->cumulative_transition_cost[i] = total_transition_cost[i];
|
|
}
|
|
|
|
Notify_Path_Formulae(last_state, state_variables, loop_detection);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// TODO This doesn't actually work at the moment, and I don't know why!!!
|
|
inline int Calculate_Old_Choice_Made(int step)
|
|
{
|
|
int* next_vars = Get_Path_State(step+1)->variables;
|
|
int* orig_vars = Get_Path_State(step)->variables;
|
|
|
|
int* copy_vars = new int[no_state_variables];
|
|
|
|
double expectedProb = Get_Path_State(step)->probability;
|
|
|
|
|
|
int selected_index = 0; //if all else fails choose 0
|
|
//This assumes that the update set represents the correct old upates
|
|
|
|
//cout << "Calculate_Old_Choice_Made(" << step<<")" <<endl;
|
|
for(int i = 0; i < Get_No_Updates(); i++)
|
|
{
|
|
CFinalUpdate* upd = Get_Update(i);
|
|
//cout << "looking at update: " << endl;
|
|
//upd->Print_Update();
|
|
Copy_Int_Array(orig_vars, copy_vars, no_state_variables);
|
|
upd->Perform_Update(copy_vars);
|
|
//cout << "This is the array of the next state..." << endl;
|
|
//Print_Array(next_vars, no_state_variables);
|
|
//cout << "This is the array of the compare state for this update" << endl;
|
|
//Print_Array(copy_vars, no_state_variables);
|
|
|
|
if(Int_Arrays_Equals(next_vars, copy_vars, no_state_variables))
|
|
{
|
|
//cout << "this is the same, now check the probability" << endl;
|
|
//cout << "expectedProb = " << expectedProb << " actualProb = " << upd->probability << endl;
|
|
if(upd->probability == expectedProb)
|
|
{
|
|
//cout << "selecting an index as: " << i << endl;
|
|
selected_index = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[]copy_vars;
|
|
return selected_index;
|
|
}
|
|
|
|
inline void Recalculate_Path_Formulae()
|
|
{
|
|
//first rest each path formula
|
|
Reset_Path_Formulae();
|
|
|
|
CPathState* last_state = NULL;
|
|
int* curr_state = stored_path[0]->variables;
|
|
Notify_Path_Formulae(last_state, curr_state, loop_detection);
|
|
|
|
for(int j = 1; j<=current_index; j++)
|
|
{
|
|
last_state = stored_path[j-1];
|
|
curr_state = stored_path[j]->variables;
|
|
Notify_Path_Formulae(last_state, curr_state, loop_detection);
|
|
}
|
|
}
|
|
|
|
|