Down in the second class named paintthis, in the constructor i declare that array = array.clone, and it says that there is nothing in the array? I declare the array in LineGraph and then put the array into the peramiters, which there is a constructor of the second class names painthis with the arguments int[] array.
package javatestframming;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class LineGraph extends JFrame{
public LineGraph(){
super("Line Graph");
int[] array = {1, 2, 3, 4, 5, 7, 8, 9};
setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
paintthis gpane = new paintthis(array);
add(gpane);
setVisible(true);
}
public static void main(String[] args){
LineGraph lg = new LineGraph();
}
}
class paintthis extends JPanel{
int[] xpoints;
paintthis(int[] array){
xpoints = array.clone;
}
int max = arrayGetMaxInt(xpoints);
int min = arrayGetMinInt(xpoints);
int divisable = findDivisableWholeNumber(max, min);
Font f = new Font("Arial", Font.BOLD, 14);
FontMetrics fm = getFontMetrics(f);
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
super.paintComponents(g);
int graphHeight = 200;
int graphWidth = 200;
int graphX = 10;
int graphY = 10;
float borderThickness = 5.0f;
//set graph background and border
g2d.setColor(Color.white);
g2d.fillRect(graphX, graphY, graphWidth, graphHeight);
g2d.setColor(Color.GRAY);
BasicStroke bs = new BasicStroke(borderThickness, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g2d.setStroke(bs);
g2d.drawLine(graphX - (int)borderThickness, graphY, graphX + graphWidth, graphY);
g2d.drawLine(graphX - (int)borderThickness, graphY + graphHeight, graphX + graphWidth, graphY + graphHeight);
g2d.drawLine(graphX - (int)borderThickness, graphY, graphX - (int)borderThickness, graphY + graphHeight);
g2d.drawLine(graphX + graphWidth, graphY, graphX + graphWidth, graphY + graphHeight);
int trueGraphWidth = graphWidth - drawYAxis(g2d, graphWidth, graphHeight, max, min, divisable, graphY, graphX);
int trueGraphHeight = graphHeight - drawXAxis(g2d, graphY + graphHeight - fm.getHeight(), graphX, graphWidth, (int)borderThickness);
System.out.println(trueGraphWidth + " " + graphWidth);
drawPoints(g2d, trueGraphWidth, trueGraphHeight, (graphWidth - trueGraphWidth) + (int)borderThickness + graphX, (graphHeight - trueGraphHeight) + (int)borderThickness + graphY);
}
public int drawYAxis(Graphics2D g, int graphWidth, int graphHeight, int max, int min, int counts, int beginingpoint, int overx){
graphHeight -= fm.getHeight();
int averageSpaceInBetween = ((graphHeight-fm.getHeight())/((max - min)/counts)); //- ((fm.getHeight()/(graphHeight/fm.getHeight())));
int space = 0;
Stack<Integer> stackAxisNumbers = new Stack<Integer>();
g.setFont(f);
for (int x = 0; x <= (max - min); x+=counts){
stackAxisNumbers.add(x + min);
}
for (int x = 0; x <= (max - min); x+= counts){
g.drawString("$" + Integer.toString(stackAxisNumbers.pop()), overx, space + beginingpoint + fm.getHeight());
space += averageSpaceInBetween;
}
space = 0;
return fm.stringWidth("$" + Integer.toString(max));
}
public int drawXAxis(Graphics2D g, int beginingpoint, int overx, int graphWidth, int borderThickness){
g.drawLine(overx - borderThickness, beginingpoint, overx + graphWidth, beginingpoint);
return beginingpoint - fm.getHeight();
}
public void drawPoints(Graphics2D g, int graphWidth,int graphHeight, int startX, int startY){
g.setColor(Color.blue);
int xSpace = (int) graphWidth/xpoints.length;
g.drawLine(startX, startY, xSpace + startX, xpoints[0]);
}
public int arrayGetMaxInt(int[] array){
int max = 0;
for (int x: array){
if (x > max){
max = x;
}
}
return max;
}
public int arrayGetMinInt(int[] array){
int min = max;
for (int x: array){
if (x < min){
min = x;
}
}
return min;
}
public int power(int base, int exp){
int num = base;
for (int x = 1; x < exp; x++){
num = num * base;
}
if (exp == 0){
num = 1;
}
return num;
}
public int findDivisableWholeNumber(int max, int min){
boolean passed = false;
int range = max - min;
int divis = 1;
int multiplier = 1;
out:
for (int x = 5; x > 0; x--){
if (range >= power(10, x)){
multiplier = x;
break;
}
}
out:
for (int x = 10 * multiplier; x <= 10 * multiplier && x > 0; x--){
if(range%((int)(range/x)) == 0){
divis = x;
passed = true;
break;
}
}
if (passed == false){
out:
for (int x = 11 * multiplier; x <= (int)(range / 2); x++){
if(range%((int)(range/x)) == 0){
divis = x;
passed = true;
break;
}
}
}
if (passed == false){
System.out.println("ERROR -- NoWholeDiviableNumbersException");
System.exit(0);
}
return divis;
}
}
Exception is:
Exception in thread "main" java.lang.NullPointerException
at javatestframming.paintthis.arrayGetMaxInt(LineGraph.java:97)
at javatestframming.paintthis.<init>(LineGraph.java:31)
at javatestframming.LineGraph.<init>(LineGraph.java:15)
at javatestframming.LineGraph.main(LineGraph.java:22)
C:\Users\Morgan Higginbotham\AppData\Local\NetBeans\Cache\8.1\executor- snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 1 second)
When you create an object using paintthis gpane = new paintthis(array); It will initialize class level variables first
int max = arrayGetMaxInt(xpoints);
then body of constructor is called. In this case xpoints is still not initialized, so you are getting NullPointerException
You can try some thing like this
class paintthis extends JPanel{
int[] xpoints;
int max;
int min;
int divisable;
public paintthis(int[] array){
xpoints = array.clone();
max = arrayGetMaxInt(xpoints);
min = arrayGetMinInt(xpoints);
divisable = findDivisableWholeNumber(max, min);
}
Related
I need help to debug my code for the following challenge - https://www.hackerrank.com/challenges/maximizing-mission-points/problem
I've followed the lines of code from - https://www.geeksforgeeks.org/segment-tree-set-1-sum-of-given-range/.
My code is as below :
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
class SegmentTreeRMQ {
int st[][];
int minVal(int x, int y) {
return (x < y) ? x : y;
}
int getMid(int s, int e) {
return s + (e - s) / 2;
}
int RMQUtil(int sx1, int sy1, int sx2, int sy2, int x1, int y1, int x2, int y2, int index1, int index2)
{
// If segment of this node is a part of given range, then
// return the min of the segment
if (x1 <= sx1 && y1 <= sy1 && x2 >= sx2 && y2 >= sy2)
return st[index1][index2];
// If segment of this node is outside the given range
if ((sx1 < x1 && sy1 < y1) || (sx2 > x2 && sy2 > y2))
return Integer.MIN_VALUE;
// If a part of this segment overlaps with the given range
int midx = getMid(sx1, sx2);
int midy = getMid(sy1, sy2);
return minVal(RMQUtil(sx1, sy1, midx, midy, x1, y1, x2, y2, 2 * index1 + 1, 2 * index2 + 1),
RMQUtil(midx + 1, midy + 1, sx2, sy2, x1, y1, x2, y2, 2 * index1 + 2, 2 * index2 + 2));
}
int RMQ(int n, int m, int x1, int y1, int x2, int y2)
{
// Check for erroneous input values
/*if (x1< 0 || x2 > n - 1 || x1 > x2) {
System.out.println("Invalid Input "+x1+" "+x2);
return -1;
}
if (y1< 0 || y2 > m - 1 || y1 > y2) {
System.out.println("Invalid Input");
return -1;
}*/
return RMQUtil(0, 0, n - 1, m - 1, x1, y1, x2, y2, 0, 0);
}
int constructSTUtil(int arr[][], int x1, int y1, int x2, int y2, int si, int sj)
{
// If there is one element in array, store it in current
// node of segment tree and return
if (x1 == x2 && y1 == y2) {
st[si][sj] = arr[x1][y1];
return arr[x1][y1];
}
// If there are more than one elements, then recur for left and
// right subtrees and store the minimum of two values in this node
int midx = getMid(x1, x2);
int midy = getMid(y1, y2);
st[si][sj] = minVal(constructSTUtil(arr, x1, y1, midx, midy, si * 2 + 1, sj * 2 + 1),
constructSTUtil(arr, midx + 1, midy + 1, x2, y2, si * 2 + 2, sj * 2 + 2));
return st[si][sj];
}
void constructST(int arr[][], int n, int m)
{
// Allocate memory for segment tree
//Height of segment tree
int x = (int) (Math.ceil(Math.log(n) / Math.log(2)));
int y = (int) (Math.ceil(Math.log(m) / Math.log(2)));
//Maximum size of segment tree
int max_size_x = 2 * (int) Math.pow(2, x) - 1;
int max_size_y = 2 * (int) Math.pow(2, y) - 1;
st = new int[max_size_x][max_size_y]; // allocate memory
// Fill the allocated memory st
constructSTUtil(arr, 0, 0, n - 1, m - 1, 0, 0);
}
}
class City implements Comparator<City> {
int latitude;
int longitude;
int height;
int points;
public City() {
}
public int compare(City c1, City c2){
return c1.height - c2.height;
}
}
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int d_lat = in.nextInt();
int d_long = in.nextInt();
ArrayList<City> cities = new ArrayList<City>();
for(int a0 = 0; a0 < n; a0++){
int latitude = in.nextInt();
int longitude = in.nextInt();
int height = in.nextInt();
int points = in.nextInt();
// Write Your Code Here
City city = new City();
city.latitude = latitude;
city.longitude = longitude;
city.height = height;
city.points = points;
cities.add(city);
}
Collections.sort(cities, new City());
int max_lat = Integer.MIN_VALUE;
int min_lat = Integer.MAX_VALUE;
int max_long = Integer.MIN_VALUE;
int min_long = Integer.MAX_VALUE;
for(City city : cities){
if(city.latitude > max_lat){
max_lat = city.latitude;
}
if(city.latitude < min_lat){
min_lat = city.latitude;
}
if(city.longitude > max_long){
max_long = city.longitude;
}
if(city.longitude < min_long){
min_long = city.longitude;
}
}
int lat_diff = max_lat-min_lat;
int long_diff = max_long-min_long;
int[][] arr = new int[lat_diff+1][long_diff+1];
for(City city : cities){
arr[city.latitude - min_lat ][city.longitude - min_long]=city.points;
}
SegmentTreeRMQ tree = new SegmentTreeRMQ();
tree.constructST(arr, lat_diff, long_diff);
int max_till_now = Integer.MIN_VALUE;
int max_till_city = 0;
for(City city : cities){
int x = city.latitude;
int y = city.longitude;
max_till_city = tree.RMQ(lat_diff+1,long_diff+1,x-d_lat,y-d_long,x+d_lat,y+d_long);
if(max_till_now < max_till_city){
max_till_now = max_till_city;
}
}
System.out.println(max_till_now);
in.close();
}
}
What I need to know is that do i require an update query as well? If yes please send me some pointers.
Thanks,
Apoorv Srivastava
Firstly I'm not sure if this is the right place to post this question, so if I am wrong, please, move it. Thanks.
I had an assignment to compare same algorithm performance in Java and C#. The algorithm is supposed to be A* search, but I think I made it more like flooding, but it works well and I'm not here to fix it. Firstly I'll post the code I was using in Java and C# and then explain what I got.
As body of question is limited to 30000 characters and I entered more, I had to delete functions readFile() from Java and C# to make it fit.
UPDATED
After Jim Mischel has pointed out I updated hash function in C# version to be same as in Java which resulted in better performance.
Also thanks to Matt Timmermans I realized that all this time I was running C# in debug (Result of not thinking it through) and changing to release increased performance even more.
C# version:
File: Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Diagnostics;
namespace A_Star_Compare
{
class Program
{
static int StartX = 0;
static int StartY = 0;
static int TargetX = 0;
static int TargetY = 0;
static int Width = 0;
static int Height = 0;
static TimeSpan TotalTime = TimeSpan.Zero;
static double[] TrialTimes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static Dictionary<int, List<int>> Obstacles = new Dictionary<int, List<int>>();
static void Main(string[] args)
{
for (int z = 0; z < 10; z++)
{
int Index = 0;
Console.WriteLine("z: " + z);
for (int x = 0; x < 14; x++)
{
if (x < 10)
Index += 10;
else
Index += 100;
string Line = string.Empty;
string FileName = "Maps-" + Index + ".txt";
TotalTime = TimeSpan.Zero;
readFile(FileName);
TrialTimes[x] += (double)TotalTime.TotalSeconds / 100;
}
}
int Index0 = 0;
for (int i = 0; i < 14; i++)
{
if (i < 10)
Index0 += 10;
else
Index0 += 100;
string FileName = "Maps-" + Index0 + ".txt";
Console.WriteLine("{0} Map size: {1}*{2}. On average map solved in: {3}", FileName, Index0, Index0, (double)TrialTimes[i] / 10);
}
}
static void measureTime()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Algorithm Solve = new Algorithm(StartX, StartY, TargetX, TargetY, Width, Height, Obstacles);
Solve.FullSolve();
stopwatch.Stop();
TotalTime += stopwatch.Elapsed;
}
}
}
File: Algorithm.cs
using System.Collections.Generic;
namespace A_Star_Compare
{
public class Node
{
public int X { get; set; }
public int Y { get; set; }
public int G { get; set; }
public int F { get; set; }
public int H { get; set; }
public Node PointsTo { get; set; }
public Node(int x, int y, int g, int f, int h, Node point)
{
this.X = x;
this.Y = y;
this.G = g;
this.F = f;
this.H = h;
this.PointsTo = point;
}
public override bool Equals(object obj)
{
Node rhs = obj as Node;
return rhs.X == this.X && rhs.Y == this.Y;
}
public override int GetHashCode()
{
int hash = 7;
hash = 83 * hash + this.X;
hash = 83 * hash + this.Y;
return hash;
}
}
class Algorithm
{
private Dictionary<int, List<int>> Obstacles { get; set; }
public HashSet<Node> OpenList { get; set; }
public HashSet<Node> ClosedList { get; set; }
private Node Parent { get; set; }
private Node LowestCost { get; set; }
private int StartX { get; set; }
private int StartY { get; set; }
private int TargetX { get; set; }
private int TargetY { get; set; }
private int Width { get; set; }
private int Height { get; set; }
private bool FirstIter = true;
public Algorithm(int stX, int stY, int tgX, int tgY, int wid, int hei, Dictionary<int, List<int>> obs)
{
this.StartX = stX;
this.StartY = stY;
this.TargetX = tgX;
this.TargetY = tgY;
this.Width = wid - 1;
this.Height = hei - 1;
this.Obstacles = new Dictionary<int, List<int>>(obs);
this.Parent = new Node(StartX, StartY, 0, 0, 0, null);
this.LowestCost = new Node(int.MaxValue, int.MaxValue, 0, int.MaxValue, 0, null);
this.ClosedList = new HashSet<Node>();
this.OpenList = new HashSet<Node>();
}
private bool IsBlockObstacle(int X, int Y)
{
if (Obstacles.ContainsKey(X) == false || (Obstacles.ContainsKey(X) == true && Obstacles[X].Contains(Y) == false))
return false;
return true;
}
private void Calculate(ref int H, int G, ref int F, int MovedX, int MovedY, Node AddToList)
{
int H1 = 0;
H = (TargetX - MovedX) * 10;
if (H < 0)
H *= -1;
H1 = (TargetY - MovedY) * 10;
if (H1 < 0)
H1 *= -1;
H += H1;
F = G + H;
AddToList.F = F;
AddToList.H = H;
AddToList.PointsTo = Parent;
}
private Node GetNodeFromOpen(Node Find)
{
Node Ret = null;
foreach (Node Nfo in OpenList)
{
if (Nfo.Equals(Find))
{
Ret = Nfo;
break;
}
}
return Ret;
}
private bool CheckNode(Node AddToList, int G)
{
if (!OpenList.Contains(AddToList))
{
OpenList.Add(AddToList);
return true;
}
else
{
Node Check = GetNodeFromOpen(AddToList);
if (Parent.G + G < Check.G)
{
int Offset = Check.G - Parent.G - G;
Check.G -= Offset;
Check.F -= Offset;
Check.PointsTo = Parent;
}
}
return false;
}
private void ChooseNode()
{
foreach (Node Nfo in OpenList)
{
if (Nfo.X == TargetX && Nfo.Y == TargetY)
{
LowestCost = Nfo;
break;
}
if (Nfo.F < LowestCost.F)
LowestCost = Nfo;
}
}
private void CountCost()
{
int[] Directions = { 1, -1 };
int[] Diagnoly = { 1, 1, -1, 1, 1, -1, -1, -1 };
int ParentX = Parent.X;
int ParentY = Parent.Y;
int MovedX = 0;
int MovedY = 0;
int H = 0;
int F = 0;
Node AddToList = null;
//Left and right
for (int i = 0; i < 2; i++)
{
//Check if it is possible to move right or left
if (ParentX + Directions[i] <= Width && ParentX + Directions[i] >= 0)
{
//Check if blocks to the right and left of parent aren't obstacles
if (!IsBlockObstacle(ParentX + Directions[i], ParentY))
{
AddToList = new Node(ParentX + Directions[i], ParentY, Parent.G + 10, 0, 0, null);
//Check if it is not on closed list
if (!ClosedList.Contains(AddToList))
{
MovedX = AddToList.X;
MovedY = AddToList.Y;
Calculate(ref H, AddToList.G, ref F, MovedX, MovedY, AddToList);
CheckNode(AddToList, 10);
}
}
}
}
//Up and down
for (int i = 0; i < 2; i++)
{
//Check if possible to move up or down
if (ParentY + Directions[i] <= Height && ParentY + Directions[i] >= 0)
{
//Check if higher and lower block of parent aren't obstacles
if (!IsBlockObstacle(ParentX, ParentY + Directions[i]))
{
AddToList = new Node(ParentX, ParentY + Directions[i], Parent.G + 10, 0, 0, null);
if (!ClosedList.Contains(AddToList))
{
MovedX = ParentX;
MovedY = ParentY + Directions[i];
Calculate(ref H, AddToList.G, ref F, MovedX, MovedY, AddToList);
CheckNode(AddToList, 10);
}
}
}
}
//Diagnoly
for (int i = 0; i < 8; i += 2)
{
if (ParentX + Diagnoly[i] <= Width && ParentX + Diagnoly[i] >= 0 && ParentY + Diagnoly[i + 1] <= Height && ParentY + Diagnoly[i + 1] >= 0)
{
if (!IsBlockObstacle(ParentX + Diagnoly[i], ParentY + Diagnoly[i + 1]))
{
AddToList = new Node(ParentX + Diagnoly[i], ParentY + Diagnoly[i + 1], Parent.G + 14, 0, 0, null);
if (!ClosedList.Contains(AddToList))
{
MovedX = ParentX + Diagnoly[i];
MovedY = ParentY + Diagnoly[i + 1];
Calculate(ref H, AddToList.G, ref F, MovedX, MovedY, AddToList);
CheckNode(AddToList, 14);
}
}
}
}
}
public void FullSolve()
{
Node Final = null;
if (FirstIter)
{
CountCost();
ChooseNode();
OpenList.Remove(Parent);
ClosedList.Add(Parent);
Parent = LowestCost;
OpenList.Remove(Parent);
ClosedList.Add(Parent);
FirstIter = false;
FullSolve();
}
else
{
while (true)
{
if (OpenList.Count == 0)
break;
CountCost();
HashSet<Node> Copy = new HashSet<Node>(OpenList);
foreach (Node Nfo in Copy)
{
Parent = Nfo;
CountCost();
ClosedList.Add(Parent);
OpenList.Remove(Parent);
if (Parent.X == TargetX && Parent.Y == TargetY)
{
Final = Parent;
break;
}
}
ChooseNode();
OpenList.Remove(Parent);
ClosedList.Add(Parent);
Parent = LowestCost;
LowestCost.F = int.MaxValue;
if (Parent.X == TargetX && Parent.Y == TargetY)
{
Final = Parent;
break;
}
}
}
}
}
}
Java version:
File: AStar_Compare.java
package a.star_compare;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.lang3.time.StopWatch;
public class AStar_Compare {
static double totalTime;
static double[] trialTimes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
static int startX;
static int startY;
static int targetX;
static int targetY;
static int width;
static int heigth;
static HashMap<Integer, List<Integer>> obstacles = new HashMap<>();
static NumberFormat formatter = new DecimalFormat("#0.000000000");
public static void main(String[] args) throws FileNotFoundException, IOException {
for (int z = 0; z < 10; z++) {
int Index = 0;
System.out.println("z: " + z);
for (int x = 0; x < 5; x++) {
if (x < 10) {
Index += 10;
} else {
Index += 100;
}
String fileName = "Maps-" + Index + ".txt";
totalTime = 0;
readFile(fileName);
trialTimes[x] += totalTime / 1E9 / 100;
}
}
int index0 = 0;
for (int i = 0; i < 14; i++) {
if (i < 10) {
index0 += 10;
} else {
index0 += 100;
}
trialTimes[i] /= 10;
String fileName = "Maps-" + index0 + ".txt";
System.out.println(fileName + " Map size: " + index0 + "*" + index0 + ". On average map solved in: " + formatter.format(trialTimes[i]));
}
}
static void measureTime() {
StopWatch time = new StopWatch();
time.start();
Algorithm solve = new Algorithm(obstacles, startX, startY, targetX, targetY, width, heigth);
solve.FullSolve();
time.stop();
totalTime += time.getNanoTime();
}
}
File: Node.java
package a.star_compare;
public class Node {
public int x;
public int y;
public int g;
public int h;
public int f;
public Node pointsTo;
public Node(int gx, int gy, int gg, int gh, int gf, Node point){
this.x = gx;
this.y = gy;
this.g = gg;
this.h = gh;
this.f = gf;
this.pointsTo = point;
}
#Override
public boolean equals(Object other){
if(other == null) return false;
if(other == this) return true;
if(!(other instanceof Node)) return false;
Node rhs = (Node)other;
return this.x == rhs.x && this.y == rhs.y;
}
#Override
public int hashCode() {
int hash = 7;
hash = 83 * hash + this.x;
hash = 83 * hash + this.y;
return hash;
}
}
File: Algorithm.java
package a.star_compare;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
public class Algorithm {
private final HashMap<Integer, List<Integer>> obstacles;
private final HashSet<Node> closedList;
private final HashSet<Node> openList;
private Node parent;
private Node lowestCost;
private final int startX;
private final int startY;
private final int targetX;
private final int targetY;
private final int width;
private final int height;
private boolean firstIter = true;
public Algorithm(HashMap<Integer, List<Integer>> obs, int stX, int stY, int tgX, int tgY, int wid, int hei) {
this.obstacles = new HashMap(obs);
this.startX = stX;
this.startY = stY;
this.targetX = tgX;
this.targetY = tgY;
this.width = wid - 1;
this.height = hei - 1;
this.parent = new Node(startX, startY, 0, 0, 0, null);
this.lowestCost = new Node(Integer.MAX_VALUE, Integer.MAX_VALUE, 0, Integer.MAX_VALUE, 0, null);
this.closedList = new HashSet<>();
this.openList = new HashSet<>();
}
private boolean isBlockObstacle(Integer x, Integer y) {
if (obstacles.containsKey(x) == false || (obstacles.containsKey(x) == true && obstacles.get(x).contains(y) == false)) {
return false;
}
return true;
}
private void calculate(int h, int g, int f, int movedX, int movedY, Node addToList) {
int h1 = 0;
h = (targetX - movedX) * 10;
if (h < 0) {
h *= -1;
}
h1 = (targetY - movedY) * 10;
if (h1 < 0) {
h1 *= -1;
}
h += h1;
f = g + h;
addToList.f = f;
addToList.h = h;
addToList.pointsTo = parent;
}
private Node getNodeFromOpen(Node find) {
Node ret = null;
for (Node nfo : openList) {
if (nfo.equals(find)) {
ret = nfo;
break;
}
}
return ret;
}
private boolean checkNode(Node addToList, int g) {
if (!openList.contains(addToList)) {
openList.add(addToList);
return true;
} else {
Node check = getNodeFromOpen(addToList);
if (parent.g + g < check.g) {
int offset = check.g - parent.g - g;
check.g -= offset;
check.f -= offset;
check.pointsTo = parent;
}
}
return false;
}
private void chooseNode() {
for (Node nfo : openList) {
if (nfo.x == targetX && nfo.y == targetY) {
lowestCost = nfo;
break;
}
if (nfo.f < lowestCost.f) {
lowestCost = nfo;
}
}
}
private void countCost() {
int[] directions = {1, -1};
int[] diagnoly = {1, 1, -1, 1, 1, -1, -1, -1};
int parentX = parent.x;
int parentY = parent.y;
int movedX = 0;
int movedY = 0;
int h = 0;
int f = 0;
Node addToList = null;
//Left and right
for (int i = 0; i < 2; i++) {
//Check if it is possible to move right or left
if (parentX + directions[i] <= width && parentX + directions[i] >= 0) {
//Check if blocks to the right and left of parent aren't obstacles
if (!isBlockObstacle(parentX + directions[i], parentY)) {
addToList = new Node(parentX + directions[i], parentY, parent.g + 10, 0, 0, null);
//Check if it is not on closed list
if (!closedList.contains(addToList)) {
movedX = addToList.x;
movedY = addToList.y;
calculate(h, addToList.g, f, movedX, movedY, addToList);
checkNode(addToList, 10);
}
}
}
}
//Up and down
for (int i = 0; i < 2; i++) {
//Check if possible to move up or down
if (parentY + directions[i] <= height && parentY + directions[i] >= 0) {
//Check if higher and lower block of parent aren't obstacles
if (!isBlockObstacle(parentX, parentY + directions[i])) {
addToList = new Node(parentX, parentY + directions[i], parent.g + 10, 0, 0, null);
if (!closedList.contains(addToList)) {
movedX = parentX;
movedY = parentY + directions[i];
calculate(h, addToList.g, f, movedX, movedY, addToList);
checkNode(addToList, 10);
}
}
}
}
//diagnoly
for (int i = 0; i < 8; i += 2) {
if (parentX + diagnoly[i] <= width && parentX + diagnoly[i] >= 0 && parentY + diagnoly[i + 1] <= height && parentY + diagnoly[i + 1] >= 0) {
if (!isBlockObstacle(parentX + diagnoly[i], parentY + diagnoly[i + 1])) {
addToList = new Node(parentX + diagnoly[i], parentY + diagnoly[i + 1], parent.g + 14, 0, 0, null);
if (!closedList.contains(addToList)) {
movedX = parentX + diagnoly[i];
movedY = parentY + diagnoly[i + 1];
calculate(h, addToList.g, f, movedX, movedY, addToList);
checkNode(addToList, 14);
}
}
}
}
}
public void FullSolve() {
Node finalPath = null;
if (firstIter) {
countCost();
chooseNode();
openList.remove(parent);
closedList.add(parent);
parent = lowestCost;
openList.remove(parent);
closedList.add(parent);
firstIter = false;
FullSolve();
} else {
while (true) {
if (openList.isEmpty()) {
break;
}
countCost();
HashSet<Node> copy = new HashSet<>(openList);
for (Node nfo : copy) {
parent = nfo;
countCost();
closedList.add(parent);
openList.remove(parent);
if (parent.x == targetX && parent.y == targetY) {
finalPath = parent;
break;
}
}
chooseNode();
openList.remove(parent);
closedList.add(parent);
parent = lowestCost;
lowestCost.f = Integer.MAX_VALUE;
if (parent.x == targetX && parent.y == targetY) {
finalPath = parent;
break;
}
}
}
}
}
The testing was done with pregenerated map files. I have 14 map files each of them contains a 100 maps with specific size. With lowest one being map by 10 * 10 and highest being by 500 * 500.
Also note that if each map has 100 examples it means that algorithm was tested 100 times to work with one specific size, furthermore I wanted to increase accuracy even more so I repeat whole process 10 times. Which gives me 1000 test with one map. I of course average those times.
I'm not really familiar with high accuracy time measuring methods so I used StopWatch() in both Java and C# (To use it in Java I downloaded it from apache commons). What I did was after reading one map information I called function measureTime() and started StopWatch() then call Algorithm class and make it solve puzzle after that I'd stop StopWatch() and take time.
Here are the results I got:
I'm posting image because I'm not sure how to make a table here. Times are in second, how much it took to solve one map in average.
Note after "-" symbol there is map size. (Maps-20.txt means map by 20 * 20 and so on)
Also a graph:
These results really surprised me, I was expecting one language having a bit of an advantage, but not like this. After update C# graph looks similar to Java graph, but has steeper growth rate. First I thought that I made some mistake while copying algorithm to Java (Firstly I wrote in C#), but I couldn't find any. So assuming that I didn't make some silly mistake.
How can I improve C# performance even more?
Also one thing I thought about getting these results that in Dictionary<int, List<int>> instead of using List<int> I could use HashSet<int> since I only need to confirm if element exists or not. But as I am not dealing with thousands of elements I don't think that it could be major factor.
Thanks.
I'm trying to write an algorithm to satisfy this challenge. I've double, triple, and quadruple checked my logic, but I think I'm missing something obvious. This program should group each color next to similar colors, but it produces something more akin to noise.
This is sort of what I expect (taken from a similar answer):
And this is what I'm actually getting:
public class AllColors extends JFrame {
private static final int WIDTH = 256;
private static final int HEIGHT = 128;
private static long TOTAL_ITERATIONS = (WIDTH * HEIGHT) * 185000;
private static int VALUES_PER_CHANNEL =32;
private static int CHANNEL_DELTA = 256/VALUES_PER_CHANNEL;
static BufferedImage image;
private static final int SCALE = 5;
static int[][] kernel = { { 0, 0, 1, 0, 0 },
{ 0, 2, 3, 2, 0 },
{ 1, 3, 0, 3, 1 },
{ 0, 2, 3, 2, 0 },
{ 0, 0, 1, 0, 0 } };
public static void main(String[] args) {
AllColors f = new AllColors();
f.setTitle("All Colors");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
image = new BufferedImage(WIDTH * SCALE, HEIGHT * SCALE, BufferedImage.TYPE_3BYTE_BGR);
init();
//gui stuff
JPanel p = new JPanel(){
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.scale(SCALE, SCALE);
g2.drawImage(image, 0, 0, null);
}
};
p.setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
f.add(p);
f.pack();
f.setVisible(true);
group(p);
}
//makes an image of all colors
private static void init() {
int x = 0;
int y = 0;
for(int r = 0; r < VALUES_PER_CHANNEL; r+= 1){
for(int g = 0; g < VALUES_PER_CHANNEL; g+= 1){
for(int b = 0; b < VALUES_PER_CHANNEL; b+= 1){
x++;
if(x % WIDTH == 0){
y++;
x = 0;
}
if(y >= HEIGHT)
return;
image.setRGB(x, y, new Color(r*CHANNEL_DELTA,g*CHANNEL_DELTA,b*CHANNEL_DELTA).getRGB());
}
}
}
}
//group together similar pixels
private static void group(JPanel panel){
Random rand = new Random();
for(long i = 0; i < TOTAL_ITERATIONS; i++){
Point first = new Point(rand.nextInt(WIDTH), rand.nextInt(HEIGHT));
Point second = new Point(rand.nextInt(WIDTH), rand.nextInt(HEIGHT));
trySwitch(first, second);
if(i % (WIDTH * HEIGHT) == 0){
System.out.println(i / (WIDTH * HEIGHT));
panel.repaint();
}
}
}
private static void swap(Point first, Point second){
int temp = image.getRGB(second.x, second.y);
image.setRGB(second.x, second.y, image.getRGB(first.x, first.y));
image.setRGB(first.x, first.y, temp);
}
//get how similar the neighbors are
private static int getNeighborDelta(int imageX, int imageY){
Color center = new Color(image.getRGB(imageX, imageY));
int sum = 0;
for (int x = 0; x < kernel[0].length; x++)
{
for (int y = 0; y < kernel.length; y++)
{
int weight = kernel[x][y];
if (weight <= 0)
{
continue;
}
int xOffset = x - (kernel[0].length / 2);
int yOffset = y - (kernel.length / 2);
try{
sum += getDistance(new Color(image.getRGB(imageX + xOffset, imageY + yOffset)), center) * weight;
}catch(ArrayIndexOutOfBoundsException e){
//if out of image
}
}
}
return sum;
}
//switches if the neighbors will be more similar
private static void trySwitch(Point first, Point second){
double firstDistance = getNeighborDelta(first.x, first.y);
swap(first, second);
double secondDistance = getNeighborDelta(first.x, first.y);
if(secondDistance > firstDistance)
swap(first, second);
}
//get similarity between colors
private static double getDistance(Color one, Color two){
int r = Math.abs(two.getRed() - one.getRed());
int g = Math.abs(two.getGreen() - one.getGreen());
int b = Math.abs(two.getBlue() - one.getBlue());
return r + g + b;
}
}
I need to make perlin noise like in AS3.0:
bitmapData.perlinNoise(baseX, baseY, numOctaves,
randomSeed, stitch, fractalNoise, grayScale, offsets);
It's seamless noise:
I found a lot of material about it, but I can't make it like in my as3.0 image. Java code:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Noise extends JPanel{
public static int octaves = 4;
public static int size = 128;
public static float[][][] noise = new float[size][size][octaves];
public static float[][] perlinnoise = new float[size][size];
public static float p = (float) 1/4;
public static Random gen = new Random();
public static float GenerateNoise() {
return gen.nextFloat();
}
public static float SmoothNoise(int x, int y, int z) {
try{
float corners = (noise[x - 1][y - 1][z] + noise[x + 1][y - 1][z] + noise[x - 1][y + 1][z] + noise[x + 1][y + 1][z]) / 16;
float sides = (noise[x - 1][y][z] + noise[x + 1][y][z] + noise[x][y - 1][z] + noise[x][y + 1][z]) / 8;
float center = noise[x][y][z] / 4;
return corners + sides + center;
}catch(Exception e) {
return 0;
}
}
public static float InterpolatedNoise(float x, float y, int pX, int pY, int pZ) {
int intX = (int) x;
int intY = (int) y;
float fracX = x - intX;
float fracY = y - intY;
float v1 = SmoothNoise(pX, pY, pZ);
float v2 = SmoothNoise(pX + 1, pY, pZ);
float v3 = SmoothNoise(pX, pY + 1, pZ);
float v4 = SmoothNoise(pX + 1, pY + 1, pZ);
float i1 = Interpolate(v1, v2, fracX);
float i2 = Interpolate(v3, v4, fracX);
return Interpolate(i1, i2, fracY);
}
public static float Interpolate(float a, float b, float x) {
float ft = (float) (x * 3.1415927);
float f = (float) ((1 - Math.cos(ft)) * 0.5);
return (float) (a * (1 - f) + b * f);
}
public static float Perlin2D(float x, float y, int posX, int posY, int posZ) {
float total = 0;
for(int i = 0; i < octaves; i++) {
double f = Math.pow(2, i);
double a = Math.pow(p, i);
total = (float) (total + InterpolatedNoise((float)(x * f), (float)(y * f), posX, posY, posZ) * a);
}
return total;
}
public static void main(String [] args) {
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
noise[x][y][z] = GenerateNoise();
}
}
}
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
perlinnoise[x][y] = Perlin2D(x / (size - 1), y / (size - 1), x, y, z) / octaves;
}
}
}
JFrame f = new JFrame("Perlin Noise");
f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Noise());
f.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
g.setColor(new Color(perlinnoise[x][y], perlinnoise[x][y], perlinnoise[x][y]));
g.fillRect(x * 2, y * 2, 2, 2);
}
}
repaint();
}
}
Help please!
The trick is, the Perlin noise does not use pseudo-random generator, it uses a function that takes an argument and returns predefined value for that argument, but when argument shifts by 1, the value jumps almost randomly. Check the sources for the permutation formulae, the init() method makes a permutation that then is used to make the entire noise.
Hey stackoverflow community! I have been reading about perlin noise for the past 2 weeks and tried implementing it on my own in the most basic way. Even so, my program does not work. It outputs near similar looking results all the time and the persistence does not seem to change anything. Here is my code:
import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Noise extends JPanel{
public static int octaves = 4;
public static int size = 128;
public static float[][][] noise = new float[size][size][octaves];
public static float[][] perlinnoise = new float[size][size];
public static float p = (float) 1/4;
public static Random gen = new Random();
public static float GenerateNoise() {
return gen.nextFloat();
}
public static float SmoothNoise(int x, int y, int z) {
try{
float corners = (noise[x - 1][y - 1][z] + noise[x + 1][y - 1][z] + noise[x - 1][y + 1][z] + noise[x + 1][y + 1][z]) / 16;
float sides = (noise[x - 1][y][z] + noise[x + 1][y][z] + noise[x][y - 1][z] + noise[x][y + 1][z]) / 8;
float center = noise[x][y][z] / 4;
return corners + sides + center;
}catch(Exception e) {
return 0;
}
}
public static float InterpolatedNoise(float x, float y, int pX, int pY, int pZ) {
int intX = (int) x;
int intY = (int) y;
float fracX = x - intX;
float fracY = y - intY;
float v1 = SmoothNoise(pX, pY, pZ);
float v2 = SmoothNoise(pX + 1, pY, pZ);
float v3 = SmoothNoise(pX, pY + 1, pZ);
float v4 = SmoothNoise(pX + 1, pY + 1, pZ);
float i1 = Interpolate(v1, v2, fracX);
float i2 = Interpolate(v3, v4, fracX);
return Interpolate(i1, i2, fracY);
}
public static float Interpolate(float a, float b, float x) {
float ft = (float) (x * 3.1415927);
float f = (float) ((1 - Math.cos(ft)) * 0.5);
return (float) (a * (1 - f) + b * f);
}
public static float Perlin2D(float x, float y, int posX, int posY, int posZ) {
float total = 0;
for(int i = 0; i < octaves; i++) {
double f = Math.pow(2, i);
double a = Math.pow(p, i);
total = (float) (total + InterpolatedNoise((float)(x * f), (float)(y * f), posX, posY, posZ) * a);
}
return total;
}
public static void main(String [] args) {
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
noise[x][y][z] = GenerateNoise();
}
}
}
for(int z = 0; z < octaves; z++) {
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
perlinnoise[x][y] = Perlin2D(x / (size - 1), y / (size - 1), x, y, z) / octaves;
}
}
}
JFrame f = new JFrame("Perlin Noise");
f.setSize(400, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Noise());
f.setVisible(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
for(int y = 0; y < size; y++) {
for(int x = 0; x < size; x++) {
g.setColor(new Color(perlinnoise[x][y], perlinnoise[x][y], perlinnoise[x][y]));
g.fillRect(x * 2, y * 2, 2, 2);
}
}
repaint();
}
}
I do not understand why it is not working because it is exactly as the pseudo code in this article said to do it. Can anyone assist me in figuring this out? Thanks.
EDIT: Ok please can someone just explain the process required to do this PLEASE I am going crazy trying to figure this out. I have been trying to figure it out for the past 2 weeks and no one is giving me any help with it. Please if you know how to do this, please just explain it to me I would greatly appreciate it. Thanks.