I'm writing a program counting average delay in given network. I use a JUNG library. On input my program reads information how many packets vertex x want to send to vertex y for second. My graph is unweighted and I assume that packets are sending by shortest path.
I use JUNG methods to get shortest path:
public class NetworkGraph {
protected final Graph graph;
protected Vertex[] vertices;
protected Random random;
protected double sumOfFlowStrengthMatrix;
protected final int[][] flowStrengthMatrix;
NetworkGraph(Input input, Graph graph) {
random = new Random();
this.graph = graph;
loadVertices(input);
loadEdges(input);
loadSumOfFlowStrengthMatrix(input);
flowStrengthMatrix = input.getFlowStrengthMatrix();
}
private void loadVertices(Input input) {
vertices = new Vertex[input.getNumberOfVertices()];
for (int i = 0; i < input.getNumberOfVertices(); i++) {
vertices[i] = new Vertex(i + 1);
graph.addVertex(vertices[i]);
}
}
private void loadEdges(Input input) {
for (int i = 0; i < input.getNumberOfVertices(); i++) {
for (int j = 0; j < input.getNumberOfVertices(); j++) {
if (input.getProbabilityOfDivulsionArray()[i][j] != 0) {
if (graph.findEdge(vertices[i], vertices[j]) == null) {
graph.addEdge(new Edge(input.getCapacityArray()[i][j], input.getProbabilityOfDivulsionArray()[i][j]), vertices[i], vertices[j]);
}
}
}
}
}
private void loadSumOfFlowStrengthMatrix(Input input) {
double sum = 0;
for (int i = 0; i < input.getNumberOfVertices(); i++) {
for (int j = 0; j < input.getNumberOfVertices(); j++) {
sum += input.getFlowStrengthMatrix()[i][j];
}
}
this.sumOfFlowStrengthMatrix = sum;
}
public double countAveragePacketDelayInNetwork() throws EdgeException {
double out = 0;
ArrayList<Edge> edges = new ArrayList<>(graph.getEdges());
recountFlows();
for (Edge e : edges) {
out += e.getAveragePacketDelay();
}
return round((out / sumOfFlowStrengthMatrix), 4);
}
protected void recountFlows() {
for (int i = 0; i < vertices.length; i++) {
for (int j = 0; j < vertices.length; j++) {
DijkstraShortestPath<Vertex, Edge> algorithm = new DijkstraShortestPath<>(graph);
List<Edge> edges = algorithm.getPath(vertices[i], vertices[j]);
for (Edge edge : edges) {
edge.addToFlowStrength(flowStrengthMatrix[i][j]);
}
}
}
}
}
I ran my program several times with the same sample graph. Unfortunately I got a different results - for each time I have different average delay - it's really annoying.
Probably it's caused by Dijkstra algorithm - I noticed that Dijkstra algorithm returns different results for the same input. I know that it can be many shortest path from x to y, but why Dijkstra algorithm returns different paths when the input and way of creating graph is exactly the same every time?
Is there any way to make this algorithm returns always the same shortest path for given x and y?
As Tony_craft said, we lack enough information about how the graph is built that a definitive answer is not possible.
However, there are two basic reasons why you might be getting different paths each time:
(1) The graph is not the same each time.
(2) The edges are being iterated over in a different order and you're getting a different edge of the same weight. Order of iteration over a Set (of outgoing edges) is not guaranteed to be consistent.
Related
I'm working on a genetic algorithm which recreates paintings using triangles. At the moment my method used to populate children is changing the values of the parents and I can't figure out why.
public void populate()
{
System.out.println("pre: " + Arrays.toString(triangles[0][0]));
for(int drawNum = 2; drawNum < 12; drawNum ++)
{
for(int triNum = 0; triNum < numTriangles; triNum ++)
{
double pChooser = Math.random();
if(pChooser < .45)
{
triangles[drawNum][triNum] = triangles[0][triNum];
}
else if(pChooser < .9)
{
triangles[drawNum][triNum] = triangles[1][triNum];
}
else
{
triangles[drawNum][triNum] = randomTriangle();
}
}
}
genNum ++;
System.out.println("pst: " + Arrays.toString(triangles[0][0]));
}
private int[] randomTriangle()
{
int[] result = new int[9];
for(int i = 0; i < 9; i++)
{
result[i] = (int) (Math.random() * 256);
}
return result;
}
triangles is a 3 dimensional int array that holds each drawing, each triangle in the drawing, and each value of the endpoints and color of the triangle in the form triangles[drawingNumber][triangleNumber][values]. triangles[0] and triangles[1] are the two parents. The print statements print the values of the first triangle in the first parent before and after the children are formed. However, the pre and post print statements are returning different results, meaning that triangles[0][0] was changed somewhere in the code, but I can't figure out where that is.
I'm trying to learn Prim's algorithm and I'm using this website to do so, but I'm having trouble making the code part of it run. I'm confused with what goes in public static int Prims(Vector<Vector<node>> adjList) and how to get the code to compile and run. (New to java so excuse me if its a silly question).
edit: This is the code I'm trying to run:
class node implements Comparable<node> {
int weight, index;
public node(int weight, int index) {
this.weight = weight;
this.index = index;
}
public int compareTo(node e) {
return weight - e.weight;
}
}public static int Prims(Vector<Vector<node>> adjList) {
// Current cost of MST.
int cost = 0;
int n = adjList.size();
PriorityQueue<node> pq = new PriorityQueue<node>();
// Keep track if each node is visited.
boolean visited[] = new boolean[n];
for (int i = 0; i < n; i++) {
visited[i] = false;
}
// Number of nodes visited.
int inTree = 1;
// Mark starting node as visited.
visited[0] = true;
// Add all edges of starting node.
for (int i = 0; i < adjList.get(0).size(); i++) {
pq.add(adjList.get(0).get(i));
}
// Keep going until all nodes visited.
while (!pq.isEmpty() && inTree < n) {
// Get the edge with the smallest weight.
node cur = pq.poll();
// Skip if node already used.
if (visited[cur.index]) {
continue;
}
inTree++;
visited[cur.index] = true;
cost += cur.weight;
// Add all the edges of the new node to the priority queue.
for (int i = 0; i < adjList.get(cur.index).size(); i++) {
pq.add(adjList.get(cur.index).get(i));
}
}
// Graph not connected if number of nodes used is less than total nodes.
if (inTree < n) {
return -1;
}
return cost;
}
Your method public static int Prims(Vector<Vector<node>> adjList) does not appear to be a member of a class. It needs to be. The leading } on the line
}public static int Prims(Vector<Vector<node>> adjList) {
should probable be moved to the end of the file.
If you do not use an IDE to compile and run a code you need to issue the following commands:
javac MyCode.java
java MyCode
where I suppose your code resides in a file named MyCode.java and there is no package defined.
for a while now, i I am writing my own neural network for recognizing digits. It works perfectly fine for one given input and one expected output. It's getting close to the values until the total error is arround around 0.00001 or something like that. But obviously i need my network to learn more then one pattern. I've written my own class DataSet which stores inputs and desired outputs. My question now is: How do i get my program to learn every single pattern from my set. For now i am doing it like this: just learning every pattern one by one and hoping that the total error is getting better. But in my net with (784 = 28*28) input neurons, 15 hidden neurons and 10 output neurons and only 3 patterns, why total error is arround 0.4 It doesnt match the target at all so i want to ask you what i can do.
My code below:
public void CalculateSignalErrors(Matrix1d in, Matrix1d exp) {
int i, j, k, OutputLayer;
double Sum;
this.calculate(in, false);
for (i = 0; i < this.OUTPUT_SIZE; i++) {
signalErrors[this.NETWORK_SIZE - 1].set(i,
(this.outputs[this.NETWORK_SIZE - 1].get(i) - exp.get(i))
* this.derivatives[this.NETWORK_SIZE - 1].get(i));
}
for(i = this.NETWORK_SIZE - 2; i > 0; i--){
for(j = 0; j < outputs[i].X; j ++){
Sum = 0;
for(k = 0; k < outputs[i+1].X; k++){
Sum = Sum + weights[i+1].get(k, j) *
signalErrors[i+1].get(k);
}
signalErrors[i].set(j,derivatives[i].get(j) * Sum);
}
}
}
public void backpropagateError(double eta) {
int i,j,k;
for(i = this.NETWORK_SIZE-1; i > 0; i--){
for(j = 0; j < outputs[i].X; j++){
for(k = 0; k < outputs[i-1].X; k++){
this.weights[i].set(j, k,this.weights[i].get(j, k) + (-eta * this.signalErrors[i].get(j) * this.outputs[i-1].get(k)));
}
this.biases[i].set(j, this.biases[i].get(j) - eta * this.signalErrors[i].get(j));
}
}
}
public void train(Matrix1d in, Matrix1d exp, double eta){
this.CalculateSignalErrors(in, exp);
this.backpropagateError(eta);
}
and my training for datasets:
public void train(TrainSet set, double epochs, double eta, boolean printIt){
for(int e = 0; e < epochs; e ++){
TrainSetIterator it = set.iterator();
while(it.hasNext()){
Matrix1d[] v = it.next();
this.train(v[0], v[1], eta);
}
if(printIt){
//System.out.format("%-9s %-7s %-15s%n", "Epoch:", e , outputError(set));
System.out.println(outputError(set));
}
}
}
My error calculations:
public double outputError(Matrix1d input, Matrix1d expected) {
Matrix1d out = this.calculate(input, false);
expected = expected.clone();
out.sub(expected);
return (out.length() * out.length() * 0.5);
}
public double outputError(TrainSet set){
TrainSetIterator it = set.iterator();
double e = 0;
while(it.hasNext()){
Matrix1d[] o = it.next();
e += outputError(o[0], o[1]);
}
return (e / (double)(set.size()));
}
Also it's important to know that while i feed my data forward, i'm writing my derivatives directly into the neurons (incase you wonder what derivative[x].get(y) means. (x = layer) (y = neuron)
Trying to get a multi-threaded matrix multiplication to work in Java. It is given a (m x n) matrix, a (n x k) matrix and 't' threads to perform the operation on.
My program works when the matrices are square and t == n. When running with t < n, the other threads do not pick up the additional operations, and it returns a partially completed matrix. When the matrices are not square, the additional threads return array out of bounds errors and do not run. I would really appreciate any advice. Here are the relevant code snippets
Beginning threads. multipliers is an array of MatrixMultiplier, a class defined later.
Multiply multiply = new Multiply(cols_mat, rows_mat2);
for (int i = 0; i < threads; i++) {
multipliers[i] = new MatrixMultiplier(multiply);
}
for (int i = 0; i < threads; i++) {
my_threads[i] = new Thread(multipliers[i]);
}
for (int i = 0; i < threads; i++) {
my_threads[i].start();
}
for (int i = 0; i < threads; i++) {
my_threads[i].join();
}
Multiply class which defines the matrix multiplication
class Multiply extends MatrixMultiplication {
private int i;
private int j;
private int chance;
public Multiply(int i, int j) {
this.i = i;
this.j = j;
chance = 0;
}
public synchronized void multiplyMatrix() {
int sum = 0;
int a = 0;
for (a = 0; a < i; a++) {
sum = 0;
for (int b = 0; b < j; b++) {
sum = sum + mat[chance][b] * mat2[b][a];
}
result[chance][a] = sum;
}
if (chance >= i)
return;
chance++;
}
}
And the matrix multiplier
class MatrixMultiplier implements Runnable {
private final Multiply mul;
public MatrixMultiplier(Multiply mul) {
this.mul = mul;
}
#Override
public void run() {
mul.multiplyMatrix();
}
}
Where I personally think the issue lies is with if (chance >= i) return; but I have not found a way to incorporate a thread's column responsibilities with the program still working. Again, any advice pointing me in the right direction would be greatly appreciated.
There are several issues with your code.
The t threads assume that only t multiplications are required to produce your result matrix. This is not to be the case when m != k or t != m or t != k. The threads are worker threads that will only process your requests. I would consider making each MatrixMultiplier have access to the mxn, nxk, mxk matrices and a rolcolumn entries container.
class MatricMultiplier {
private double a[][], b[][], results[][];
private Queue<..> entries;
....
}
The run method will then use the entries container to calculate the sum for a given <row,column> entry of the resulting mxk matrix. The run method could become:
run() {
for (Entry entry = entries.poll(); entry != null; entry = entries.poll()) {
int row = entry.row;
int col = entry.col;
double sum = 0.0;
for (int i = 0; i < a[row].length; i++) {
sum += a[row][i] * b[i][col];
}
results[row][col] = sum;
}
}
There are three things to note here that is different than what you have.
you are not using a synchronization block
each entry is calculating the answer for a unique row/column of the result matrix
the Multiple class is not required any longer
You can then create t threads that process each entry in the entries container and will exit when the entries container is empty.
Note that the entries container should be one of the concurrent Queue containers available in the java.util.concurrent package.
The remaining task is how to create the rowcolumn entries container. Here is some code that you could use:
Queue<..> entries = new Concurrent...<..>();
int rowSize = a.length;
int colSize = b[0].length;
for (int row = 0; row < rowSize; row++) {
for (int col = 0; col < colSize; col++) {
entries.add(new RowColumnEntry(row, col));
}
}
Noting that the a and b are the m×n and n×k matrices.
Hope this helps.
The below code is my implementation of temporal difference learning. The agent who uses the TD algorithm plays more than 750,000 games against an agent that uses mini-max procedure to play the game, But the problem is the TD-agent does not learn... What is wrong with this implementation?
updateToNextState is called when the agent choose a next move.
public void updateToNextState(int[] currentState, double[] nextStateOutput) {
double[] outputOfNext = nextStateOutput;
double[] outputOfCurrent = getOutput(currentState);
double[] error = getDifferenceOfOutputs(outputOfNext, outputOfCurrent);
lastHandledState = currentState;
for (int j = 0; j < layers[HIDDEN].neurons.length; j++) {
for (int k = 0; k < layers[OUTPUT].neurons.length; k++) {
double toBeUpdatedValueForJToK = BETA * error[k]
* eligibilityTraces.getEjk(j, k);
layers[HIDDEN].neurons[j].updateWeightToNeuron(
layers[OUTPUT].neurons[k].getNeuronId(),
toBeUpdatedValueForJToK);
for (int i = 0; i < layers[INPUT].neurons.length; i++) {
double toBeUpdatedValueForIToJ = ALPHA * error[k]
* eligibilityTraces.getEijk(i, j, k);
layers[INPUT].neurons[i].updateWeightToNeuron(
layers[HIDDEN].neurons[j].getNeuronId(),
toBeUpdatedValueForIToJ);
}
}
}
updateEligibilityTraces(currentState);
}
private void updateEligibilityTraces(int[] currentState) {
// to ensure that the values in neurons are originated from current
// state
feedForward(currentState);
for (int j = 0; j < layers[HIDDEN].neurons.length; j++) {
for (int k = 0; k < layers[OUTPUT].neurons.length; k++) {
double toBeUpdatedValueForJK = gradient(layers[OUTPUT].neurons[k])
* layers[HIDDEN].neurons[j].output;
eligibilityTraces.updateEjk(j, k, toBeUpdatedValueForJK);
for (int i = 0; i < layers[INPUT].neurons.length; i++) {
double toBeUpdatedValueForIJK = gradient(layers[OUTPUT].neurons[k])
* gradient(layers[HIDDEN].neurons[j])
* layers[INPUT].neurons[i].output
* layers[HIDDEN].neurons[j]
.getWeightToNeuron(layers[OUTPUT].neurons[k]
.getNeuronId());
eligibilityTraces.updateEijk(i, j, k,
toBeUpdatedValueForIJK);
}
}
}
}
private double gradient(Neuron neuron) {
return neuron.output * (1 - neuron.output);
}
public void updateToNextWhenOpponentEndsGame(double[] outputOfEndState) {
updateToNextState(lastHandledState, outputOfEndState);
}
private double[] getDifferenceOfOutputs(double[] outputNext,
double[] outputCurrent) {
double[] differencesVector = new double[outputNext.length];
for (int i = 0; i < outputNext.length; i++) {
double difference = outputNext[i] - outputCurrent[i];
differencesVector[i] = difference;
}
return differencesVector;
}
I have used this link as guide line. I have tried different values for ALPHA & BETA, amount of hidden neurons. Eligibility traces are initialized to 0.
The problem mainly is that you cannot tune your neural network function approximator, and from what you said I can assume that "it does not learn", means that the algorithm does not converge.
This happens when we use using TD and NN together. And this happened to me previously, and I searched for it for a long time. The lesson that I have learned is as follows:
According to Richard Sutton: Do not try to use Neural Networks as function approximators, together with TD methods, unless you know exactly how to tune your neural network. Otherwise, this will cause lots of problems.
To know more about it find Sutton's talk on youtube.