How to acces Matrix as an object - java

I have an object calld Matice. Matice is a matrix nxn filled with random numbers in a set range. I want to perform some operations on my objects like adding, multiplying, inversion, etc. How can i do that? If i try something like m1[i][j] * m2[j][i].
but i get error message.
public class Main {
public static void main(String[] args) {
Matice m1 = new Matice(3);
m1.matrixFill(0, 5);
m1.matrixPrint();
//m1.matrixAdd(m2);
}
}
public class Matice {
int[][] matice;
private int n;
public Matice(int n) {
this.n = n;
if(n > 0) {
matice = new int[n][n];
}
}
public void matrixPrint(){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
System.out.format("%5d", matice[i][j]);
}
System.out.println("");
}
System.out.println("");
}
public void matrixFill(int a, int b){
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matice[i][j] = (int) (Math.random() * (a + b + 1) - a);
}
}
}
public void matrixAdd(Matice m1, Matice m2){
int[][] resultMatrix = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
resultMatrix[i][j] = m1[i][j] + m2[i][j];
}
}
}
}

You are referring to the object itself not the array that is the field of object.
Try this:
resultMatrix[i][j] = m1.matice[i][j] + m2.matice[i][j];
instead of
resultMatrix[i][j] = m1[i][j] + m2[i][j];
btw. I recommend to mark matrixAdd to static because it is a stateless, helper method or extract into a different class.

You already started the right way: by adding the operations as methods to your Matice class. Unlike C++, you can not define operators for your class. You'll have to stick with ordinary methods.
Your methods should use the Matice they are called on as one argument. Thus use something like add(Matice other) Next you'll have to decide if you methods modify the Matice they are called on, or if they return a copy of the data.
Last but not least, if this isn't a toy/exercise project, I'd check out existing libraries: Java matrix libraries

Related

How to protect arrays from changing?

I'm trying to get data from arrays that were used in method fifo and lifo. I have main array that fills from input by user. These array is used in methods fifo and lifo, the problem is that these two functions giving the same priceOfGoods, because while fifo using main array in process it changing data inside it. I want to prevent changing data in ```main array** and use it in two methods without changing data inside main array. Any ideas? Thanks!
public class Solution {
public static int[][] takingGoodsAndPrice(Scanner input, Integer m) {
final int[][] goodsAndPrice = new int[m][2];
// Taking goods and its price
for (int i = 0; i < m; i++) {
for (int j = 0; j < 2; j++) {
goodsAndPrice[i][j] = Integer.parseInt(input.next());
}
}
return goodsAndPrice;
}
public static int[] takingAmountOfSales(Scanner input, Integer k) {
final int[] amountOfSales = new int[k];
// Taking sale of goods
for (int i = 0; i < k; i++) {
amountOfSales[i] = Integer.parseInt(input.next());
}
return amountOfSales;
}
public static Integer fifo(Integer k, Integer m, int[][] goodsAndPrice, int[] amountOfSales) {
int priceOfRestGoods = 0;
int[][] goods = goodsAndPrice;
int[] amount = amountOfSales;
// Evaluates amount of goods that were not sold
for (int i = 0; i < k; i++) {
for (int j = 0; j < m; j++) {
if (amount[i] == 0)
break;
if (goods[j][0] > amount[i]) {
goods[j][0] = goods[j][0] - amount[i];
amount[i] = amount[i] - amount[i];
} else if (goods[j][0] <= amount[i]) {
amount[i] = amount[i] - goods[j][0];
goods[j][0] = 0;
}
}
}
// Evaluates price of goods that were not sold
for (int i = 0; i < m; i++) {
priceOfRestGoods = priceOfRestGoods + (goods[i][0] * goods[i][1]);
}
return priceOfRestGoods;
}
public static Integer lifo(Integer k, Integer m, int[][] goodsAndPrice, int[] amountOfSales) {
int priceOfRestGoods = 0;
// Evaluates amount of goods that were not sold
for (int i = 0; i < k; i++) {
for (int j = m-1; j >= 0; j--) {
if (amountOfSales[i] == 0)
break;
if (goodsAndPrice[j][0] > amountOfSales[i]) {
goodsAndPrice[j][0] = goodsAndPrice[j][0] - amountOfSales[i];
amountOfSales[i] = amountOfSales[i] - amountOfSales[i];
} else if (goodsAndPrice[j][0] <= amountOfSales[i]) {
amountOfSales[i] = amountOfSales[i] - goodsAndPrice[j][0];
goodsAndPrice[j][0] = 0;
}
}
}
// Evaluates price of goods that were not sold
for (int i = 0; i < m; i++) {
priceOfRestGoods = priceOfRestGoods + (goodsAndPrice[i][0] * goodsAndPrice[i][1]);
}
return priceOfRestGoods;
}
//
// public static Integer medium() {
//
// }
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int n = input.nextInt(); // n - total amount of goods
final int m = input.nextInt(); // m - total amount of goods that has been received
final int k = input.nextInt(); // k - total amount of goods that has been released
final int[][] goodsAndPrice = takingGoodsAndPrice(input, m);
final int[] amountOfSales = takingAmountOfSales(input, k);
System.out.println(fifo(k, m, goodsAndPrice, amountOfSales));
System.out.println(lifo(k, m, goodsAndPrice, amountOfSales));
}
}
At the moment, you're creating new variables to store the arrays, but they will reference the same array done like this, meaning that any changes made to them will also be present in the original parameters. You'll want to store a copy of the arrays in those variables instead. See here.
When you do the following
int[][] goods = goodsAndPrice;
you are still referencing the values referenced by goodsAndPrice i.e. both goods and goodsAndPrice will reference the same values. Therefore, any changes made using one of these references will be same for the other reference.
What you need to do is to create a copy of goodsAndPrice[][] and make changes to the copy. You can do create a copy of goodsAndPrice[][] as follows:
int[][] goods = Arrays.stream(goodsAndPrice).map(int[]::clone).toArray(int[][]::new);

