Number of Swappings/DataMovement in QuickSort Using Recursion - java

I can't seem to get how to find the number of dataMovements/Swappings in this code. Will there even be swappings/dataMovements in this Recursion Code ? 0_o and
what would be it's memory space requirement ?
package skirmish;
public class QuickSort
{
public static int countComparisons = 0;
public static int countSwappings = 0;
public LinkedList qSort(LinkedList l)
{
if(l.count() <= 1)
return l;
int p = l.peekStart();
l.removeFromStart();
LinkedList s = new LinkedList();
LinkedList g = new LinkedList();
while(!l.isEmpty())
{
countComparisons++;
if(l.peekStart() < p)
s.addAtEnd(l.peekStart());
else
g.addAtEnd(l.peekStart());
l.removeFromStart();
}
s = qSort(s);
g = qSort(g);
s.addAtEnd(p);
countSwappings++;
while(!g.isEmpty())
{
s.addAtEnd(g.peekStart());
g.removeFromStart();
countSwappings++;
}
return s;
}
}

Related

Brute Force out of memory space

I'm busy creating a brute force TSP algorithm, the program currently works and calculates the shortest possible route I input. Sadly the maximum amount of nodes I can use is 10, this is because whenever I go higher I get: "Java.lang.OutofMemoryError: Java heap space". I've already been trying to optimize the code but the result has been negligible. How can I further optimize my code so I can use more nodes while running my algorithm?
This is my code:
import com.sybrand.TSP.*;
import java.util.*;
public class BruteForce extends TSP_Algorithm {
private ArrayList<Coordinate> sortedCoords = new ArrayList<>();
ArrayList<Coordinate> coords = new ArrayList<>();
ArrayList<Coordinate> shortestRoute;
public BruteForce(ArrayList<Coordinate> coords) {
sortedCoords.addAll(coords);
permutation(sortedCoords);
}
public void permutation(ArrayList<Coordinate> nums) {
List<List<Coordinate>> accum = new ArrayList<>();
permutation(accum, Collections.emptyList(), nums);
float shortestDistance = 0.0f;
for (List<Coordinate> routeOption: accum) {
Path calcDistance = new Path((ArrayList<Coordinate>) routeOption);
if (shortestDistance == 0.0f || calcDistance.getDistance() < shortestDistance) {
shortestDistance = calcDistance.getDistance();
this.shortestRoute = (ArrayList<Coordinate>) routeOption;
}
}
}
private static void permutation(List<List<Coordinate>> accum, List<Coordinate> prefix, List<Coordinate> nums) {
int n = nums.size();
if (n == 0) {
accum.add(prefix);
} else {
for (int i = 0; i < n; ++i) {
List<Coordinate> newPrefix = new ArrayList<>(prefix);
newPrefix.add(nums.get(i));
List<Coordinate> numsLeft = new ArrayList<>(nums);
numsLeft.remove(i);
permutation(accum, newPrefix, numsLeft);
}
}
}
public ArrayList<Coordinate> getSortedCoordinates() {
return shortestRoute;
}
}

How to overcome this stack overflow issue when finding SCCs?

