I wrote a program which is solving the Simplex Method but it works only on equations where the number of constraints is equal or less then the number of variables in the target function. If there is any other equation there is an OutOfBoundsException and I don't know how to solve this problem. If someone knows please tell me or share the link to the working algorithm.
private static int ROW;
private static int COL;
private static Scanner scanner = new Scanner(System.in);
private static double[] calctemp(double[] temp, double[][] constLeft,
double[] targetFunc, int[] basic) {
double[] calcTemp = new double[temp.length];
for (int i = 0; i < COL; i++) {
calcTemp[i] = 0;
for (int j = 0; j < ROW; j++) {
calcTemp[i] += targetFunc[basic[j]] * constLeft[j][i];
}
calcTemp[i] -= targetFunc[i];
}
return calcTemp;
}
private static int minimum(double[] arr) {
double arrmin = arr[0];
int minPos = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] < arrmin) {
arrmin = arr[i];
minPos = i;
}
}
return minPos;
}
private static void printFrame(double[] targetFunc) {
StringBuilder sb = new StringBuilder();
sb.append("Cj\t\t\t");
for (int i = 0; i < targetFunc.length; i++) {
sb.append(targetFunc[i] + "\t");
}
sb.append("\ncB\txB\tb\t");
for (int i = 0; i < targetFunc.length; i++) {
sb.append("a" + (i + 1) + "\t");
}
System.out.print(sb);
}
private static void printAll(double[] targetFunc, double[] constraintRight,
double[][] constraintLeft, int[] basic) {
printFrame(targetFunc);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ROW; i++) {
sb.append("\n" + targetFunc[basic[i]] + "\tx" + (basic[i] + 1)
+ "\t" + constraintRight[i] + "\t");
for (int j = 0; j < COL; j++) {
sb.append(constraintLeft[i][j] + "\t");
}
sb.append("\n");
}
System.out.println(sb);
}
public static void main(String[] args) {
double[] targetFunc = { 6, -5, 0, 0};
ROW = 2;
COL = 2 + ROW;
double[][] constraintsLeft = { { 2, 5, 1, 0 },
{ 5, 2, 0, 1 }};
double[] constraintsRight = { 10, 10 };
double[] temp = new double[COL];
int tempMinPos;
double[] miniRatio = new double[ROW];
int miniRatioMinPos = 0;
double key;
int goOutCol = 0;
double z;
double[] x = new double[COL];
int[] basic = new int[ROW];
int[] nonBasic = new int[ROW];
boolean flag = false;
for (int i = 0; i < ROW; i++) {
basic[i] = (i + ROW);
nonBasic[i] = i;
}
System.out.println("------------Calculating------------");
while (!flag) {
z = 0;
temp = calctemp(temp, constraintsLeft, targetFunc, basic);
tempMinPos = minimum(temp);
printAll(targetFunc, constraintsRight, constraintsLeft, basic);
System.out.print("Zj-Cj\t\t\t");
for (int i = 0; i < COL; i++) {
System.out.print(temp[i] + "\t");
}
System.out
.println("\n--------------------------------------------------");
System.out.println("Basic variables : ");
for (int i = 0; i < ROW; i++) {
x[basic[i]] = constraintsRight[i];
x[nonBasic[i]] = 0;
System.out.println("x" + (basic[i] + 1) + " = "
+ constraintsRight[i]);
}
for (int i = 0; i < ROW; i++) {
z = z + targetFunc[i] * x[i];
}
System.out.println("Max(z) = " + z);
for (int i = 0; i < ROW; i++) {
if (constraintsLeft[i][tempMinPos] <= 0) {
miniRatio[i] = 999;
continue;
}
miniRatio[i] = constraintsRight[i]
/ constraintsLeft[i][tempMinPos];
}
miniRatioMinPos = minimum(miniRatio);
for (int i = 0; i < ROW; i++) {
if (miniRatioMinPos == i) {
goOutCol = basic[i];
}
}
System.out.println("Outgoing variable : x" + (goOutCol + 1));
System.out.println("Incoming variable : x" + (tempMinPos + 1));
basic[miniRatioMinPos] = tempMinPos;
nonBasic[tempMinPos] = goOutCol;
key = constraintsLeft[miniRatioMinPos][tempMinPos];
constraintsRight[miniRatioMinPos] /= key;
for (int i = 0; i < COL; i++) {
constraintsLeft[miniRatioMinPos][i] /= key;
}
for (int i = 0; i < ROW; i++) {
if (miniRatioMinPos == i) {
continue;
}
key = constraintsLeft[i][tempMinPos];
for (int j = 0; j < COL; j++) {
constraintsLeft[i][j] -= constraintsLeft[miniRatioMinPos][j]
* key;
}
constraintsRight[i] -= constraintsRight[miniRatioMinPos] * key;
}
for (int i = 0; i < COL; i++) {
flag = true;
if (temp[i] < 0) {
flag = false;
break;
}
}
}
}
I entered some equation to solve. It's is solved right.
Try to change on this
double[] targetFunc = { 8, 2, 0, 0, 0};
ROW = 3;
COL = 2 + ROW;
double[][] constraintsLeft = { { 1, -4, 1, 0, 0 },
{ -4, 1, 0, 1, 0 },
{ 1, 1, 0, 0, 1}};
double[] constraintsRight = { 4, 4, 6 };
Here is my scala version. I tried it on degenerated case and I think it supports the "Brand Rule".
object Simplex {
sealed trait Pivot {};
case class Next(row: Int, col: Int) extends Pivot;
object NoSolution extends Pivot;
object NoMore extends Pivot;
def minSuch[T,U](array: Array[T])(fn: (T,Int)=>Option[U])(implicit order: scala.math.Ordering[U]): Option[(Int, T, U)] = {
#scala.annotation.tailrec
def compute(idx: Int, res: Option[(Int, T, U)]): Option[(Int, T, U)] = if(idx>=array.length) res else (res, fn(array(idx), idx)) match {
case (r , None) => compute(idx+1,r)
case (r # Some((_, _, u1)), Some(u2)) if order.lt(u1, u2) => compute(idx+1, r)
case (_ , Some(u)) => compute(idx+1, Some((idx, array(idx), u)))
}
return compute(0, Option.empty[(Int, T, U)])
}
def solve[T](A: Array[Array[T]], Y: Array[T], C: Array[T])(implicit frac:scala.math.Fractional[T], classtag: scala.reflect.ClassTag[T]) : Option[(T,Array[T])] = {
import scala.math.Fractional.Implicits._
import scala.math.Ordering.Implicits._
val N = (0 to (C.length-1) by +1).toArray
val B = (1 to -(Y.length ) by -1).toArray
val Z = C.map(-_)
var z = frac.zero
def pivot(): Pivot = minSuch(Z) { case (z,_) =>
if( z<frac.zero ) Some(z) else None
}.map { case (col, _, _) =>
minSuch(A) { case(cells,row) =>
if( cells(col)>frac.zero ) Some(Y(row)/cells(col)) else None
}.map { case (row, _, _) =>
new Next(row, col)
}.getOrElse(NoSolution)
}.getOrElse(NoMore)
#scala.annotation.tailrec
def resolve(): Option[(T, Array[T])] = pivot() match {
case NoSolution => None
case NoMore => {
Some((z, Y.zip(B).foldLeft(Array.fill(C.length)(frac.zero))( (result, yb)=>
if( yb._2 >= 0 ) result.updated(yb._2, yb._1) else result
)))
}
case Next(row, col) => {
val coef = A(row)(col)
val tmp = B(row)
B(row) = N(col)
N(col) = tmp
Z(col) = -Z(col) / coef
z = z + Z(col) * Y(row)
for(c <- 0 to Z.length-1 if(c!=col)) Z(c) = Z(c) + A(row)(c) * Z(col)
Y(row) = Y(row) / coef
for(r <- 0 to Y.length-1 if(r!=row)) Y(r) = Y(r) - A(r)(col) * Y(row)
A(row)(col) = frac.one / coef
for(c <- 0 to A(row).length-1 if(col!=c) ) A(row)(c)=A(row)(c)/coef
for(r <- 0 to A.length-1 if(row!=r); c <- 0 to A(r).length-1 if(col!=c)) A(r)(c)=A(r)(c) - A(r)(col) * A(row)(c)
for(r <- 0 to A.length-1 if(row!=r)) A(r)(col) = -A(r)(col) / coef
return resolve()
}
}
return resolve();
}
}
This use case works. I've tried with a cyclic one and it works too...
Simplex.solve(
Array(
Array(Rational(1), Rational(1)),
Array(Rational(1), Rational(-2)),
Array(Rational(-1), Rational(4))
),
Array(
Rational(2),
Rational(0),
Rational(1)
),
Array(Rational(5), Rational(8))
).foreach { result=>
println(result._1)
result._2.foreach(println)
}
Related
I was trying to solve a XOR problem, but the output always converged to 0.5, so i tried a simpler problem like NOT and the same thing happened.
I really don't know what's going on, i checked the code a million times and everything seems to be right, when i debugged it saving the neural network info I saw that the either the weight values or the biases values were getting really large. To do that I followed the 3 blue 1 brown youtube series about neural network and some other videos, too.
this is my code:
PS: I put the entire code here but I think the main problem is inside the bakpropag function
class NeuralNetwork {
int inNum, hiddenLayersNum, outNum, netSize;
int[] hiddenLayerSize;
Matrix[] weights;
Matrix[] biases;
Matrix[] sums;
Matrix[] activations;
Matrix[] error;
Matrix inputs;
long samples = 0;
float learningRate;
//Constructor------------------------------------------------------------------------------------------------------
NeuralNetwork(int inNum, int hiddenLayersNum, int[] hiddenLayerSize, int outNum, float learningRate) {
this.inNum = inNum;
this.hiddenLayersNum = hiddenLayersNum;
this.hiddenLayerSize = hiddenLayerSize;
this.outNum = outNum;
this.netSize = hiddenLayersNum + 1;
this.learningRate = learningRate;
//output layer plus the hidden layer size
//Note: I'm not adding the input layer because it doesn't have weights
weights = new Matrix[netSize];
//no biases added to the output layer
biases = new Matrix[netSize - 1];
sums = new Matrix[netSize];
activations = new Matrix[netSize];
error = new Matrix[netSize];
initializeHiddenLayer();
initializeOutputLayer();
}
//Initializing Algorithms------------------------------------------------------------------------------------------
void initializeHiddenLayer() {
for (int i = 0; i < hiddenLayersNum; i++) {
if (i == 0) {//only the first hidden layer takes the inputs
weights[i] = new Matrix(hiddenLayerSize[i], inNum);
} else {
weights[i] = new Matrix(hiddenLayerSize[i], hiddenLayerSize[i - 1]);
}
biases[i] = new Matrix(hiddenLayerSize[i], 1);
sums[i] = new Matrix(hiddenLayerSize[i], 1);
activations[i] = new Matrix(hiddenLayerSize[i], 1);
error[i] = new Matrix(hiddenLayerSize[i], 1);
}
}
void initializeOutputLayer() {
//the output layer takes the last hidden layer activation values
weights[netSize - 1] = new Matrix(outNum, hiddenLayerSize[hiddenLayerSize.length - 1]);
activations[netSize - 1] = new Matrix(outNum, 1);
sums[netSize - 1] = new Matrix(outNum, 1);
error[netSize - 1] = new Matrix(outNum, 1);
for (Matrix m : weights) {
for (int i = 0; i < m.i; i++) {
for (int j = 0; j < m.j; j++) {
m.values[i][j] = random(-1, 1);
}
}
}
for (Matrix m : biases) {
for (int i = 0; i < m.i; i++) {
for (int j = 0; j < m.j; j++) {
m.values[i][j] = 1;
}
}
}
for (Matrix m : sums) {
for (int i = 0; i < m.i; i++) {
for (int j = 0; j < m.j; j++) {
m.values[i][j] = 0;
}
}
}
}
//Calculation------------------------------------------------------------------------------------------------------
void calculate(float[] inputs) {
this.inputs = new Matrix(0, 0);
this.inputs = this.inputs.arrayToCollumn(inputs);
sums[0] = (weights[0].matrixMult(this.inputs)).sum(biases[0]);
activations[0] = sigM(sums[0]);
for (int i = 1; i < netSize - 1; i++) {
sums[i] = weights[i].matrixMult(activations[i - 1]);
activations[i] = sigM(sums[i]).sum(biases[i]);
}
//there's no biases in the output layer
//And the output layer uses sigmoid function
sums[netSize - 1] = weights[netSize - 1].matrixMult(activations[netSize - 1 - 1]);
activations[netSize - 1] = sigM(sums[netSize - 1]);
}
//Sending outputs--------------------------------------------------------------------------------------------------
Matrix getOuts() {
return activations[netSize - 1];
}
//Backpropagation--------------------------------------------------------------------------------------------------
void calcError(float[] exp) {
Matrix expected = new Matrix(0, 0);
expected = expected.arrayToCollumn(exp);
//E = (output - expected)
error[netSize - 1] = this.getOuts().diff(expected);
samples++;
}
void backPropag(int layer) {
if (layer == netSize - 1) {
error[layer].scalarDiv(samples);
for (int i = layer - 1; i >= 0; i--) {
prevLayerCost(i);
}
weightError(layer);
backPropag(layer - 1);
} else {
weightError(layer);
biasError(layer);
if (layer != 0)
backPropag(layer - 1);
}
}
void weightError(int layer) {
if (layer != 0) {
for (int i = 0; i < weights[layer].i; i++) {
for (int j = 0; j < weights[layer].j; j++) {
float changeWeight = 0;
if (layer != netSize - 1)
changeWeight = activations[layer - 1].values[j][0] * deriSig(sums[layer].values[i][0]) * error[layer].values[i][0];
else
changeWeight = activations[layer - 1].values[j][0] * deriSig(sums[layer].values[i][0]) * error[layer].values[i][0];
weights[layer].values[i][j] += -learningRate * changeWeight;
}
}
} else {
for (int i = 0; i < weights[layer].i; i++) {
for (int j = 0; j < weights[layer].j; j++) {
float changeWeight = this.inputs.values[j][0] * deriSig(sums[layer].values[i][0]) * error[layer].values[i][0];
weights[layer].values[i][j] += -learningRate * changeWeight;
}
}
}
}
void biasError(int layer) {
for (int i = 0; i < biases[layer].i; i++) {
for (int j = 0; j < biases[layer].j; j++) {
float changeBias = 0;
if (layer != netSize - 1)
changeBias = deriSig(sums[layer].values[i][0]) * error[layer].values[i][0];
biases[layer].values[i][j] += -learningRate * changeBias;
}
}
}
void prevLayerCost(int layer) {
for (int i = 0; i < activations[layer].i; i++) {
for (int j = 0; j < activations[layer + 1].j; j++) {//for all conections of that neuron to the next layer
if (layer != netSize - 1)
error[layer].values[i][0] += weights[layer + 1].values[j][i] * deriSig(sums[layer + 1].values[j][0]) * error[layer + 1].values[j][0];
else
error[layer].values[i][0] += weights[layer + 1].values[j][i] * deriSig(sums[layer + 1].values[j][0]) * error[layer + 1].values[j][0];
}
}
}
//Activation Functions---------------------------------------------------------------------------------------------
Matrix reLUM(Matrix m) {
Matrix temp = m.copyM();
for (int i = 0; i < temp.i; i++) {
for (int j = 0; j < temp.j; j++) {
temp.values[i][j] = ReLU(m.values[i][j]);
}
}
return temp;
}
float ReLU(float x) {
return max(0, x);
}
float deriReLU(float x) {
if (x <= 0)
return 0;
else
return 1;
}
Matrix sigM(Matrix m) {
Matrix temp = m.copyM();
for (int i = 0; i < temp.i; i++) {
for (int j = 0; j < temp.j; j++) {
temp.values[i][j] = sig(m.values[i][j]);
}
}
return temp;
}
float sig(float x) {
return 1 / (1 + exp(-x));
}
float deriSig(float x) {
return sig(x) * (1 - sig(x));
}
//Saving Files-----------------------------------------------------------------------------------------------------
void SaveNeuNet() {
for (int i = 0; i < weights.length; i++) {
weights[i].saveM("weights\\weightLayer" + i);
}
for (int i = 0; i < biases.length; i++) {
biases[i].saveM("biases\\biasLayer" + i);
}
for (int i = 0; i < activations.length; i++) {
activations[i].saveM("activations\\activationLayer" + i);
}
for (int i = 0; i < error.length; i++) {
error[i].saveM("errors\\errorLayer" + i);
}
}
}
and this is the Matrix code:
class Matrix {
int i, j, size;
float[][] values;
Matrix(int i, int j) {
this.i = i;
this.j = j;
this.size = i * j;
values = new float[i][j];
}
Matrix sum (Matrix other) {
if (other.i == this.i && other.j == this.j) {
for (int x = 0; x < this.i; x++) {
for (int z = 0; z < this.j; z++) {
values[x][z] += other.values[x][z];
}
}
return this;
}
return null;
}
Matrix diff(Matrix other) {
if (other.i == this.i && other.j == this.j) {
for (int x = 0; x < this.i; x++) {
for (int z = 0; z < this.j; z++) {
values[x][z] -= other.values[x][z];
}
}
return this;
}
return null;
}
Matrix scalarMult(float k) {
for (int i = 0; i < this.i; i++) {
for (int j = 0; j < this.j; j++) {
values[i][j] *= k;
}
}
return this;
}
Matrix scalarDiv(float k) {
if (k != 0) {
for (int i = 0; i < this.i; i++) {
for (int j = 0; j < this.j; j++) {
values[i][j] /= k;
}
}
return this;
} else
return null;
}
Matrix matrixMult(Matrix other) {
if (this.j != other.i)
return null;
else {
Matrix temp = new Matrix(this.i, other.j);
for (int i = 0; i < temp.i; i++) {
for (int j = 0; j < temp.j; j++) {
for (int k = 0; k < this.j; k++) {
temp.values[i][j] += this.values[i][k] * other.values[k][j];
}
}
}
return temp;
}
}
Matrix squaredValues(){
for (int i = 0; i < this.i; i++){
for (int j = 0; j < this.j; j++){
values[i][j] = sq(values[i][j]);
}
}
return this;
}
void printM() {
for (int x = 0; x < this.i; x++) {
print("| ");
for (int z = 0; z < this.j; z++) {
print(values[x][z] + " | ");
}
println();
}
}
void saveM(String name) {
String out = "";
for (int x = 0; x < this.i; x++) {
out += "| ";
for (int z = 0; z < this.j; z++) {
out += values[x][z] + " | ";
}
out += "\n";
}
saveStrings("outputs\\" + name + ".txt", new String[] {out});
}
Matrix arrayToCollumn(float[] array) {
Matrix temp = new Matrix(array.length, 1);
for (int i = 0; i < array.length; i++)
temp.values[i][0] = array[i];
return temp;
}
Matrix arrayToLine(float[] array) {
Matrix temp = new Matrix(1, array.length);
for (int j = 0; j < array.length; j++)
temp.values[0][j] = array[j];
return temp;
}
Matrix copyM(){
Matrix temp = new Matrix(i, j);
for (int i = 0; i < this.i; i++){
for (int j = 0; j < this.j; j++){
temp.values[i][j] = this.values[i][j];
}
}
return temp;
}
}
As I said, the outputs are always converging to 0.5 instead of the actual value 1 or 0
I rewrote the code and it is working now! I have no idea what was wrong with the code before but this one works:
class NeuralNetwork {
int netSize;
float learningRate;
Matrix[] weights;
Matrix[] biases;
Matrix[] activations;
Matrix[] sums;
Matrix[] errors;
NeuralNetwork(int inNum, int hiddenNum, int[] hiddenLayerSize, int outNum, float learningRate) {
netSize = hiddenNum + 1;
this.learningRate = learningRate;
weights = new Matrix[netSize];
biases = new Matrix[netSize - 1];
activations = new Matrix[netSize];
sums = new Matrix[netSize];
errors = new Matrix[netSize];
initializeMatrices(inNum, hiddenNum, hiddenLayerSize, outNum);
}
//INITIALIZING MATRICES
void initializeMatrices(int inNum, int hiddenNum, int[] layerSize, int outNum) {
for (int i = 0; i < hiddenNum; i++) {
if (i == 0)
weights[i] = new Matrix(layerSize[0], inNum);
else
weights[i] = new Matrix(layerSize[i], layerSize[i - 1]);
biases[i] = new Matrix(layerSize[i], 1);
activations[i] = new Matrix(layerSize[i], 1);
errors[i] = new Matrix(layerSize[i], 1);
sums[i] = new Matrix(layerSize[i], 1);
weights[i].randomize(-1, 1);
biases[i].randomize(-1, 1);
activations[i].randomize(-1, 1);
}
weights[netSize - 1] = new Matrix(outNum, layerSize[layerSize.length - 1]);
activations[netSize - 1] = new Matrix(outNum, 1);
errors[netSize - 1] = new Matrix(outNum, 1);
sums[netSize - 1] = new Matrix(outNum, 1);
weights[netSize - 1].randomize(-1, 1);
activations[netSize - 1].randomize(-1, 1);
}
//---------------------------------------------------------------------------------------------------------------
void forwardPropag(float[] ins) {
Matrix inputs = new Matrix(0, 0);
inputs = inputs.arrayToCollumn(ins);
sums[0] = (weights[0].matrixMult(inputs)).sum(biases[0]);
activations[0] = sigM(sums[0]);
for (int i = 1; i < netSize - 1; i++) {
sums[i] = (weights[i].matrixMult(activations[i - 1])).sum(biases[i]);
activations[i] = sigM(sums[i]);
}
//output layer does not have biases
sums[netSize - 1] = weights[netSize - 1].matrixMult(activations[netSize - 2]);
activations[netSize - 1] = sigM(sums[netSize - 1]);
}
Matrix predict(float[] inputs) {
forwardPropag(inputs);
return activations[netSize - 1].copyM();
}
//SUPERVISED LEARNING - BACKPROPAGATION
void train(float[] inps, float[] expec) {
Matrix expected = new Matrix(0, 0);
expected = expected.arrayToCollumn(expec);
errors[netSize - 1] = predict(inps).diff(expected);
calcErorrPrevLayers();
adjustWeights(inps);
adjustBiases();
for (Matrix m : errors){
m.reset();
}
}
void calcErorrPrevLayers() {
for (int l = netSize - 2; l >= 0; l--) {
for (int i = 0; i < activations[l].i; i++) {
for (int j = 0; j < activations[l + 1].i; j++) {
errors[l].values[i][0] += weights[l + 1].values[j][i] * dSig(sums[l + 1].values[j][0]) * errors[l + 1].values[j][0];
}
}
}
}
void adjustWeights(float[] inputs) {
for (int l = 0; l < netSize; l++) {
if (l == 0) {
//for ervery neuron n in the first layer
for (int n = 0; n < activations[l].i; n++) {
//for every weight w of the first layer
for (int w = 0; w < inputs.length; w++) {
float weightChange = inputs[w] * dSig(sums[l].values[n][0]) * errors[l].values[n][0];
weights[l].values[n][w] += -learningRate * weightChange;
}
}
} else {
//for ervery neuron n in the first layer
for (int n = 0; n < activations[l].i; n++) {
//for every weight w of the first layer
for (int w = 0; w < activations[l - 1].i; w++) {
float weightChange = activations[l - 1].values[w][0] * dSig(sums[l].values[n][0]) * errors[l].values[n][0];
weights[l].values[n][w] += -learningRate * weightChange;
}
}
}
}
}
void adjustBiases() {
for (int l = 0; l < netSize - 1; l++) {
//for ervery neuron n in the first layer
for (int n = 0; n < activations[l].i; n++) {
float biasChange = dSig(sums[l].values[n][0]) * errors[l].values[n][0];
biases[l].values[n][0] += -learningRate * biasChange;
}
}
}
//ACTIVATION FUNCTION
float sig(float x) {
return 1 / (1 + exp(-x));
}
float dSig(float x) {
return sig(x) * (1 - sig(x));
}
Matrix sigM(Matrix m) {
Matrix temp = m.copyM();
for (int i = 0; i < m.i; i++) {
for (int j = 0; j < m.j; j++) {
temp.values[i][j] = sig(m.values[i][j]);
}
}
return temp;
}
}
My Recursive Backtracking approach to Knight's Tour runs into an infinite loop. At first, I thought the problem might be taking this much time in general but some solutions do it in an instant. Please tell what is wrong with my code.
package io.github.thegeekybaniya.InterviewPrep.TopTopics.Backtracking;
import java.util.Arrays;
public class KnightsTour {
private static int counter=0;
public static void main(String[] args) {
knightsTour(8);
}
private static void knightsTour(int i) {
int[][] board = new int[i][i];
for (int[] arr :
board) {
Arrays.fill(arr, -1);
}
board[0][0] = 0;
knightsTour(board,0,1);
}
private static boolean knightsTour(int[][] board, int cellno, int stepno) {
if (stepno == board.length * board.length) {
printBoard(board);
return true;
}
int[][] dirs = {
{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}
};
int row = cellno / board.length, col = cellno % board.length;
for (int i = 0; i < dirs.length; i++) {
int r = dirs[i][0] + row;
int c = dirs[i][1] + col;
if (isSafe(board, r, c)&&board[r][c]==-1) {
int ncell = r * board.length + c;
board[r][c] = stepno;
if (knightsTour(board, ncell, stepno + 1)) {
return true;
} else {
board[r][c] = -1;
}
}
}
return false;
}
private static boolean isSafe(int[][] board, int r, int c) {
return r >= 0 && c >= 0 && r < board.length && c < board.length;
}
private static void printBoard(int[][] board) {
System.out.println(++counter);
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board.length; j++) {
System.out.print(board[i][j]+" ");
}
System.out.println();
}
}
}
There's no bug in your code, it's just that the brute force approach is slow because the search space is enormous. You can speed up the search by implementing Warnsdorf's Rule. This is a heuristic for choosing the next move, where you always try the move that results in the fewest available moves for the next move after that. It can be done in a couple of simple loops:
int row = cellno / board.length, col = cellno % board.length;
// find move with fewest moves available for the next move:
int minMovesAvailable = 8;
int minMovesDir = 0;
for (int i = 0; i < dirs.length; i++) {
int r = dirs[i][0] + row;
int c = dirs[i][1] + col;
if (isSafe(board, r, c)&&board[r][c]==-1)
{
board[r][c] = stepno;
int movesAvailable = 0;
for (int j = 0; j < dirs.length; j++) {
int r2 = dirs[j][0] + r;
int c2 = dirs[j][1] + c;
if (isSafe(board, r2, c2)&&board[r2][c2]==-1)
{
movesAvailable++;
}
}
board[r][c] = -1;
if(movesAvailable < minMovesAvailable)
{
minMovesAvailable = movesAvailable;
minMovesDir = i;
}
}
}
// now recurse this move first:
// int r = dirs[minMovesDir][0] + row;
// int c = dirs[minMovesDir][1] + col;
I have to build Simplex Algorithm and its working but I want to allow user to input data, in method main I made few "for" loops where I put date into arrays, but that I put the same data in another arrays, (they have exactly the same data) I have no idea how to fix it.
When I try to make just one arrays for one type of date, it's crash.
[edit]
Yep, I update those Scanners (thanks guys)
And right now I have this error:
"Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at simplex.Simplex$Modeler.(Simplex.java:224)
at simplex.Simplex.main(Simplex.java:196)"
package simplex;
import java.awt.List;
import java.util.ArrayList;
import java.util.Scanner;
public class Simplex {
private double[][] macierz; // macierz
private int LiczbaOgraniczen; // liczba ograniczen
private int LiczbaX; // liczba zmiennych "orginalnych"
private boolean MaxCzyMin;
private static final boolean MAX = true;
private static final boolean MIN = false;
private int[] baza; // baza[i] = basic variable corresponding to row i
public Simplex(double[][] macierz, int LiczbaOgraniczen, int numberOfOriginalVariable, boolean MaxCzyMin) {
this.MaxCzyMin = MaxCzyMin;
this.LiczbaOgraniczen = LiczbaOgraniczen;
this.LiczbaX = numberOfOriginalVariable;
this.macierz = macierz;
baza = new int[LiczbaOgraniczen];
for (int i = 0; i < LiczbaOgraniczen; i++)
baza[i] = LiczbaX + i;
Licz();
}
// Licz algorytm simples od startowych BFS
private void Licz() {
while (true) {
DrukujInteracje();
int q = 0;
// znajdz kolumne q wchodzącą do bazy
if (MaxCzyMin) {
q = ZnajdzIndexPoz(); //jesli szukamy max
} else {
q = ZnajdzIndexNeg(); //jesli szukamy min
}
if (q == -1){
break; // optimum
}
// znajdz rzad p wychodzący z bazy
int p = minRatioRule(q);
if (p == -1){
throw new ArithmeticException("BLAD");
}
//wiersz - kolumna
piwot(p, q);
// zaktualizuj baze
baza[p] = q;
}
}
// znajdowanie indexu niebazowej kolumny z najbardzoje pozytywnym kosztem
private int ZnajdzIndexPoz() {
int q = 0;
for (int j = 1; j < LiczbaOgraniczen + LiczbaX; j++)
if (macierz[LiczbaOgraniczen][j] > macierz[LiczbaOgraniczen][q])
q = j;
if (macierz[LiczbaOgraniczen][q] <= 0){
return -1; // optimum
} else {
return q;
}
}
// znajdowanie indexu niebazowej kolumny z najbardziej negatywnym kosztem
private int ZnajdzIndexNeg() {
int q = 0;
for (int j = 1; j < LiczbaOgraniczen + LiczbaX; j++)
if (macierz[LiczbaOgraniczen][j] < macierz[LiczbaOgraniczen][q])
q = j;
if (macierz[LiczbaOgraniczen][q] >= 0){
return -1; // optimum
} else {
return q;
}
}
// find row p using min ratio rule (-1 if no such row)
private int minRatioRule(int q) {
int p = -1;
for (int i = 0; i < LiczbaOgraniczen; i++) {
if (macierz[i][q] <= 0)
continue;
else if (p == -1)
p = i;
else if ((macierz[i][LiczbaOgraniczen
+ LiczbaX] / macierz[i][q]) < (macierz[p][LiczbaOgraniczen
+ LiczbaX] / macierz[p][q]))
p = i;
}
return p;
}
//zastosowanie metody Gauss-Jordan, aby doprowadzic macierz do postaci bazowej
private void piwot(int p, int q) {
for (int i = 0; i <= LiczbaOgraniczen; i++)
for (int j = 0; j <= LiczbaOgraniczen + LiczbaX; j++)
if (i != p && j != q)
macierz[i][j] -= macierz[p][j] * macierz[i][q] / macierz[p][q];
for (int i = 0; i <= LiczbaOgraniczen; i++)
if (i != p)
macierz[i][q] = 0.0;
for (int j = 0; j <= LiczbaOgraniczen + LiczbaX; j++)
if (j != q)
macierz[p][j] /= macierz[p][q];
macierz[p][q] = 1.0;
}
// Metoda zwraca wartosc funkcji celu
public double WartoscFunkcjiCelu() {
return -macierz[LiczbaOgraniczen][LiczbaOgraniczen + LiczbaX];
}
// metoda zwaraca wartosc x-ow
public double[] WyliczX() {
double[] x = new double[LiczbaX];
for (int i = 0; i < LiczbaOgraniczen; i++)
if (baza[i] < LiczbaX)
x[baza[i]] = macierz[i][LiczbaOgraniczen + LiczbaX];
return x;
}
// drukuj macierz => drukuj tabele
public void DrukujInteracje() {
System.out.println("Liczba Ograniczen = " + LiczbaOgraniczen);
System.out.println("Liczba zmiennych 'orginalnych' = " + LiczbaX);
for (int i = 0; i <= LiczbaOgraniczen; i++) {
for (int j = 0; j <= LiczbaOgraniczen
+ LiczbaX; j++) {
System.out.printf("%7.2f ", macierz[i][j]);
}
System.out.println();
}
System.out.println("Funkcja celu = " + WartoscFunkcjiCelu());
for (int i = 0; i < LiczbaOgraniczen; i++)
if (baza[i] < LiczbaX)
System.out.println("x_"
+ baza[i]
+ " = "
+ macierz[i][LiczbaOgraniczen + LiczbaX]);
System.out.println();
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Podaj ilosc x");
int iloscX = scan.nextInt();
double[] WspolczynnikiFunkcjiCelu = new double[iloscX + 1];
for(int ggg = 0; ggg < iloscX; ggg++){
System.out.println("Podaj x" + ggg);
WspolczynnikiFunkcjiCelu[ggg] =scan.nextDouble();
}
System.out.println("Podaj ilosc ograniczen");
int iloscOgraniczen = scan.nextInt();
double[][] LewaStronaOgraniczen = new double[iloscOgraniczen][iloscX];
double[] PrawaStronaOgraniczen = new double[iloscOgraniczen + 1];
Znaki[] OperatorOgraniczen = new Znaki [iloscOgraniczen + 1];
for(int ggh = 0;ggh <iloscOgraniczen; ggh++){
System.out.println("Podaj znak ograniczenia (lessThan - equal - greatherThan ");
OperatorOgraniczen[ggh] = Znaki.valueOf(scan.next());
System.out.println("Podaj prawa strone ograniczenia");
PrawaStronaOgraniczen[ggh] = scan.nextDouble();
for(int haha = 0; haha < iloscX; haha++){
System.out.println("Lewa strona: Podaj wspolczynnik przy x" + haha);
LewaStronaOgraniczen[ggh][haha] =scan.nextDouble();
}
}
//double[] WspolczynnikiFunkcjiCelu = {Xsy[0], Xsy[1]};
// double[][] LewaStronaOgraniczen = {
// { TablicaTablic[0][0], TablicaTablic[0][1] }, { TablicaTablic[1][0], TablicaTablic[1][1] }, { TablicaTablic[2][0], TablicaTablic[2][1] }, { TablicaTablic[3][0], TablicaTablic[3][1] } };
//Znaki[] OperatorOgraniczen = { TablicaOgraniczen[0], TablicaOgraniczen[1], TablicaOgraniczen[2], TablicaOgraniczen[3] };
//double[] PrawaStronaOgraniczen = {TablicaPrawejStrony[0],TablicaPrawejStrony[1],TablicaPrawejStrony[2],TablicaPrawejStrony[3]};
Modeler model = new Modeler(LewaStronaOgraniczen, PrawaStronaOgraniczen, OperatorOgraniczen, WspolczynnikiFunkcjiCelu);
Simplex simplex = new Simplex(model.getmacierz(),
model.getLiczbaOgraniczen(),
model.getLiczbaX(), MAX);
double[] x = simplex.WyliczX();
for (int i = 0; i < x.length; i++)
System.out.println("x[" + i + "] = " + x[i]);
System.out.println("Rozwiazanie optymalne: " + simplex.WartoscFunkcjiCelu());
}
//zbior mozliwych znakow ograniczajacych
private enum Znaki {
lessThan, equal, greatherThan
}
public static class Modeler {
private double[][] a; // macierz
private int LiczbaOgraniczen; // Liczba Ograniczen
private int LiczbaX; // Liczba x w funkcji celu
public Modeler(double[][] LewaStronaOgraniczen,double[] PrawaStronaOgraniczen, Znaki[] OperatorOgraniczen, double[] WspolczynnikiFunkcjiCelu) {
LiczbaOgraniczen = PrawaStronaOgraniczen.length;
LiczbaX = WspolczynnikiFunkcjiCelu.length;
a = new double[LiczbaOgraniczen + 1][LiczbaX + LiczbaOgraniczen + 1];
for (int i = 0; i < LiczbaOgraniczen; i++) {
for (int j = 0; j < LiczbaX; j++) {
a[i][j] = LewaStronaOgraniczen[i][j];
}
}
for (int i = 0; i < LiczbaOgraniczen; i++)
a[i][LiczbaOgraniczen + LiczbaX] = PrawaStronaOgraniczen[i];
for (int i = 0; i < LiczbaOgraniczen; i++) {
int slack = 0;
switch (OperatorOgraniczen[i]) {
case greatherThan:
slack = -1;
break;
case lessThan:
slack = 1;
break;
default:
}
a[i][LiczbaX + i] = slack;
}
for (int j = 0; j < LiczbaX; j++)
a[LiczbaOgraniczen][j] = WspolczynnikiFunkcjiCelu[j];
}
public double[][] getmacierz() {
return a;
}
public int getLiczbaOgraniczen() {
return LiczbaOgraniczen;
}
public int getLiczbaX() {
return LiczbaX;
}
}
}
why have you so many scanners? Try use only one. Declare and initialize it at the beginning main method.
I was tasked with creating a 2D array (10-by-10), filling it with random numbers (from 10 to 99), and other tasks. I am, however, having difficulty sorting each row of this array in ascending order without using the array sort() method.
My sorting method does not sort. Instead, it prints out values diagonally, from the top leftmost corner to the bottom right corner. What should I do to sort the numbers?
Here is my code:
public class Program3
{
public static void main(String args[])
{
int[][] arrayOne = new int[10][10];
int[][] arrayTwo = new int[10][10];
arrayTwo = fillArray(arrayOne);
System.out.println("");
looper(arrayTwo);
System.out.println("");
sorter(arrayTwo);
}
public static int randomRange(int min, int max)
{
// Where (int)(Math.random() * ((upperbound - lowerbound) + 1) + lowerbound);
return (int)(Math.random()* ((max - min) + 1) + min);
}
public static int[][] fillArray(int x[][])
{
for (int row = 0; row < x.length; row++)
{
for (int column = 0; column < x[row].length; column++)
{
x[row][column] = randomRange(10,99);
System.out.print(x[row][column] + "\t");
}
System.out.println();
}
return x;
}
public static void looper(int y[][])
{
for (int row = 0; row < y.length; row++)
{
for (int column = 0; column < y[row].length; column++)
{
if (y[row][column]%2 == 0)
{
y[row][column] = 2 * y[row][column];
if (y[row][column]%10 == 0)
{
y[row][column] = y[row][column]/10;
}
}
else if (y[row][column] == 59)
{
y[row][column] = 99;
}
System.out.print(y[row][column] + "\t");
}
System.out.println();
}
//return y;
}
public static void sorter(int[][] z)
{
int temp = 0;
int tempTwo = 0;
int lowest;
int bravo = 0;
int bravoBefore = -1;
for (int alpha = 0; alpha < z.length; alpha++)
{
//System.out.println(alpha + "a");
lowest = z[alpha][bravoBefore + 1];
bravoBefore++;
for (bravo = alpha + 1; bravo < z[alpha].length; bravo++)
{
//System.out.println(alpha + "b");
temp = bravo;
if((z[alpha][bravo]) < lowest)
{
temp = bravo;
lowest = z[alpha][bravo];
//System.out.println(lowest + " " + temp);
//System.out.println(alpha + "c" + temp);
tempTwo = z[alpha][bravo];
z[alpha][bravo] = z[alpha][temp];
z[alpha][temp] = tempTwo;
//System.out.println(alpha + "d" + temp);
}
}
System.out.print(z[alpha][bravoBefore] + "\t");
}
/*
for (int alpha = 0; alpha < z.length; alpha++)
{
for (int bravo = 0; bravo < z.length - 1; bravo++)
{
if(Integer.valueOf(z[alpha][bravo]) < Integer.valueOf(z[alpha - 1][bravo]))
{
int[][] temp = z[alpha - 1][bravo];
z[alpha-1][bravo] = z[alpha][bravo];
z[alpha][bravo] = temp;
}
}
}
*/
}
}
for(int k = 0; k < arr.length; k++)
{
for(int p = 0; p < arr[k].length; p++)
{
least = arr[k][p];
for(int i = k; i < arr.length; i++)
{
if(i == k)
z = p + 1;
else
z = 0;
for(;z < arr[i].length; z++)
{
if(arr[i][z] <= small)
{
least = array[i][z];
row = i;
col = z;
}
}
}
arr[row][col] = arr[k][p];
arr[k][p] = least;
System.out.print(arr[k][p] + " ");
}
System.out.println();
}
Hope this code helps . Happy coding
let x is our unsorted array;
int t1=0;
int i1=0;
int j1=0;
int n=0;
boolean f1=false;
for(int i=0;i<x.length;i++){
for(int j=0;j<x[i].length;j++){
t1=x[i][j];
for(int m=i;m<x.length;m++){
if(m==i)n=j+1;
else n=0;
for(;n<x[m].length;n++){
if(x[m][n]<=t1){
t1=x[m][n];
i1=m;
j1=n;
f1=true;
}
}
}
if(f1){
x[i1][j1]=x[i][j];
x[i][j]=t1;
f1=false;
}
}
}
//now x is sorted; "-";
This is the code for my sorting attempt. After running for about ten minutes in Eclipse's debugger mode, I got a lot of StackOverFlow errors. This was my output display:
Exception in thread "main" java.lang.StackOverflowError
at TestSorter.Tester.sort(Tester.java:6)
... (x112 repetitions of at TestSorter.Tester.sort(Tester.java:49))
at TestSorter.Tester.sort(Tester.java:49)
public static int[] sort(int[] a) {
int prod = (a.length)/2, b = lessThan(a, prod), c = greaterThan(a, prod), d = equalTo(a, prod);
int[] first, last, mid;
first = new int[b];
last = new int[c];
mid = new int[d];
int[] fina = new int[a.length];
int f = 0, l = 0, m = 0;
if (isSorted(a))
return a;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
first[f] = a[x];
f++;
}
else if (a[x] > prod) {
last[l] = a[x];
l++;
}
else if (a[x] == prod) {
mid[m] = a[x];
m++;
}
}
if (m == a.length)
return a;
first = sort(first);
last = sort(last);
for (int x = 0; x < b; x++) {
fina[x] += first[x];
}
for (int x = 0; x < d; x++) {
fina[x + b] = mid[x];
}
for (int x = 0; x < c; x++) {
fina[x + b + c] = last[x];
}
return fina;
}
My support methods are as follows:
private static int lessThan(int[] a, int prod) {
int less = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
less++;
}
}
return less;
}
private static int greaterThan(int[] a, int prod) {
int greater = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] > prod) {
greater++;
}
}
return greater;
}
private static int equalTo(int[] a, int prod) {
int equal = 0;
for (int x = 0; x < a.length; x++) {
if (a[x] == prod) {
equal++;
}
}
return equal;
}
private static boolean isSorted(int[] a) {
for (int x = 0; x < a.length - 1; x++) {
if (a[x] > a[x + 1])
return false;
}
return true;
}
Presumably the trouble is that your "prod" is not within the domain of your array. Thus either "first" or "last" is the same size as the input array, and you have an infinite recursion. Try setting prod to be an element in the array you are trying to sort.
THREE POINTS:
The pord should be the mid-element of the array, NOT the half of the array's length.
So, it should be prod =a[(a.length) / 2],
NOT prod =(a.length) / 2
If the array first only have 1 element, it does not need invoke the method sort any more.
Also the last.
So, add if statement:
if (1 < first.length) {
first = sort(first);
}
When you append the element of last to fina, the index should be x+b+d, it means first elements(b) + mid elements(d). NOT x+b+c.
So, change fina[x + b + c] = last[x]; to fina[x + b + d] = last[x];
Well, the method sort maybe like this:
public static int[] sort(int[] a) {
int prod =a[(a.length) / 2], b = lessThan(a, prod), c = greaterThan(a,
prod), d = equalTo(a, prod);
int[] first, last, mid;
first = new int[b];
last = new int[c];
mid = new int[d];
int[] fina = new int[a.length];
int f = 0, l = 0, m = 0;
if (isSorted(a) )
return a;
for (int x = 0; x < a.length; x++) {
if (a[x] < prod) {
first[f] = a[x];
f++;
} else if (a[x] > prod) {
last[l] = a[x];
l++;
} else if (a[x] == prod) {
mid[m] = a[x];
m++;
}
}
if (m == a.length)
return a;
if (1 < first.length) {
first = sort(first);
}
if (1 < last.length) {
last = sort(last);
}
for (int x = 0; x < b; x++) {
fina[x] += first[x];
}
for (int x = 0; x < d; x++) {
fina[x + b] = mid[x];
}
for (int x = 0; x < c; x++) {
fina[x + b + d] = last[x];
}
return fina;
}