Checking to see if two 2D boolean arrays are equal at a given interval: Java

I have two 2d boolean arrays, the smaller array (shape) is going over the larger array (world).
I am having trouble to find a method to find out when the smaller array can "fit" into the larger one.
When I run the code it either just goes through the larger array, never stopping, or stops after one step (incorrectly).
public void solve() {
ArrayList<Boolean> worldList=new ArrayList<>();
ArrayList<Boolean> shapeList=new ArrayList<>();
for (int i = 0; i < world.length; i++) {
for (int k = 0; k < world[i].length; k++) {
worldList.add(world[i][k]);
display(i, k, Orientation.ROTATE_NONE);
for (int j = 0; j < shape.length; j++) {
for (int l = 0; l < shape[j].length; l++) {
shapeList.add(shape[j][l]);
if(shapeList.equals(worldList)) {
return;
}
}
}
}
}
}
A good place to start with a problem like this is brute force for the simplest case. So, for each index in the world list, just check to see if every following index of world and shapes match.
Notice we only iterate to world.size()-shapes.size(), because naturally if shapes is longer than the portion of world we haven't checked, it won't fit.
import java.util.ArrayList;
public class Test {
ArrayList<Boolean> world = new ArrayList<>();
ArrayList<Boolean> shapes = new ArrayList<>();
public static void main(String[] args) {
new Work();
}
public Test() {
world.add(true);
world.add(false);
world.add(false);
world.add(true);
shapes.add(false);
shapes.add(true);
// Arraylists initialized to these values:
// world: T F F T
// shapes: F T
System.out.println(getFitIndex());
}
/**
* Get the index of the fit, -1 if it won't fit.
* #return
*/
public int getFitIndex() {
for (int w = 0; w <= world.size()-shapes.size(); w++) {
boolean fits = true;
for (int s = 0; s < shapes.size(); s++) {
System.out.println("Compare shapes[" + s + "] and world["+ (w+s) + "]: " +
shapes.get(s).equals(world.get(w+s)));
if (!shapes.get(s).equals(world.get(w+s))) fits = false;
}
System.out.println();
if (fits) return w;
}
return -1;
}
}
When we run this code, we get a value of 2 printed to the console, since shapes does indeed fit inside world, starting at world[2].
You can find the row and column of fitting like this
public void fit() {
int h = world.length - shape.length;
int w = world[0].length - shape[0].length;
for (int i = 0; i <= h; i++) {
for (int k = 0; k <= w; k++) {
boolean found = true;
for (int j = 0; j < shape.length && found; j++) {
for (int l = 0; l < shape[j].length && found; l++) {
if (shape[j][l] != world[i + j][k + l])
found = false;
}
}
if (found) {
//Your shape list fit the world list at starting index (i, k)
//You can for example save the i, k variable in instance variable
//Or return then as an object for further use
return;
}
}
}

Need help pinpointing issue in Genetic Algorithm Single-Point Crossover Mechanism in Java

I have been implementing a simple genetic algorithm(GA) using Java. The steps of my GA are basically binary encoding, tournament selection, single-point crossover, and bit-wise mutation. Each individual of the population is represented by a class consisting of binary genes and a fitness value.
public class Individual {
int gene[];
int fitness;
public Individual(int n){
this.gene = new int[n];
}
}
The codes below does not include the bit-wise mutation part as I have been facing problem at the single-point crossover part of the GA. The way I have implemented the single-point crossover algorithm is by randomly finding a point for two consecutive Individual array elements and then swap their tails. The tail swapping is then repeated for each pair of Individual. I have also created the printGenome() method to print out all the arrays to compare, the resulting array after the crossover process is not properly swapped. I have tested my single-point crossover algorithm separately, it works. However when I tried to run it here in the codes below, the crossover simply does not work. May I know is it because there is something wrong within the Tournament Selection algorithm? Or is it something else(silly mistakes)? I have been reworking on it and still I could not pinpoint the error.
I would be grateful for any help and information provided! :)
public class GeneticAlgorithm {
public static void main(String[] args) {
int p = 10;
int n = 10;
Individual population[];
//create new population
population = new Individual[p];
for (int i = 0; i < p; i++) {
population[i] = new Individual(n);
}
//fills individual's gene with binary randomly
for (int i = 0; i < p; i++) {
for (int j = 0; j < n; j++) {
population[i].gene[j] = (Math.random() < 0.5) ? 0 : 1;
}
population[i].fitness = 0;
}
//evaluate each individual
for (int i = 0; i < p; i++) {
for (int j = 0; j < n; j++) {
if (population[i].gene[j] == 1) {
population[i].fitness++;
}
}
}
//total fitness check
System.out.println("Total fitness check #1 before tournament selection: " + getTotalFitness(population, p));
System.out.println("Mean fitness check #1 before tournament selection: " + getMeanFitness(population, p));
System.out.println("");
//tournament selection
Individual offspring[] = new Individual[p];
for (int i = 0; i < p; i++) {
offspring[i] = new Individual(n);
}
int parent1, parent2;
Random rand = new Random();
for (int i = 0; i < p; i++) {
parent1 = rand.nextInt(p); //randomly choose parent
parent2 = rand.nextInt(p); //randomly choose parent
if (population[parent1].fitness >= population[parent2].fitness) {
offspring[i] = population[parent1];
} else {
offspring[i] = population[parent2];
}
}
//total fitness check
System.out.println("Total fitness check #2 after tournament selection: " + getTotalFitness(offspring, p));
System.out.println("Mean fitness check #2 after tournament selection: " + getMeanFitness(offspring, p));
System.out.println("");
//genome check
System.out.println("Before Crossover: ");
printGenome(offspring, p, n);
//crossover
for (int i = 0; i < p; i = i + 2) {
int splitPoint = rand.nextInt(n);
for (int j = splitPoint; j < n; j++) {
int temp = offspring[i].gene[j];
offspring[i].gene[j] = offspring[i + 1].gene[j];
offspring[i + 1].gene[j] = temp;
}
}
//genome check
System.out.println("After Crossover:");
printGenome(offspring, p, n);
//evaluate each individual by counting the number of 1s after crossover
for (int i = 0; i < p; i++) {
offspring[i].fitness = 0;
for (int j = 0; j < n; j++) {
if (offspring[i].gene[j] == 1) {
offspring[i].fitness++;
}
}
}
//total fitness check
System.out.println("Total fitness check #3 after crossover: " + getTotalFitness(offspring, p));
System.out.println("Mean fitness check #3 after crossover: " + getMeanFitness(offspring, p));
}
public static void printGenome(Individual pop[], int p, int n) {
for (int i = 0; i < p; i++) {
for (int j = 0; j < n; j++) {
System.out.print(pop[i].gene[j]);
}
System.out.println("");
}
}
public static int getTotalFitness(Individual pop[], int p) {
int totalFitness = 0;
for (int i = 0; i < p; i++) {
totalFitness = totalFitness + pop[i].fitness;
}
return totalFitness;
}
public static double getMeanFitness(Individual pop[], int p) {
double meanFitness = getTotalFitness(pop, p) / (double) p;
return meanFitness;
}
}
The problem is that, in your selection you are (most likely) duplicating individuals, when you say:
offspring[i] = population[parent1]
You are actually storing a reference to population[parent1] in offspring[i]. As a result your offspring array can contain the same reference multiple times, hence the same object will participate in crossover multiple times with multiple partners.
As a solution, you can store a clone instead of a reference to the same object. In Individual add:
public Individual clone(){
Individual clone = new Individual(gene.length);
clone.gene = gene.clone();
return clone;
}
And in your selection (note the added .clone()):
for (int i = 0; i < p; i++) {
parent1 = rand.nextInt(p); //randomly choose parent
parent2 = rand.nextInt(p); //randomly choose parent
if (population[parent1].fitness >= population[parent2].fitness) {
offspring[i] = population[parent1].clone();
} else {
offspring[i] = population[parent2].clone();
}
}
This way every element in offspring is a different object, even if the genome is the same.
That solves the Java part. Regarding the GA theory I hope some things, for instance your fitness measure are just placeholders, right?

Conway's Game of Life Rules Java

I am making the Conway's Game of Life like almost every other beginner. The main problem I have is I have no clue how to implement the rules for the game, which are :a dead cell with exactly three live neighbors becomes alive, a live cell with exactly one live neighbor becomes dead, and a live cell with more than three live neighbors becomes dead. I've never manipulated a matrix before so I do not have any idea where to start. The class I'm in does not allow us to use non-static methods yet, and also we cannot use the java libraries. This is currently what I have:
public class Life {
public static boolean[][] origin(int a) {
boolean[][] randomMatrix = new boolean [a][a];
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
randomMatrix[i][j] = StdRandom.bernoulli();
}
}
return randomMatrix;
}
public static void print(boolean[][] a) {
int N = a.length;
StdOut.println(N);
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (a[i][j]) StdOut.print("1 ");
else StdOut.print("0 ");
}
StdOut.println();
}
}
public static void show(boolean[][] a, boolean which) {
int N = a.length;
StdDraw.setXscale(0, N-1);
StdDraw.setYscale(0, N-1);
double r = .5;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (a[i][j] == which) {
StdDraw.filledSquare(j, N-i-1, r);
}
}
}
}
public static void main(String[] args) {
int a = 5;
boolean[][] b = origin(a);
int gens = 3;
for (int i = 0; i < gens; i++) {
System.out.println("Generation " + i + ":");
print(b);
show(b, true);
}
}
}
The output I'm receiving right now is what I need for the initial generation of the game. I think I need a new array to store the new generations, and maybe some if and else statements to check if the cells are alive or dead. Any help is appreciated.
HINTS
Recently I completed this example. So the right structure is:
Required 2 dimension arrays ("current" & "next")
Initialize "current" with random values
print "current"
Copy & Calculate each cell of the next generation in array "next"
After calculation, update the "current" array. Use function to update each cell
Set "current" with "next" generation values
Print "current" and go to step 4
Warning!!
Use different formula to check the cells that are on the edges.

Why does this code in java print a reference instead the result of invoking the method?

I am supposed to write a method that accepts 3 2-D arrays of This method should determine whether one of the matrices is the result of matrix addition of the other two.
public class Matrix {
public static void main(String[]args){
int [][] a = {{5,2,3},{4,1,6},{0,7,2}};
int [][] b = {{1,2,3},{4,5,6},{0,1,2}};
int [][] t = {{6,4,6},{8,6,12},{0,8,4}};
System.out.println(add(a,b));
System.out.println(check(a,b,t));
}
public static int [][] add(int[][]a,int[][]b){
int i=0;
int j=0;
int[][] r = new int [3][3];
while (i<a.length){
r[i][j] = a[i][j] + b[i][j];
i++;
j++;
}
return r;
}
public static boolean check(int[][]a,int[][]b,int[][]t){
int i = 0;
int j = 0;
while(i<t.length){
if(t==add(a,b))
return true;
}
return false;
}
}
add returns an array. Arrays in Java are objects, but they do not override the toString() method. When printing, you'd print their default toString() call, which is implemented by Object as return getClass().getName() + "#" + Integer.toHexString(hashCode());.
Luckily, Java provides a utility in the form of java.util.Arrays.deepToString(Ojbect[]) to generate a more readable string output:
System.out.println(Arrays.deepToString(add(a,b)));
EDIT:
Your add method is also wrong. Your code iterates i and j together, so it only sums the elements along the matrix's diagonal instead of adding all of them. You should use a nested loop instead:
public static int [][] add(int[][]a, int[][]b) {
int[][] r = new int [3][3];
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
r[i][j] = a[i][j] + b[i][j];
}
}
return r;
}
Your check method, by the way, is also wrong - it attempts to compare the array itself instead of is elements:
public static boolean check(int[][]a, int[][]b, int[][]t) {
int[][] r = add(a, b);
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
if (r[i][j] != t[i][j]) {
return false;
}
}
}
return true;
}

Categories