Skip to content

Commit

Permalink
Memory management for sequence representation
Browse files Browse the repository at this point in the history
  • Loading branch information
tturocy committed Jul 19, 2024
1 parent 3676cc3 commit 6ab5b8b
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 63 deletions.
71 changes: 23 additions & 48 deletions src/solvers/enumpoly/sfg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@ using namespace Gambit;
namespace Gambit {

//--------------------------------------
// Sequence: Member functions
// SequenceRep: Member functions
//--------------------------------------

List<GameAction> Sequence::History() const
std::list<GameAction> SequenceRep::GetHistory() const
{
List<GameAction> h;
GameAction a = action;
const Sequence *s = (this);
std::list<GameAction> h;
auto a = action;
auto s = shared_from_this();
while (a) {
h.push_back(a);
h.push_front(a);
s = s->parent;
a = s->GetAction();
}
Expand All @@ -49,29 +49,17 @@ List<GameAction> Sequence::History() const
// SequenceSet: Member functions
//--------------------------------------

SequenceSet::SequenceSet(const GamePlayer &p) : efp(p), sequences()
SequenceSet::SequenceSet(const GamePlayer &p) : efp(p)
{
AddSequence(new Sequence(p, nullptr, nullptr, 1));
}

SequenceSet::~SequenceSet()
{

// potential problem here? It is not clear this is where this belongs.
// What if there are multiple SequenceSets pointing to
// the same sequences?

for (int i = 1; i <= sequences.Length(); i++) {
delete sequences[i];
}
AddSequence(std::make_shared<SequenceRep>(p, nullptr, nullptr, 1));
}

//------------------------------------------
// SequenceSet: Member functions
//------------------------------------------

// Append a sequences to the SequenceSet
void SequenceSet::AddSequence(Sequence *s)
void SequenceSet::AddSequence(std::shared_ptr<SequenceRep> s)
{
if (efp != s->GetPlayer()) {
throw MismatchException();
Expand All @@ -81,7 +69,7 @@ void SequenceSet::AddSequence(Sequence *s)

// Finds the sequence pointer of sequence number j. Returns 0 if there
// is no sequence with that number.
Sequence *SequenceSet::Find(int j)
std::shared_ptr<SequenceRep> SequenceSet::Find(int j)
{
int t = 1;
while (t <= sequences.Length()) {
Expand Down Expand Up @@ -142,7 +130,7 @@ Sfg::Sfg(const BehaviorSupportProfile &S)
sequences.push_back(new SequenceSet(support.GetGame()->GetPlayer(i)));
}

Array<Sequence *> parent(support.GetGame()->NumPlayers());
Array<std::shared_ptr<SequenceRep>> parent(support.GetGame()->NumPlayers());
for (int i = 1; i <= support.GetGame()->NumPlayers(); i++) {
parent[i] = sequences[i]->GetSequenceSet()[1];
}
Expand All @@ -168,7 +156,7 @@ Sfg::~Sfg()
}

void Sfg::MakeSequenceForm(const GameNode &n, const Rational &prob, Array<int> seq,
Array<GameInfoset> iset, Array<Sequence *> parent,
Array<GameInfoset> iset, Array<std::shared_ptr<SequenceRep>> parent,
PVector<int> &isetFlag)
{
if (n->GetOutcome()) {
Expand Down Expand Up @@ -197,7 +185,7 @@ void Sfg::MakeSequenceForm(const GameNode &n, const Rational &prob, Array<int> s
}

(*E[pl])(isetRow(pl, isetnum), seq[pl]) = (Rational)1;
Sequence *myparent(parent[pl]);
std::shared_ptr<SequenceRep> myparent(parent[pl]);

bool flag = false;
if (!isetFlag(pl, isetnum)) { // on first visit to iset, create new sequences
Expand All @@ -208,9 +196,8 @@ void Sfg::MakeSequenceForm(const GameNode &n, const Rational &prob, Array<int> s
if (support.Contains(n->GetInfoset()->GetAction(i))) {
snew[pl] += 1;
if (flag) {
Sequence *child;
child =
new Sequence(n->GetPlayer(), n->GetInfoset()->GetAction(i), myparent, snew[pl]);
auto child = std::make_shared<SequenceRep>(
n->GetPlayer(), n->GetInfoset()->GetAction(i), myparent, snew[pl]);
parent[pl] = child;
sequences[pl]->AddSequence(child);
}
Expand All @@ -225,11 +212,9 @@ void Sfg::MakeSequenceForm(const GameNode &n, const Rational &prob, Array<int> s

void Sfg::GetSequenceDims(const GameNode &n, PVector<int> &isetFlag)
{
int i;

if (n->GetInfoset()) {
if (n->GetPlayer()->IsChance()) {
for (i = 1; i <= n->NumChildren(); i++) {
for (int i = 1; i <= n->NumChildren(); i++) {
GetSequenceDims(n->GetChild(i), isetFlag);
}
}
Expand All @@ -244,7 +229,7 @@ void Sfg::GetSequenceDims(const GameNode &n, PVector<int> &isetFlag)
isetRow(pl, isetnum) = infosets[pl].Length() + 1;
flag = true;
}
for (i = 1; i <= n->NumChildren(); i++) {
for (int i = 1; i <= n->NumChildren(); i++) {
if (support.Contains(n->GetInfoset()->GetAction(i))) {
if (flag) {
seq[pl]++;
Expand Down Expand Up @@ -307,28 +292,18 @@ MixedBehaviorProfile<double> Sfg::ToBehav(const PVector<double> &x) const

b = (Rational)0;

Sequence *sij;
const Sequence *parent;
Rational value;

int i, j;
for (i = 1; i <= support.GetGame()->NumPlayers(); i++) {
for (j = 2; j <= seq[i]; j++) {
sij = sequences[i]->GetSequenceSet()[j];
for (int i = 1; i <= support.GetGame()->NumPlayers(); i++) {
for (int j = 2; j <= seq[i]; j++) {
auto sij = sequences[i]->GetSequenceSet()[j];
int sn = sij->GetNumber();
parent = sij->Parent();

// gout << "\ni,j,sn,iset,act: " << i << " " << j << " " << sn << " ";
// gout << sij->GetInfoset()->GetNumber() << " " << sij->GetAction()->GetNumber();
auto parent = sij->GetParent();

if (x(i, parent->GetNumber()) > (double)0) {
value = Rational(x(i, sn) / x(i, parent->GetNumber()));
b[sij->GetAction()] = Rational(x(i, sn) / x(i, parent->GetNumber()));
}
else {
value = Rational(0);
b[sij->GetAction()] = Rational(0);
}

b[sij->GetAction()] = value;
}
}
return b;
Expand Down
35 changes: 20 additions & 15 deletions src/solvers/enumpoly/sfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,15 @@
#ifndef SFG_H
#define SFG_H

#include <memory>

#include "gambit.h"
#include "odometer.h"
#include "gnarray.h"

namespace Gambit {

struct Sequence {
class SequenceRep : public std::enable_shared_from_this<SequenceRep> {
friend class Sfg;
friend class SequenceSet;

Expand All @@ -38,49 +40,49 @@ struct Sequence {
std::string name;
GamePlayer player;
GameAction action;
const Sequence *parent;
std::shared_ptr<SequenceRep> parent;

Sequence(const GamePlayer &pl, const GameAction &a, const Sequence *p, int n)
public:
SequenceRep(const GamePlayer &pl, const GameAction &a, std::shared_ptr<SequenceRep> p, int n)
: number(n), player(pl), action(a), parent(p)
{
}
~SequenceRep() = default;

~Sequence() = default;

public:
const std::string &GetName() const { return name; }
void SetName(const std::string &s) { name = s; }

List<GameAction> History() const;
// Return the history of actions corresponding to the sequence, starting from the root
std::list<GameAction> GetHistory() const;
int GetNumber() const { return number; }
GameAction GetAction() const { return action; }
GameInfoset GetInfoset() const { return (action) ? action->GetInfoset() : nullptr; }
GamePlayer GetPlayer() const { return player; }
const Sequence *Parent() const { return parent; }
std::shared_ptr<SequenceRep> GetParent() const { return parent; }
};

class SequenceSet {
protected:
GamePlayer efp;
Array<Sequence *> sequences;
Array<std::shared_ptr<SequenceRep>> sequences;

public:
explicit SequenceSet(const GamePlayer &p);
SequenceSet(const SequenceSet &) = delete;
~SequenceSet();
~SequenceSet() = default;

SequenceSet &operator=(const SequenceSet &s) = delete;

// Append a sequence to the SequenceSet
void AddSequence(Sequence *s);
void AddSequence(std::shared_ptr<SequenceRep>);

Sequence *Find(int j);
std::shared_ptr<SequenceRep> Find(int j);

// Number of sequences in the SequenceSet
int NumSequences() const { return sequences.Length(); }

// return the entire sequence set in a const Array
const Array<Sequence *> &GetSequenceSet() const { return sequences; }
const Array<std::shared_ptr<SequenceRep>> &GetSequenceSet() const { return sequences; }
};

class Sfg {
Expand All @@ -94,7 +96,7 @@ class Sfg {
Array<List<GameInfoset>> infosets;

void MakeSequenceForm(const GameNode &, const Rational &, Array<int>, Array<GameInfoset>,
Array<Sequence *>, PVector<int> &);
Array<std::shared_ptr<SequenceRep>>, PVector<int> &);

void GetSequenceDims(const GameNode &, PVector<int> &);

Expand All @@ -121,7 +123,10 @@ class Sfg {

MixedBehaviorProfile<double> ToBehav(const PVector<double> &x) const;

const Sequence *GetSequence(int pl, int seq) const { return (sequences[pl])->Find(seq); }
std::shared_ptr<SequenceRep> GetSequence(int pl, int seq) const
{
return (sequences[pl])->Find(seq);
}
};

} // end namespace Gambit
Expand Down

0 comments on commit 6ab5b8b

Please sign in to comment.