Skip to content

Instantly share code, notes, and snippets.

@hungtatai
Last active December 17, 2015 18:39
Show Gist options
  • Save hungtatai/5654987 to your computer and use it in GitHub Desktop.
Save hungtatai/5654987 to your computer and use it in GitHub Desktop.
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Father {
public static void main(String[] args) {
int testNum = 10;
boolean maskResponse = true;
Boolean[] mudChildren = new Boolean[] { true, true, true, true, true, true, true, false, false, false };
//Boolean[] mudChildren = new Boolean[] { true, true, false };
/*
Boolean[] mudChildren = new Boolean[50];
Random random = new Random();
for(int i=0;i<mudChildren.length;i++)
mudChildren[i] = random.nextDouble() > 0.5;
//*/
Child[] children = new Child[mudChildren.length];
for (int i = 0; i < children.length; i++) {
children[i] = new Child();
children[i].maskResponse = maskResponse;
}
double p = 0;
for(int i=0;i<testNum;i++) {
new Father(mudChildren, children, false);
double _p = correctProb(mudChildren, children);
System.out.printf("Test %d: %.2f%%\n", i, _p*100);
resetChild(children);
p += _p;
}
System.out.println("Avg Correct Prob: "+(p/testNum*100)+"%");
}
public Father(Boolean[] mudChildren, Child[] children, boolean printOut) {
if (printOut) {
System.out.printf("===============================================================\n");
System.out.printf("There are %d children, and %d children has mud on the forehead.\n", mudChildren.length, calcMudded(mudChildren));
System.out.printf("Father say: At least one of you have mud on the forehead.\n");
System.out.printf("===============================================================\n");
}
int r = 1;
while (true) {
if (printOut)
System.out.printf("Round: %d\n", r++);
// observe
for (int i = 0; i < children.length; i++) {
List<Boolean> state = new ArrayList<Boolean>();
for (int j = 0; j < mudChildren.length; j++) {
if (i != j)
state.add(mudChildren[j]);
}
children[i].observe(state);
}
// response
Integer[] othersResponse = new Integer[children.length];
for (int i = 0; i < children.length; i++) {
othersResponse[i] = children[i].response();
}
// listen
for (int i = 0; i < children.length; i++) {
children[i].listen(othersResponse);
}
// print
/*
* for(Integer res: othersResponse)
* System.out.printf("%d ", res);
* System.out.println("");
*/
if (printOut) {
for (int i = 0; i < othersResponse.length; i++)
System.out.printf("Child %d say: [%d] %s\n", i, othersResponse[i], childSay(othersResponse[i]));
}
// check end
boolean endFlag = true;
for (Integer res : othersResponse)
if (res == 0)
endFlag = false;
if (endFlag)
break;
}
}
public String childSay(int s) {
if (s == 1)
return "I have mud";
else if (s == -1)
return "I haven't mud";
else
return "I don't know";
}
public static void resetChild(Child[] children) {
for (int i = 0; i < children.length; i++) {
children[i].reset();
}
}
public int[] childResponse(Child[] children) {
int[] othersResponse = new int[children.length];
for (int i = 0; i < children.length; i++) {
othersResponse[i] = children[i].response();
}
return othersResponse;
}
public int calcMudded(Boolean[] mudChildren) {
int mudded = 0;
for (Boolean c : mudChildren)
if (c)
mudded++;
return mudded;
}
public static double correctProb(Boolean[] mudChildren, Child[] children) {
int eqNum = 0;
for (int i = 0; i < children.length; i++) {
if (children[i].response() == 1 && mudChildren[i] == true)
eqNum++;
else if (children[i].response() == -1 && mudChildren[i] == false)
eqNum++;
}
return eqNum / (double)children.length;
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import org.neuroph.core.NeuralNetwork;
import org.neuroph.core.learning.DataSet;
import org.neuroph.core.learning.DataSetRow;
import org.neuroph.nnet.MultiLayerPerceptron;
import org.neuroph.util.TransferFunctionType;
public class Child {
public boolean maskResponse = false;
private NeuralNetwork nnResponse;
private int mudChildNum;
private int totalChildNum;
private ArrayList<Integer[]> othersResponse;
private Random random = new Random();
// round is equal to othersResponse.size()
private int round;
private boolean ihasmud;
private boolean isLearning;
public Child() {
reset();
}
public void reset() {
othersResponse = new ArrayList<Integer[]>();
round = 0;
ihasmud = false;
isLearning = false;
}
// observe who has muddy
public void observe(List<Boolean> state) {
mudChildNum = 0;
totalChildNum = state.size() + 1; // add self
for (Boolean b : state) {
if (b)
mudChildNum++;
}
}
// listen other's response
public void listen(Integer[] r) {
if (othersResponse == null)
othersResponse = new ArrayList<Integer[]>();
othersResponse.add(r);
round = othersResponse.size();
}
// 1: I have mud, 0: I don't know, -1: I haven't mud
public int response() {
if (othersResponse == null || othersResponse.size() == 0)
return 0;
// System.out.printf("| %d %d %d %d\n", round,
// otherResponseMudNum(round), mudChildNum, totalChildNum);
/*
* if ( round == 1 && otherResponseMudNum(round) == 0 && mudChildNum ==0)
* return 1;
* else if ( round == 2 && otherResponseMudNum(round) == 1 && mudChildNum == 1)
*/
int r = round;
int m = mudChildNum;
int o = otherResponseMudNum(round);
int result;
if ((r - 1 == m && o == 0) || ihasmud) {
ihasmud = true;
result = 1;
} else if (o == m)
result = -1;
else
result = 0;
if (maskResponse) {
DataSet trainingSet;
if (nnResponse == null) {
nnResponse = new MultiLayerPerceptron(TransferFunctionType.TANH, 4, 2, 1);
// nnResponse = new Perceptron(4, 1);
trainingSet = new DataSet(nnResponse.getInputsCount(), nnResponse.getOutputsCount());
// trainingSet.addRow(new DataSetRow(new double[]{ r, o, m,
// totalChildNum}, new double[]{r, m, o})); //output = input
// case: [true]
trainingSet.addRow(new DataSetRow(new double[] { 0, 0, 0, 0 }, new double[] { 0 }));
trainingSet.addRow(new DataSetRow(new double[] { 1, 0, 0, 1 }, new double[] { 1 }));
// case: [true, false]
/*
trainingSet.addRow(new DataSetRow(new double[] { 1, 0, 0, 2 }, new double[] { 1 }));
trainingSet.addRow(new DataSetRow(new double[] { 1, 0, 1, 2 }, new double[] { 0 }));
trainingSet.addRow(new DataSetRow(new double[] { 2, 1, 0, 2 }, new double[] { 1 }));
trainingSet.addRow(new DataSetRow(new double[] { 2, 1, 1, 2 }, new double[] { -1 }));
//*/
nnResponse.learn(trainingSet);
}
int _m = random.nextInt(totalChildNum + 1);
int _o = random.nextInt(totalChildNum + 1);
int _t = random.nextInt(totalChildNum + 1);
nnResponse.setInput(r, _o, _m, _t);
nnResponse.calculate();
double[] output = nnResponse.getOutput();
trainingSet = new DataSet(nnResponse.getInputsCount(), nnResponse.getOutputsCount());
trainingSet.addRow(new DataSetRow(new double[] { r, o, m, totalChildNum }, new double[] { result }));
// trainingSet.addRow(new DataSetRow(new double[] { r, _o, _m, _t },
// new double[] { result }));
if (random.nextDouble() < 0.005 || (ihasmud && isLearning)) {
nnResponse.learn(trainingSet);
}
return (int) Math.round(output[0]);
} else {
return result;
}
}
private int otherResponseMudNum(int r) {
if (r > round || r <= 0)
return 0;
else {
int mudNum = 0;
for (Integer i : othersResponse.get(r - 1)) {
if (i == 1)
mudNum++;
}
return mudNum;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment