Skip to content

Commit

Permalink
project complete? novelty search needs more focus
Browse files Browse the repository at this point in the history
  • Loading branch information
snorthman committed May 19, 2017
1 parent 562a2de commit 6442c69
Show file tree
Hide file tree
Showing 8 changed files with 220 additions and 196 deletions.
5 changes: 3 additions & 2 deletions src/SharpNeatDomains/IPD/IPDEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace SharpNeat.Domains.IPD
{
class IPDEvaluator : IPhenomeEvaluator<IBlackBox>
{
private const int ARCHIVE_MAX_SIZE = 100;
private const int ARCHIVE_MAX_SIZE = 200;
private const bool ALLOW_NOVELTY = true;

public ulong EvaluationCount { get; private set; }

Expand Down Expand Up @@ -42,7 +43,7 @@ public FitnessInfo Evaluate(IBlackBox phenome)
{
EvaluationCount++;

_noveltyMode = (_archive.Count == ARCHIVE_MAX_SIZE && _info.CurrentGeneration > ARCHIVE_MAX_SIZE * 2);
_noveltyMode = (ALLOW_NOVELTY && _archive.Count == ARCHIVE_MAX_SIZE && _info.CurrentGeneration > ARCHIVE_MAX_SIZE * 2);

double objectiveFitness = EvaluateObjectively(phenome);
double noveltyFitness = EvaluateNovelty(phenome);
Expand Down
68 changes: 32 additions & 36 deletions src/SharpNeatDomains/IPD/IPDExperiment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ namespace SharpNeat.Domains.IPD
{
class IPDExperiment : IGuiNeatExperiment
{
public enum OpponentPool {
AllC_Only,
AllD_Only,
DoubleTrouble, //AllC, AllD
TripleThreat, //AllC, AllD, TFT
TFTFails //AllC, AllD, TFT, STFT
public enum Opponent
{
AllC,
AllD,
TFT,
STFT
}

private static readonly ILog __log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
Expand Down Expand Up @@ -125,9 +125,12 @@ public void Initialize(string name, XmlElement xmlConfig)
_complexityRegulationStr = XmlUtils.TryGetValueAsString(xmlConfig, "ComplexityRegulationStrategy");
_complexityThreshold = XmlUtils.TryGetValueAsInt(xmlConfig, "ComplexityThreshold");

_numberOfGames = XmlUtils.GetValueAsInt(xmlConfig, "Games");
_opponentPool = CreatePool((OpponentPool)System.Enum.Parse(typeof(OpponentPool), XmlUtils.GetValueAsString(xmlConfig, "OpponentsPool"), true));

_numberOfGames = XmlUtils.GetValueAsInt(xmlConfig, "IPDGames");
int seed = XmlUtils.GetValueAsInt(xmlConfig, "RandomPlayerSeed");
int randoms = XmlUtils.GetValueAsInt(xmlConfig, "RandomPlayerCount");
string[] opps = XmlUtils.GetValueAsString(xmlConfig, "StaticOpponents").Split(',');
_opponentPool = _CreatePool(seed, randoms, System.Array.ConvertAll(opps, (string o) => { return (Opponent)System.Enum.Parse(typeof(Opponent), o, true); }));

_pastInputReach = XmlUtils.GetValueAsInt(xmlConfig, "PastInputReach");

_description = XmlUtils.TryGetValueAsString(xmlConfig, "Description");
Expand Down Expand Up @@ -259,36 +262,29 @@ public AbstractDomainView CreateDomainView()
}

#endregion
private IPDPlayer[] CreatePool(OpponentPool pool)

private IPDPlayer[] _CreatePool(int seed, int randoms, params Opponent[] opponents)
{
switch (pool)
Players.IPDPlayerFactory pf = new Players.IPDPlayerFactory(seed);
var pool = new IPDPlayer[randoms + opponents.Length];
for (int i = 0; i < randoms; i++)
pool[i] = pf.Random();
for (int i = randoms, j = 0; i < pool.Length; i++, j++)
{
case OpponentPool.AllC_Only:
return new IPDPlayer[] { Players.IPDPlayerFactory.AllC };
case OpponentPool.AllD_Only:
return new IPDPlayer[] { Players.IPDPlayerFactory.AllC };
case OpponentPool.DoubleTrouble:
return new IPDPlayer[] {
Players.IPDPlayerFactory.AllC,
Players.IPDPlayerFactory.AllD
};
case OpponentPool.TripleThreat:
return new IPDPlayer[] {
Players.IPDPlayerFactory.AllC,
Players.IPDPlayerFactory.AllD,
Players.IPDPlayerFactory.TFT
};
case OpponentPool.TFTFails:
return new IPDPlayer[] {
Players.IPDPlayerFactory.AllC,
Players.IPDPlayerFactory.AllD,
Players.IPDPlayerFactory.TFT,
Players.IPDPlayerFactory.STFT
};
default:
return new IPDPlayer[0];
switch (opponents[j])
{
case Opponent.AllC:
pool[i] = Players.IPDPlayerFactory.AllC; break;
case Opponent.AllD:
pool[i] = Players.IPDPlayerFactory.AllD; break;
case Opponent.TFT:
pool[i] = Players.IPDPlayerFactory.TFT; break;
case Opponent.STFT:
default:
pool[i] = Players.IPDPlayerFactory.STFT; break;
}
}
return pool;
}

public struct Info
Expand Down
236 changes: 139 additions & 97 deletions src/SharpNeatDomains/IPD/Players/IPDPlayerFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,144 +4,186 @@
using System.Text;
using System.Threading.Tasks;
using SharpNeat.Domains.IPD.Players.Tree;
using RandomNameGeneratorLibrary;

namespace SharpNeat.Domains.IPD.Players
{
static class IPDPlayerFactory
class IPDPlayerFactory
{
public static IPDPlayerGenerated TFT => _createXTFT("TFT", IPDGame.Choices.C);
public static IPDPlayerGenerated STFT => _createXTFT("STFT", IPDGame.Choices.D);
public static IPDPlayerGenerated AllC => _allX("AllC", IPDGame.Choices.C);
public static IPDPlayerGenerated AllR => _allX("AllR", IPDGame.Choices.R);
public static IPDPlayerGenerated AllD => _allX("AllD", IPDGame.Choices.D);

public static IPDPlayerGenerated Random()
{
Random r = new System.Random();
Dictionary<int, Node> treeDict = new Dictionary<int, Node>();

IPDGame.Choices randomChoice()
{
double n = r.NextDouble();
if (n < 0.1)
return IPDGame.Choices.R;
else if (n < 0.55)
return IPDGame.Choices.C;
else return IPDGame.Choices.D;
}

int loopCount()
{
int l = 0;
double n = 1.0d;
while (r.NextDouble() < n)
{
n /= 2;
l++;
}
return l;

QFunction createQFunction()
private static IPDPlayerGenerated _createXTFT(string name, IPDGame.Choices startingChoice)
{
DecisionTree tree = new DecisionTree(new Dictionary<int, Node>()
{
double n = r.NextDouble();
if (n < 0.5)
return new QFunction()
}
{ 0, new PayoffConditionalNode(1, 2, 1, IPDGame.Past.P, IPDGame.Past.S) },
{ 1, new AssignResultNode(new QFunction(new QFunctionSequence(IPDGame.Choices.D)))},
{ 2, new AssignResultNode(new QFunction(new QFunctionSequence(IPDGame.Choices.C)))}
});

QFunctionConditional createQFunctionConditional()
{
return new QFunctionConditional()//make conditional
}
return new IPDPlayerGenerated(name, tree, startingChoice);
}

QFunctionSequence createQFunctionSequence()
private static IPDPlayerGenerated _allX(string name, IPDGame.Choices X)
{
DecisionTree tree = new DecisionTree(new Dictionary<int, Node>()
{
QFunctionSequence.Piece[] p = new QFunctionSequence.Piece[loopCount()];
for (int i = 0; i < p.Length; i++)
p[i] = createQFunctionPiece();
return new QFunctionSequence(p);
}
{ 0, new AssignResultNode(new QFunction(new QFunctionSequence(X)))},
}, QFunction.Default);

QFunctionSequence.Piece createQFunctionPiece()
{
QFunctionSequence.Piece.Values v;
int reps = 0;
double n = r.NextDouble();
if (n < 0.33)
v = QFunctionSequence.Piece.Values.Alpha;
else if (n < 0.66)
v = QFunctionSequence.Piece.Values.Beta;
else
{
v = QFunctionSequence.Piece.Values.Number;
reps = r.Next(10);
}
return new QFunctionSequence.Piece(randomChoice(), v, (reps > 3) ? reps / 2 : reps);
}
return new IPDPlayerGenerated(name, tree, X);
}

Node createNode()
{
double n = r.NextDouble();
if (n < 0.33)
return createAssignNode();
else if (n < 0.66)
return createPayoffNode();
else
return createValueNode();
}
private Random _r;
private int _condId;
private int _resultId;
private Func<(int, int)>[,] _table;

AssignResultNode createAssignNode()
{
return new AssignResultNode()
}
private IPDGame.Past[] _past = new IPDGame.Past[4] { IPDGame.Past.T, IPDGame.Past.R, IPDGame.Past.P, IPDGame.Past.S };

PayoffConditionalNode createPayoffNode()
public IPDPlayerFactory(int seed = 0)
{
_r = (seed <= 0) ? new System.Random() : new System.Random(seed);

Func<(int, int)> RR = () => { return (_resultId++, _resultId++); };
Func<(int, int)> CC = () => { return (_condId++, _condId++); };
Func<(int, int)> CR = () => { return (_condId++, _resultId++); };
Func<(int, int)> RC = () => { return (_resultId++, _condId++); };
Func<(int, int)> T = () => { return (_r.NextDouble() < 0.5) ? (_resultId++, _condId++) : (_condId++, _resultId++); };
_table = new Func<(int, int)>[3, 4]
{
{ RR, RR, RR, RR },
{ T , CR, RC, T },
{ T , CR, RC, CC }
};
}

}
public IPDPlayerGenerated Random()
{
Dictionary<int, Node> treeDict = new Dictionary<int, Node>();

(int left, int right)[] condNodes = new (int, int)[RandomAmount(7)];
_condId = 1;
_resultId = condNodes.Length;

ValueConditionalNode createValueNode()
for (int i = 0; i < condNodes.Length; i++)
{
int a = (_r.NextDouble() < 0.5d) ? 0 : 1;
int b = (_r.NextDouble() < 0.5d) ? 0 : 2;

int x = Math.Min(condNodes.Length - _condId, 2);
int y = a + b;

condNodes[i] = _table[x, y]();
}

for (int i = 0; i < condNodes.Length; i++)
treeDict.Add(i, CreateConditionalNode(condNodes[i].left, condNodes[i].right));
for (int i = condNodes.Length; i < _resultId; i++)
treeDict.Add(i, CreateResultNode());

QFunction Q;
new Dictionary<int, Node>()
{
{

}
}
string name = _r.GenerateRandomFirstAndLastName() + " " + _r.GenerateRandomPlaceName();
IPDGame.Choices[] c = new IPDGame.Choices[RandomAmount()];
for (int i = 0; i < c.Length; i++)
c[i] = RandomChoice();

return new IPDPlayerGenerated(name, new DecisionTree(treeDict, CreateQFunction()), c);
}

private IPDGame.Choices RandomChoice()
{
double n = _r.NextDouble();
if (n < 0.1)
return IPDGame.Choices.R;
else if (n < 0.55)
return IPDGame.Choices.C;
else return IPDGame.Choices.D;
}

/// <summary>
/// Minimum is always 1.
/// </summary>
private int RandomAmount(int max = 3)
{
int a = 0;
double n = max;
while (a <= max && _r.NextDouble() < n-- / max)
a++;
return a;
}

#region QFunction
private QFunction CreateQFunction()
{
double n = _r.NextDouble();
if (n < 0.75)
return new QFunction(CreateQFunctionSequence());
else
return new QFunction(CreateQFunctionConditional(), CreateQFunctionSequence(), CreateQFunctionSequence());
}


private QFunction.Values RandomQValue()
{
double n = _r.NextDouble();
if (n < 0.25)
return QFunction.Values.Alpha;
if (n < 0.50)
return QFunction.Values.Beta;
else
return QFunction.Values.Number;
}

return null;
private QFunctionConditional CreateQFunctionConditional()
{
QFunction.Values[] v = new QFunction.Values[] { RandomQValue(), RandomQValue() };
if (v[0] == QFunction.Values.Number && v[1] == QFunction.Values.Number)
return new QFunctionConditional(RandomAmount(), RandomAmount());
if (v[0] != QFunction.Values.Number && v[1] != QFunction.Values.Number)
return new QFunctionConditional(v[0], v[1]);
if (v[0] == QFunction.Values.Number)
return new QFunctionConditional(v[0], RandomAmount());
else //(v[1] == QFunction.Values.Number)
return new QFunctionConditional(RandomAmount(), v[1]);
}

private static IPDPlayerGenerated _createXTFT(string name, IPDGame.Choices startingChoice)
private QFunctionSequence CreateQFunctionSequence()
{
DecisionTree tree = new DecisionTree(new Dictionary<int, Node>()
{
{ 0, new PayoffConditionalNode(1, 2, 1, IPDGame.Past.P, IPDGame.Past.S) },
{ 1, new AssignResultNode(new QFunction(new QFunctionSequence(IPDGame.Choices.D)))},
{ 2, new AssignResultNode(new QFunction(new QFunctionSequence(IPDGame.Choices.C)))}
});
QFunctionSequence.Piece[] p = new QFunctionSequence.Piece[RandomAmount()];
for (int i = 0; i < p.Length; i++)
p[i] = new QFunctionSequence.Piece(RandomChoice(), RandomQValue(), RandomAmount());
return new QFunctionSequence(p);
}
#endregion

private ResultNode CreateResultNode()
{
return new AssignResultNode(CreateQFunction());
}

return new IPDPlayerGenerated(name, tree, startingChoice);
private ConditionalNode CreateConditionalNode(int leftNode, int rightNode)
{
if (_r.NextDouble() < 0.5)
return CreatePayoffNode(leftNode, rightNode);
else return CreateValueNode(leftNode, rightNode);
}

private static IPDPlayerGenerated _allX(string name, IPDGame.Choices X)
private PayoffConditionalNode CreatePayoffNode(int leftNode, int rightNode)
{
DecisionTree tree = new DecisionTree(new Dictionary<int, Node>()
{
{ 0, new AssignResultNode(new QFunction(new QFunctionSequence(X)))},
}, QFunction.Default);
int[] r = MathNet.Numerics.Combinatorics.GeneratePermutation(4, _r);
IPDGame.Past[] p = new IPDGame.Past[RandomAmount(3)];
for (int i = 0; i < p.Length; i++)
p[i] = _past[r[i]];
return new PayoffConditionalNode(leftNode, rightNode, RandomAmount(), RandomAmount(4) - 1, RandomAmount(4) - 1, p);
}

return new IPDPlayerGenerated(name, tree, X);
private ValueConditionalNode CreateValueNode(int leftNode, int rightNode)
{
return new ValueConditionalNode(leftNode, rightNode, CreateQFunctionConditional(), RandomAmount(4) - 1, RandomAmount(4) - 1);
}
}
}
Loading

0 comments on commit 6442c69

Please sign in to comment.