Last active
December 17, 2015 18:39
-
-
Save hungtatai/5654987 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} | |
/* | |
* 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; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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