This is the code I wrote to find SCCs usigng Kosaraju's Two-Passed Algorithm. When I run the main method, I get a StackOverFlowError on SCC.revDFS. How can I avoid the stack overflow error when having a large amount of recursive calls?
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import java.util.Scanner;
public class SCC {
int n = 875714;
Map<Integer,List<Integer>> adjList;
Map<Integer,List<Integer>> adjListRev;
int[] ft;
int t;
int s;
boolean[] marked;
int[] leaders;
public SCC() {
init();
t = 0;
s = 0;
marked = new boolean[n + 1];
leaders = new int[n + 1];
}
void init() {
adjList = new HashMap<Integer,List<Integer>>();
adjListRev = new HashMap<Integer,List<Integer>>();
ft = new int[n + 1];
List<Integer> adj;
try {
Scanner scanner = new Scanner (new InputStreamReader(this.getClass().
getClassLoader().getResourceAsStream("SCC.txt")));
while(scanner.hasNextLine()) {
String s = scanner.nextLine().trim();
String[] num = s.split(" ");
if (!adjList.containsKey(Integer.parseInt(num[0]))) {
adjList.put(Integer.parseInt(num[0]), new ArrayList<Integer>());
}
adj = adjList.get(Integer.parseInt(num[0]));
adj.add(Integer.parseInt(num[1]));
adjList.put(Integer.parseInt(num[0]), adj);
if (!adjListRev.containsKey(Integer.parseInt(num[1]))) {
adjListRev.put(Integer.parseInt(num[1]), new ArrayList<Integer>());
}
adj = adjListRev.get(Integer.parseInt(num[1]));
adj.add(Integer.parseInt(num[0]));
adjListRev.put(Integer.parseInt(num[1]), adj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void DFS_Loop() {
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
}
for (int i = n; i > 0; i--) {
if (!marked[i]) {
revDFS(i);
}
}
for (int i = 1; i < n + 1; i++) {
marked[i] = false;
leaders[i] = 0;
}
for (int i = n; i > 0; i--) {
if (!marked[ft[i]]) {
s = ft[i];
DFS(ft[i]);
}
}
}
public void revDFS(int i) {
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
public void DFS(int i) {
marked[i] = true;
leaders[s] += 1;
List<Integer> edges = adjList.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
DFS(j);
}
}
}
}
public static void main(String[] args) {
SCC scc = new SCC();
scc.DFS_Loop();
Arrays.sort(scc.leaders);
for (int i = scc.n; i < scc.n - 5; i--) {
System.out.println(scc.leaders[i]);
}
}
}
Maybe you can try to convert the logic to iterative approach. Also, do check if you have base and edge cases handled properly.
The basic idea for converting a recursive function into an iterative function is that a recursive function consumes arguments from a stack.
So you can create a stack and push the values into it and then consume them in a loop.
public void _revDFS(int _i) {
LinkedList<Integer> stack = new LinkedList<>();
stack.push(_i);
while(!stack.isEmpty()){
int i = stack.pop();
marked[i] = true;
List<Integer> edges = adjListRev.get(i);
if (edges != null) {
for (int j: edges) {
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
}
t += 1;
ft[t] = i;
}
}
I can't really test it to see if I made a mistake of some kind and revDFS is a function with a lot of side effect and it does not return a value, so is a bit difficult to reason with it.
But the gist is that instead of calling the function itself you can just push the edge indexes onto the stack and then consume them.
The child edges will be processed in reverse order so if you want to keep the same order of processing of the original you should read the edges in reverse order :
ListIterator<Integer> li = edges.listIterator(edges.size());
while(li.hasPrevious()){
int j = li.previous();
if (!marked[j]) {
stack.push(j);
//revDFS(j);
}
}
you have implemented your Dfs function recursively which causes "stack overflow". To overcome this issue you need to implement it using stack data structure.
see link bellow for more motivations
https://github.com/sinamalakouti/MyFavoriteAlgorithmProblems

Can't locate the problems in this simple Genetic Algorithm program

I have written a simple genetic algorithm program in java. What it is does is maximize the decimal value represented by the bits in the chromosome. Somehow mutation is not working as expected, e.g. causing two genes to mutate when just one is to change. The print statements I have included there show which to mutate, but in addition to that some more chromosomes get mutated. I can't figure out what the problem is :-(
Here are my java classes.
Gene.java
public class Gene {
private int value;
public Gene() {
value = Math.random() < 0.5 ? 0 : 1;
}
public Gene(int value) {
if (value != 0 && value != 1) {
throw new IllegalArgumentException("value must be either 0 or 1");
}
else {
this.value = value;
}
}
public void mutate() {
value = 1 - value;
}
public int value() {
return value;
}
#Override
public String toString() {
return String.valueOf(value);
}
}
Chromosome.java
import java.util.ArrayList;
import java.util.List;
public class Chromosome implements Comparable {
private ArrayList<Gene> genes;
private final int chromosomeLength;
public Chromosome(int length) {
this.genes = new ArrayList<>();
this.chromosomeLength = length > 0 ? length : 16;
for (int i = 0; i < chromosomeLength; i++) {
this.genes.add(i, new Gene());
}
}
public List<Gene> getAllele(int fromIndex, int toIndex) {
return new ArrayList<>(genes.subList(fromIndex, toIndex));
}
public void setAllele(int fromIndex, List<Gene> allele) {
int lastIndex = fromIndex + allele.size();
if (lastIndex > chromosomeLength) {
throw new IndexOutOfBoundsException("the allele exceeds beyond the size of the chromosome");
}
for (int i = fromIndex, j = 0; i < lastIndex; i++, j++) {
genes.set(i, allele.get(j));
}
}
public int getChromosomeLength() {
return chromosomeLength;
}
public void setGeneAt(int index, Gene gene) {
genes.set(index, gene);
}
public Gene getGeneAt(int index) {
return genes.get(index);
}
public int value() {
return Integer.parseInt(this.toString(), 2);
}
#Override
public String toString() {
StringBuilder chromosome = new StringBuilder("");
genes.stream().forEach((Gene g) -> chromosome.append(g));
return chromosome.toString();
}
#Override
public int compareTo(Object anotherChromosome) {
Chromosome c = (Chromosome) anotherChromosome;
return this.value() - c.value();
}
}
GenePool.java
import java.util.ArrayList;
import java.util.Arrays;
public class GenePool {
private final ArrayList<Chromosome> genePool;
private final int genePoolSize;
private final int chromosomeLength;
private final double crossOverRate;
private final double mutationRate;
private int[] crossPoints;
public GenePool(int numOfChromosome, int chromosomeLength, double crossOverRate, double mutationRate) {
this.genePoolSize = numOfChromosome;
this.chromosomeLength = chromosomeLength > 0 ? chromosomeLength : 16;
this.crossOverRate = crossOverRate;
this.mutationRate = mutationRate;
crossPoints = new int[1];
crossPoints[0] = this.chromosomeLength / 2;
genePool = new ArrayList<>();
for (int i = 0; i < numOfChromosome; i++) {
genePool.add(new Chromosome(chromosomeLength));
}
}
public int getGenePoolSize() {
return genePoolSize;
}
public Chromosome getChromosomeAt(int index) {
return genePool.get(index);
}
public void setChromosomeAt(int index, Chromosome c) {
genePool.set(index, c);
}
public int getChromosomeLength() {
return chromosomeLength;
}
public Chromosome[] crossOver(Chromosome c1, Chromosome c2) {
Chromosome[] offsprings = new Chromosome[2];
offsprings[0] = new Chromosome(c1.getChromosomeLength());
offsprings[1] = new Chromosome(c1.getChromosomeLength());
Chromosome[] parentChromosomes = {c1, c2};
int selector = 0;
for (int i = 0, start = 0; i <= crossPoints.length; i++) {
int crossPoint = i == crossPoints.length ? c1.getChromosomeLength() : crossPoints[i];
offsprings[0].setAllele(start, parentChromosomes[selector].getAllele(start, crossPoint));
offsprings[1].setAllele(start, parentChromosomes[1 - selector].getAllele(start, crossPoint));
selector = 1 - selector;
start = crossPoint;
}
return offsprings;
}
public void mutateGenePool() {
int totalGeneCount = genePoolSize * chromosomeLength;
System.out.println("Mutating genes:");
for (int i = 0; i < totalGeneCount; i++) {
double prob = Math.random();
if (prob < mutationRate) {
System.out.printf("Chromosome#: %d\tGene#: %d\n", i / chromosomeLength, i % chromosomeLength);
genePool.get(i / chromosomeLength).getGeneAt(i % chromosomeLength).mutate();
}
}
System.out.println("");
}
public int getLeastFitIndex() {
int index = 0;
int min = genePool.get(index).value();
int currentValue;
for (int i = 1; i < genePoolSize; i++) {
currentValue = genePool.get(i).value();
if (currentValue < min) {
index = i;
min = currentValue;
}
}
return index;
}
public void saveFittest(ArrayList<Chromosome> offsprings) {
// sort in ascending order
offsprings.sort(null);
offsprings.stream().forEach((offspring) -> {
int leastFitIndex = getLeastFitIndex();
if (offspring.value() > genePool.get(leastFitIndex).value()) {
genePool.set(leastFitIndex, offspring);
}
});
}
public void evolve(int noOfGeneration) {
for (int generation = 1; generation <= noOfGeneration; generation++) {
System.out.println("Generation :" + generation);
ArrayList<Integer> selection = new ArrayList<>();
for (int i = 0; i < genePoolSize; i++) {
if (Math.random() <= crossOverRate) {
selection.add(i);
}
}
if (selection.size() % 2 == 1) {
selection.remove(selection.size() - 1);
}
ArrayList<Chromosome> offsprings = new ArrayList<>();
for (int i = 0; i < selection.size(); i += 2) {
int index1 = selection.get(i);
int index2 = selection.get(i + 1);
offsprings.addAll(Arrays.asList(crossOver(genePool.get(index1), genePool.get(index2))));
}
System.out.println("Before saving the offsprings");
displayChromosomes(genePool, "GenePool");
displayChromosomes(offsprings, "Offsprings");
saveFittest(offsprings);
System.out.println("Before mutation:");
displayChromosomes(genePool, "GenePool");
mutateGenePool();
System.out.println("After mutation:");
displayChromosomes(genePool, "GenePool");
System.out.println("\n\n");
}
}
public void displayChromosomes(ArrayList<Chromosome> geneList, String name) {
System.out.println(name);
if (geneList.isEmpty()) {
System.out.println("Empty list");
}
geneList.stream().forEach((c) -> {
System.out.println(c + " -> " + c.value());
});
System.out.println("");
}
}
GADemo.java
public class GADemo {
public static void main(String[] args) {
GenePool gp = new GenePool(6, 8, 0.25, 0.01);
gp.evolve(10);
}
}
After evolving for a number of generations, the chromosomes all tend to become exactly the same, or very similar. And the problem is that that value is not the maximum for that many bits, and sometimes even a small value. For example, for 8 bits the values should (tend to) approach 255, but this doesn't do so in my code. Someone please provide a hint where/how to look for and solve the problem.
Focus on these lines and imagine the references. These are from setAllele()
for (int i = fromIndex, j = 0; i < lastIndex; i++, j++) {
genes.set(i, allele.get(j));
}
You are basically copying the reference from one onto the other. They are the same Gene so whatever mutation you do on those genes, will also affect even other Chromosomes.
You must produce a deep copy here.
Initially each chromosome has an own list of genes. But when you do the crossover operation you set gene objects from one chromosome into the gene list of other chromosome.
When you evolve the system, the number of shared genes will rise and therefore ultimately all chromosomes will share the same genes. No matter how you mutate a gene the chromosomes are not affected.
EDIT:
As Incognito also answered the setAllele method seems to be the culprit where gene sharing starts. You may want to introduce a method in the gene class where you can set its value given another gene.

Null Pointer Exception in LinkedList Hash Table

So I'm creating a hash table with LinkedLists using the multiplication method. As an instance variable I define the LinkedList "T" that I'll be using, and in the constructor of the class I specify the size of T. However, every time I run my Driver testing class, I get NullPointerExceptions on everything I try to reference anything in T[]. Am I overlooking something? I've spent over an hour trying to figure it out.
ChainedHashTable class:
public class ChainedHashTable
{
private LinkedList<Integer>[] T;
private int m;
private double A;
public ChainedHashTable(int n)
{
for (m = 1; m < n; m *= 2);
T = new LinkedList[m];
Random random = new Random();
int s = random.nextInt(Integer.MAX_VALUE);
A = (s * 1.00) / Integer.MAX_VALUE;
}
public void insert(Integer key)
{
T[hash(key)].add(Integer.valueOf(key));
}
public void delete(int key)
{
T[hash(key)].remove(Integer.valueOf(key));
}
public Integer search(int key)
{
int n = T[hash(key)].indexOf(key);
if (n == -1)
return -1;
else
return T[hash(key)].get(n);
}
private int hash(int key)
{
System.out.println((int)(m * ((key * A) % 1)));
return (int)(m * ((key * A) % 1));
}
public void printTable()
{
for (int i = 0; i < T.length; i++)
{
System.out.println("index: " + i + " " + T[i]);
}
}
}
Driver class:
public class Driver
{
public static void main(String[] args)
{
ChainedHashTable test1 = new ChainedHashTable(20);
test1.printTable();
test1.insert(4);
test1.insert(54);
test1.insert(6);
test1.insert(3);
test1.insert(26);
test1.insert(54);
test1.insert(11);
test1.insert(10);
test1.insert(76);
test1.insert(42);
test1.insert(41);
test1.insert(32);
test1.insert(87);
test1.insert(76);
test1.insert(72);
test1.insert(57);
test1.insert(29);
test1.insert(16);
test1.insert(92);
test1.insert(64);
test1.printTable();
}
}
You are creating an array of references to type LinkedList and setting them to their initial state, which is null.
T = new LinkedList[m];
T now is an array of the computed size m. You need to initialize the objects inside of the array.
T = new LinkedList[m];
for (int i = 0; i < m; i++) {
T[i] = new LinkedList<>();
}

Collections.sort compile error - incompatible types

I have been developing an implementation of the neighbourhood algorithm in Java for a physics project I am working on. I'm brand new to Java so I apologize for any idiocy that results.
I have been getting the error
''
incompatible types
found : void
required: java.util.List<VoronoiPoint>
'' on line 22 from the Java compiler in attempting to compile the program shown below. I cannot figure out why the variable ''thelist'' somehow turns into a void when I declared it to be of type List<VoronoiPoint>. If anybody can explain to me what is going on it would be much appreciated!
import java.lang.Double;
import java.util.*;
public class VoronoiTiling
{
public static void main(String args[])
{
Integer n = 10; //Number of dimensions of model parameter space
Integer ns = 20; //Number of points per iteration
Integer nr = 4; //Number of cells to populate
Integer iterations = 5; //Number of iterations
List<VoronoiPoint> thelist = VoronoiList.startlist(ns,n);
//System.out.println(thelist);
//System.out.println(thelist.get(1).misfit);
for (Integer i=0 ; i<thelist.size() ; i++)
{
thelist.get(i).setmisfit();
}
List<VoronoiPoint> orderedlist = Collections.sort(thelist);
Double distance = EuclidianDistance((thelist.get(1)).location,(thelist.get(2)).location);
System.out.println(distance);
}
public static Double EuclidianDistance(Double[] point1, Double[] point2)
{
Double distance=0.0;
for (int i = 0; i < point1.length; i++)
{
distance = distance + Math.pow((point1[i]-point2[i]),2);
}
return Math.sqrt(distance);
}
}
The other classes I used are here:
The VoronoiList class:
import java.util.*;
public class VoronoiList
{
public static List<VoronoiPoint> startlist(Integer ns, Integer n)
{
List<VoronoiPoint> thestartlist = new ArrayList<VoronoiPoint>();
for (int i = 0; i < ns; i++)
{
thestartlist.add(new VoronoiPoint(0.,n));
}
return thestartlist;
}
}
The VoronoiPoint class:
import java.util.Random;
public class VoronoiPoint implements Comparable<VoronoiPoint>
{
Double[] location;
private Random generator = new Random();
Double misfit = -1.;
//***************************************************************
public VoronoiPoint(Double misfit, Integer n)
{
location = new Double[n];
ParameterBoundaries boundaries = new ParameterBoundaries(n);
for(int i = 0; i < n; i++)
{
location[i] = boundaries.getboundaries(2*i)+2*generator.nextDouble();
}
}
//***************************************************************
//public Double[] getlocation()
//{
//return location;
//}
public void setlocationi(Integer i, Double j)
{
location[i] = j;
}
//***************************************************************
public void setmisfit()
{
Integer n = location.length;
Double tempmisfit = 0.0;
for(Integer i = 0; i < n; i++)
{
tempmisfit = tempmisfit + Math.pow((location[i]),2);
}
misfit = Math.sqrt(tempmisfit); // Temporarily just distance to centre
}
//public Double getmisfit()
//{
//return misfit;
//}
public int compareTo(VoronoiPoint b)
{
if (this.misfit<b.misfit) return -1;
else if (this.misfit==b.misfit) return 0;
return 1;
}
}
And the parameter boundaries class:
public class ParameterBoundaries
{
private Double[] boundaries; /*Set to 2n where n is dimensions of parameter space,
* it just makes it easier*/
public ParameterBoundaries(Integer n)
{
boundaries = new Double[2*n];
for(Integer i = 0; i<n; i++)
{
boundaries[2*i] = -1.0;
boundaries[2*i+1] = 1.0;
}
}
public Double getboundaries(Integer i)
{
return boundaries[i];
}
}
Collections.sort(..) sorts the original list. It doesn't return a new list. (Its return type is void)
Your code is wrong. Collections.sort() is an in-place sort function; it modifies the given list argument and returns nothing (void).

Categories

Resources