This is a ACM-ICPC practicing problem: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=975. And the basic idea is to find the shortest weight of a minimum spanning tree. And I tried to solve it with Kruskal algorithm. I tested it myself and it seems to be working fine. However, when I submit it onto the uva online judge, the result is "wrong answer". Could any body see where is not correct? Thanks!
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
//import java.util.Comparator;
import java.util.List;
//import java.math.*;
public class Main {
public static void main(String[] args) throws Exception, IOException {
BufferedReader cin = new BufferedReader(new InputStreamReader(System.in));
int numOfCases = Integer.parseInt(cin.readLine());
while (numOfCases > 0) {
cin.readLine();
int numOfPoints = Integer.parseInt(cin.readLine());
List<Points> listOfPoints = new ArrayList<Points>();
List<Edge> listOfEdges = new ArrayList<Edge>();
double inkUsed = 0;
for (int i = 0; i < numOfPoints; i++) {
String[] tokens = cin.readLine().split(" ");
Points point = new Points(Double.parseDouble(tokens[0]),Double.parseDouble(tokens[1]));
listOfPoints.add(point);
}
for (int i = 0; i < listOfPoints.size(); i++) {
for (int j = i+1; j < listOfPoints.size(); j++) {
Edge edge = new Edge(listOfPoints.get(i), listOfPoints.get(j));
listOfEdges.add(edge);
}
}
Collections.sort(listOfEdges);
for (Edge e: listOfEdges) {
Points pointA = null;
Points pointB = null;
// Find pointA and pointB in the list "listOfPoints"
for (int i = 0; i < listOfPoints.size(); i++) {
if (listOfPoints.get(i).x == e.A.x && listOfPoints.get(i).y == e.A.y) {
pointA = listOfPoints.get(i);
}
if (listOfPoints.get(i).x == e.B.x && listOfPoints.get(i).y == e.B.y) {
pointB = listOfPoints.get(i);
}
}
Points rootOfA = findSet(pointA);
Points rootOfB = findSet(pointB);
if (rootOfA.x != rootOfB.x || rootOfA.y != rootOfB.y){ //add this edge
//System.out.println( "[" + "(" + pointA.x +"," + pointA.y+"); (" + pointB.x +"," + pointB.y+")"+ "]");
inkUsed += e.weight;
rootOfA.parent = rootOfB;
}
}
DecimalFormat df = new DecimalFormat("#.00");
System.out.println(df.format(inkUsed));
numOfCases--;
}
}
public static Points findSet(Points A) {
Points rootOfA = A;
while (rootOfA.parent != null) {
rootOfA = rootOfA.parent;
}
return rootOfA;
}
}
class Points {
public double x;
public double y;
public Points parent = null;
Points (double x, double y) {
this.x = x;
this.y = y;
}
}
class Edge implements Comparable<Edge> {
Points A;
Points B;
double weight;
Edge (Points var1, Points var2) {
A = var1;
B = var2;
weight = Math.sqrt(Math.pow((A.x-B.x), 2) + Math.pow((A.y-B.y), 2));
}
public String toString() {
return Double.toString(weight);
}
public int compareTo(Edge anotherEdge) {
if (this.weight < anotherEdge.weight) {
return -1;
} else if (this.weight == anotherEdge.weight) {
return 0;
} else {
return 1;
}
}
}
Related
This question already has answers here:
What does "Could not find or load main class" mean?
(61 answers)
Closed 2 years ago.
I've been working on a project recently and I have come to the end of my compilation, moving out of Eclipse and into cmd. I have a single .java names PA3 containing multiple classes.
My task is to compile the program with:
javac PA3.java
And to run the program with the command:
java PA3 test.dat
where test.dat is a placeholder (no need to worry about that)
When I compile, all the classes compile properly as shown:
here
All I seem to run into is issues regarding
Error: Could not find or load main class PA3
Caused by: java.lang.ClassNotFoundException: PA3
And my code is below:
(Mind you it is messy and a little over the place at the moment)
'''
import linkedlist.MyPolygons;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class PA3
{
//================================MAIN================================//
public static void main(String[] args)
{
MyPolygons.main(args);
};
}
class MyPolygons{
//================================MAIN================================//
public static void main(String[] args)
{
MyPolygons poly = Import(new ExtendedFile("src\\linkedlist\\text.txt"));
poly.display();
}
//Represent a node of the doubly linked list
class Node{
PlanarShape data;
String type;
Node previous;
Node next;
public Node(PlanarShape data, String type) {
this.data = data;
this.type = type;
}
}
//Represent the head and tail of the doubly linked list
Node head, tail = null;
public void sort()
{
Node current = head;
boolean changed = true;
while(changed)
{
changed = false;
Node next;
for(int i = 0; i < 50; i++)
{
current = head;
while((next = current.next) != null)
{
if(current.data.getArea(current.type) > next.data.getArea(next.type))
{
//System.out.println("Current.data: " + current.data.getArea(current.type) + " Next.data: " + next.data.getArea(next.type));
PlanarShape temp;
temp = current.data;
current.data = next.data;
next.data = temp;
String temps;
temps = current.type;
current.type = next.type;
next.type = temps;
current = next;
}
current = next;
}
}
}
}
//addNode() will add a node to the list
public void addNode(PlanarShape data, String type) {
//Create a new node
Node newNode = new Node(data, type);
//If list is empty
if(head == null) {
//Both head and tail will point to newNode
head = tail = newNode;
//head's previous will point to null
head.previous = null;
//tail's next will point to null, as it is the last node of the list
tail.next = null;
}
else {
//newNode will be added after tail such that tail's next will point to newNode
tail.next = newNode;
//newNode's previous will point to tail
newNode.previous = tail;
//newNode will become new tail
tail = newNode;
//As it is last node, tail's next will point to null
tail.next = null;
}
}
//display() will print out the nodes of the list
public void display()
{
//Node current will point to head
Node current = head;
if(head == null)
{
System.out.println("List is empty");
return;
}
System.out.println("Nodes of a Double linked list: ");
System.out.println("Unsorted List: ");
while(current != null)
{
System.out.print(current.type);
System.out.print("[");
//Prints each node by incrementing the pointer.
System.out.print(current.data);
if (current.type == "CIRC= ")
{
System.out.print(", ");
System.out.print(getRad());
}
System.out.println(String.format("]: %.2f", current.data.getArea(current.type)));
current = current.next;
}
sort();
System.out.println("Sorted List: ");
current = head;
while(current != null)
{
System.out.print(current.type);
System.out.print("[");
//Prints each node by incrementing the pointer.
System.out.print(current.data);
if (current.type == "CIRC= ")
{
System.out.print(", ");
System.out.print(PlanarShape.returnRadius());
}
System.out.println(String.format("]: %.2f", current.data.getArea(current.type)));
//System.out.println(current.data.originDistance());
current = current.next;
}
}
static float radius;
static float vertlength;
static PlanarShape PlanarShape = new PlanarShape();
public static MyPolygons Import(ExtendedFile f)
{
String[] lines = f.readLines();
MyPolygons poly = new MyPolygons();
for (int i = 0; i < lines.length; i++)
{
PlanarShape PlanarShape = new PlanarShape();
String[] array = lines[i].split(" ");
String shapetype = array[0];
switch(shapetype)
{
case "P":
for(int k = 2; k < array.length-1; k++)
{
float x = Float.parseFloat(array[k]);
k++;
float y = Float.parseFloat(array[k]);
PlanarShape.addVerticy(new Point(x, y));
vertlength = ((array.length-2)/2);
}
//Add nodes to the list
poly.addNode(PlanarShape, "POLY= ");
break;
case "C":
for(int k = 1; k < array.length-1; k++)
{
PlanarShape.addRadius(Float.parseFloat(array[array.length-1]));
float x = Float.parseFloat(array[k]);
k++;
float y = Float.parseFloat(array[k]);
PlanarShape.addVerticy(new Point(x, y));
}
poly.addNode(PlanarShape, "CIRC= ");
break;
case "S":
for(int k = 1; k < array.length-1; k++)
{
float x = Float.parseFloat(array[k]);
k++;
float y = Float.parseFloat(array[k]);
PlanarShape.addVerticy(new Point(x, y));
}
//Add nodes to the list
poly.addNode(PlanarShape, "SEMI= ");
break;
}
}
return poly;
}
public float getRad()
{
return PlanarShape.returnRadius();
}
public float getLength()
{
return vertlength;
}
}
#SuppressWarnings("serial")
class ExtendedFile extends File
{
public ExtendedFile(String pathname) {
super(pathname);
}
public String[] readLines()
{
try
{
FileReader fr = new FileReader(this);
BufferedReader br = new BufferedReader(fr);
Object[] buffer = br.lines().toArray();
String[] lines = Arrays.copyOf(buffer, buffer.length, String[].class);
fr.close(); br.close();
return lines ;
}
catch (IOException e)
{
return new String[0];
}
}
}
class Point
{
float x;
float y;
Point(float ex, float why)
{
x = ex;
y = why;
}
public String toString()
{
return String.format("(%.2f , %.2f)", x, y);
}
public float getX()
{
return x;
}
public float getY()
{
return y;
}
public double dto()
{
return Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2));
}
}
class PlanarShape
{
List < Point > verticies = new ArrayList < Point > ();
float radius;
public void addRadius(float rad)
{
radius = rad;
}
public float returnRadius()
{
return radius;
}
public void addVerticy(Point toAdd)
{
verticies.add(toAdd);
}
public String toString()
{
String buffer = "";
for (int i = 0; i < verticies.size(); i++)
{
buffer += verticies.get(i).toString();
}
return buffer;
}
public Point[] getVerticies()
{
Object[] buffer = verticies.toArray();
return Arrays.copyOf(buffer, buffer.length, Point[].class);
}
public float polyarea;
public float circarea;
public float semiarea;
public float getArea(String type)
{
float area = 0;
switch(type)
{
case "POLY= ":
{
for(int n = 0; n < verticies.size(); n++)
{
area += verticies.get(n).getY()*verticies.get(n == verticies.size()-1?0:n+1).getX() - verticies.get(n).getX()*verticies.get(n == verticies.size()-1?0:n+1).getY();
}
if(area < 0)
{
area = -area;
}
area /= 2;
polyarea = area;
break;
}
case "CIRC= ":
{
float pi = 3.14159265359F;
float radius = returnRadius();
area = pi * radius * radius;
if(area < 0)
{
area = -area;
}
circarea = area;
break;
}
case "SEMI= ":
{
float x0 = verticies.get(0).getX();
float y0 = verticies.get(0).getY();
float x1 = verticies.get(1).getX();
float y1 = verticies.get(1).getY();
float y0y1;
if ((y0 - y1) < 0)
{
y0y1 = -(y0 - y1);
}
else
{
y0y1 = (y0 - y1);
}
float x0x1;
if ((x0 - x1) < 0)
{
x0x1 = -(x0 - x1);
}
else
{
x0x1 = (x0 - x1);
}
float x2 = x0 - y0y1;
float x3 = x0 + y0y1;
float y2 = y0 + x0x1;
float y3 = y0 - x0x1;
double diam = Math.sqrt((Math.pow((x2-x3), 2)) + ((Math.pow((y3 - y2), 2))));
float radius2 = ((float)diam)/2;
float pi = 3.14159265359F;
area = (pi * radius2 * radius2)/2;
if(area < 0)
{
area = -area;
}
break;
}
}
return area;
}
public float returnArea(String type)
{
switch(type)
{
case("POLY= "):
{
return polyarea;
}
case("CIRC= "):
{
return circarea;
}
case("SEMI= "):
{
return semiarea;
}
}
return 0;
}
}
class SemiCircle
{
List < Point > verticies = new ArrayList < Point > ();
public void addVerticy(Point toAdd)
{
verticies.add(toAdd);
}
public String toString()
{
String buffer = "";
for (int i = 0; i < verticies.size(); i++)
{
buffer += verticies.get(i).toString();
}
return buffer;
}
public Point[] getVerticies()
{
Object[] buffer = verticies.toArray();
return Arrays.copyOf(buffer, buffer.length, Point[].class);
}
public float getArea()
{
float area = 0;
for(int n = 0; n < verticies.size(); n++)
{
area += verticies.get(n).getY()*verticies.get(n == verticies.size()-1?0:n+1).getX() - verticies.get(n).getX()*verticies.get(n == verticies.size()-1?0:n+1).getY();
}
return area;
}
public double originDistance()
{
double distance;
distance = Math.sqrt((Math.pow((verticies.get(1).getX()),2))+(Math.pow((verticies.get(1).getY()),2)));
System.out.println(distance);
return distance;
}
}
class Polygon
{
List < Point > verticies = new ArrayList < Point > ();
public void addVerticy(Point toAdd)
{
verticies.add(toAdd);
}
public String toString()
{
String buffer = "";
for (int i = 0; i < verticies.size(); i++)
{
buffer += verticies.get(i).toString();
}
return buffer;
}
public Point[] getVerticies()
{
Object[] buffer = verticies.toArray();
return Arrays.copyOf(buffer, buffer.length, Point[].class);
}
public float getArea()
{
float area = 0;
for(int n = 0; n < verticies.size(); n++)
{
area += verticies.get(n).getY()*verticies.get(n == verticies.size()-1?0:n+1).getX() - verticies.get(n).getX()*verticies.get(n == verticies.size()-1?0:n+1).getY();
}
if(area < 0)
{
area = -area;
}
area /= 2;
return area;
}
public double originDistance()
{
double distance = Math.sqrt(Math.pow((verticies.get(1).getX()), 2)+Math.pow((verticies.get(1).getY()), 2));
System.out.println(distance);
return distance;
}
}
class Circle
{
List < Point > verticies = new ArrayList < Point > ();
public void addVerticy(Point toAdd)
{
verticies.add(toAdd);
}
public String toString()
{
String buffer = "";
for (int i = 0; i < verticies.size(); i++)
{
buffer += verticies.get(i).toString();
}
return buffer;
}
public Point[] getVerticies()
{
Object[] buffer = verticies.toArray();
return Arrays.copyOf(buffer, buffer.length, Point[].class);
}
public float getArea()
{
float pi = 3.14159265359F;
MyPolygons polygon = new MyPolygons();
float radius = polygon.getRad();
float area = 0;
area = pi * radius * radius;
if(area < 0)
{
area = -area;
}
return area;
}
public double originDistance()
{
double distance;
distance = Math.sqrt((Math.pow((verticies.get(0).getX()),2))+(Math.pow((verticies.get(0).getY()),2)));
System.out.println(distance);
return distance;
}
}
Edit: Removing the 'linkedlist.package' and pulling the .java and .text files, they still retain the same error when compiling and running
If you want to run files that are in a package, make sure all your java files that are part of the package are in a folder named the package name (i.e. linkedlist).
Then, in the directory outside your package folder, do:
javac linkedlist/*.java
java linkedlist.PA3
I am developing a game in LWJGL. I have an item pickup code to add an item to the player's inventory, but whenever I call it, it adds the item to the slot (x) and the slot after slot (x). (x meaning any random number) I was hoping I could have some help debugging it.
The class add method is being called in:
package geniushour.gameobject.entity;
import static org.lwjgl.input.Keyboard.KEY_A;
import static org.lwjgl.input.Keyboard.KEY_D;
import static org.lwjgl.input.Keyboard.KEY_P;
import static org.lwjgl.input.Keyboard.KEY_SPACE;
import static org.lwjgl.input.Keyboard.isKeyDown;
import java.util.ArrayList;
import java.util.Random;
import geniushour.engine.Physics;
import geniushour.engine.time.Delay;
import geniushour.engine.time.Time;
import geniushour.game.Game;
import geniushour.game.Util;
import geniushour.game.type.ArmorType;
import geniushour.game.type.ClawType;
import geniushour.game.type.EntityType;
import geniushour.gameobject.GameObject;
import geniushour.gameobject.StatObject;
import geniushour.gameobject.item.Backpack;
import geniushour.gameobject.item.Item;
public class Player extends StatObject {
private Delay delay;
private boolean collide = false;
private int facingDirection = 0;
private int firstFree = 0;
private Random damageRandom;
private final int NORTH = 0;
private final int EAST = 1;
private final int SOUTH = 2;
private final int WEST = 3;
public Player(float x, float y){
super(true,0,6);
init(x,y,ENTITY_SIZE,ENTITY_SIZE,0.25f,1f,.25f,EntityType.PLAYER_ID.getID());
deleteBackpack();
setClaw(ClawType.BASIC);
setArmorType(ArmorType.SKIN);
setStrength(1, claw);
delay = new Delay(500); delay.terminate();
}
public void update(){
ArrayList<GameObject> items = Game.rectCollide(x, y, x+ENTITY_SIZE, y+ENTITY_SIZE);
for(GameObject go : items){
if(go.getType() == EntityType.ITEM_ID.getID()){
go.remove();
inv.add ((Item)go);
}
}
ArrayList<GameObject> wall = Game.rectCollide(x, y, x+ENTITY_SIZE, y+ENTITY_SIZE);
for(GameObject go : wall){
if(go.getType() == EntityType.BLOCK_ID.getID()){
if(Physics.checkCollision(this, go) != null){
collide = true;
}
else if(Physics.checkCollision(this, go) == null){
collide = false;
}
}
if(collide){
if(this.facingDirection == WEST){
move(1,0);
collide = false;
}
else if(this.facingDirection == EAST){
move(-1,0);
collide = false;
}
}
}
if(getCurrentHealth() <= 0){
addHP(-getCurrentHealth());
deleteBackpack(); //TODO: Backpack temp or not?
}
for(int i = 0; i < inv.getLength(); i++){
if(inv.get( i ) instanceof Backpack){
ownBackpack();
inv.remove(i);
inv.setSlots(27);
}
}
}
outputData(true);
}
public void getInput(){
if(!collide){
if(isKeyDown(KEY_A)){
move(-1,0);
}
if(isKeyDown(KEY_D)){
move(1,0);
}
if(isKeyDown(KEY_SPACE) && delay.over()){
attack();
}
if(isKeyDown(KEY_P)){
}
}
}
private void move(int magX, int magY){
if(magX == 1){
facingDirection = EAST;
}
if(magX == -1){
facingDirection = WEST;
}
x += getSpeed(armor) * magX * Time.getDelta();
y += getSpeed(armor) * magY * Time.getDelta();
}
private void attack(){
//Find GameObjects in Attack Range
ArrayList<GameObject> obj = new ArrayList<GameObject>();
switch(facingDirection){
case NORTH: obj = Game.rectCollide(x, y, x + ENTITY_SIZE, y + getCloseAttackRange());
break;
case EAST: obj = Game.rectCollide(x, y, x + getCloseAttackRange(), y + ENTITY_SIZE);
break;
case SOUTH: obj = Game.rectCollide(x, y - getCloseAttackRange() + ENTITY_SIZE, x + ENTITY_SIZE, y);
break;
case WEST: obj = Game.rectCollide(x - getCloseAttackRange() + ENTITY_SIZE, y, x, y + ENTITY_SIZE);
break;
}
//Find which GOs are Enemy Type
ArrayList<Enemy> enemies = new ArrayList<Enemy>();
for(GameObject go : obj){
if(go.getType() == EntityType.ENEMY_ID.getID()){
enemies.add((Enemy)go);
}
}
//Find closest existing enemy
if(enemies.size() > 0){
Enemy target = enemies.get(0);
if(enemies.size() > 1){
for(Enemy e : enemies){
if(Util.dist(x, y, e.getX(), e.getY()) < Util.dist(x, y, target.getX(), target.getY())){
target = e;
}
}
}
damageRandom = new Random();
double e = Math.pow(getStrength(claw), (Math.cbrt(damageRandom.nextInt(15)) + 1)) / (Math.sqrt(getStrength(claw) + 1));
target.damage((int) Math.round(e));
Util.writeLine(" : " + target.getCurrentHealth() + "/" + target.getMaxHP());
if(target.getCurrentHealth() <= 0){
addXP(100);
}
}
delay.start();
}
private void outputData(boolean ask){
if(ask){
for(int i = 0; i < inv.getLength(); i++){
Util.writeLine("Main Inv Slot "+i+": " + inv.get(i));
}
Util.writeLine("");
Util.writeLine("Backpack Owned: " + getBackpack());
Util.writeLine("");
Util.writeLine("Inventory Size: " + inv.getLength());
Util.writeLine("");
Util.writeLine("Health: "+getCurrentHealth());
Util.writeLine("");
Util.writeLine("End of Information Output");
}
}
}
The Class add() is defined in:
package geniushour.game.inventory;
import geniushour.game.Util;
import geniushour.gameobject.item.Item;
public class Inventory {
private Item[] items;
private int firstFree;
public Inventory(int size){
items = new Item[size];
firstFree = 0;
}
public boolean add(Item item){
for(int i = 0; i < items.length; i++){
if(get(i) == null){
firstFree = i;
break;
}
}
Util.writeLine(firstFree);
if(add(item, firstFree)){
firstFree++;
if(firstFree > items.length){
firstFree = items.length;
}
return true;
}
return false;
}
public boolean add(Item item, int index){
if(items[index] == null && index <= items.length){ // != or == ?
items[index] = item;
return true;
}
else{
return false;
}
}
public Item get(int index){
return items[index];
}
public void remove(int index){
items[index] = null;
if(index < firstFree){
firstFree = index;
}
if(firstFree < 0){
firstFree = 0;
}
}
public void remove(Item item){
for(int i = 0; i < items.length; i++){
if(items[i] == item){
remove(i);
return;
}
}
}
public Item[] getItemList(){
return items;
}
public int getLength(){
return items.length;
}
public void setSlots(int amt){
Item[] temp = new Item[items.length];
for(int i = 0; i < items.length; i++){
temp[i] = items[i];
}
items = new Item[amt];
for(int i = 0; i < temp.length; i++){
items[i] = temp[i];
}
temp = new Item[items.length];
}
}
I'm trying to implement a rush hour solving algorithm using breadth first search to traverse a graph of the different paths, stopping when a solution has been found.
After numerous tests, I've come across a problem I have no idea how to solve. When there is a solution, the algorithm works very well, but when none can be found, it just endlessly cycles because it recreates "nodes" that contain the same information as older ones, instead of returning towards the older ones if the information is the same. How would I be able to make it stop when it figures out there are no more possibilities?
Here are the classes I am using for the solver:
This is the main class RushHour, the one I run.
package rush.hour;
import java.io.*;
import java.util.List;
import java.util.ArrayList;
public class RushHour
{
public static void main(String[] args)
{
String fileName = "Parking.txt";
String line;
int lineNumber = 0;
int numOfCars;
List<Car> carsList = new ArrayList<>();
try
{
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
lineNumber += 1;
// System.out.println(lineNumber);
System.out.println(line);
if (lineNumber == 15)
numOfCars = Integer.parseInt(
line.substring(line.length() - 1)) + 1;
if (lineNumber >= 17)
{
String[] splitLine = line.split(":");
char[] coordinates = splitLine[1].toCharArray();
int a = coordinates[3] - 48;
int b = coordinates[5] - 48;
int c = coordinates[10] - 48;
int d = coordinates[12] - 48;
Car car = new Car(lineNumber - 17, a, b, c, d);
carsList.add(car);
}
}
Parking parking = new Parking(carsList);
Graph graph = new Graph(parking);
List<Parking> sol = graph.bfs();
System.out.println("\n------------- Solution -------------");
for (Parking sols: sol)
{ // L = Left, D = Down, R = Right, U = Up
System.out.println(sols);
}
}
catch(FileNotFoundException ex)
{ex.printStackTrace();}
catch(IOException ex)
{ex.printStackTrace();}
}
}
And this is the "graph" that uses the adapted BFS
package rush.hour;
import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;
import java.util.Queue;
public class Graph
{
Parking posDepart;
public Graph(Parking parking)
{
posDepart = parking;
}
public List<Parking> bfs()
{
List<Parking> res = new ArrayList<>();
Queue<Parking> queue = new LinkedList<>();
queue.add(posDepart);
while (!queue.isEmpty())
{
Parking next = queue.remove();
if (next.isFinal())
{
res.add(next);
return next.getPath();
}
next.setChildren();
for (Parking child : next.children) {
queue.add(child);
}
}
return res;
}
}
This is the Graph's "node", it represents the disposition of the cars on the board
package rush.hour;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
public class Parking
{
Parking father = null;
List<Car> carsList = new ArrayList<>();
boolean visited = false;
List<Parking> children = new ArrayList<>();
List<Character> move = new ArrayList<>();
public Parking(List<Car> list)
{
for (Car car: list)
carsList.add(car.clone());
}
public Parking(Parking vader,List<Character> mov)
{
for (Car car: vader.carsList)
carsList.add(car.clone());
father = vader;
move = mov;
}
public void getNextParkings(List<List<Character>> moves)
{
children.clear();
for (int i = 0; i < moves.size(); ++i)
{
List<Character> info = moves.get(i);
Parking nextParking = new Parking(this, info);
nextParking.carsList.get(info.get(0) - 48).move(info.get(1));
children.add(nextParking);
}
}
#Override
public String toString()
{
String res = "";
if (!move.isEmpty())
{
res += "Move made to reach this parking:";
res += move;
res += "\n";
}
for (Car car : carsList)
res += car.toString();
return res;
}
public boolean isFinal()
{
return carsList.get(0).isFinal();
}
public void setChildren()
{
if (children.isEmpty())
{
List<List<Character>> moves = getPossibleMoves();
getNextParkings(moves);
}
}
public List<List<Character>> getPossibleMoves()
{
List<List<Character>> res = new ArrayList<>();
List<List<Character>> moves;
for (Car car : carsList)
{
moves = car.getPossibleMoves();
for (int i = 0; i < moves.size(); ++i)
{
List<Character> move = moves.get(i);
if (!hasNeighbour(move.get(0),
move.get(1) - 48, move.get(2) - 48))
{
List<Character> foo = new ArrayList<>(2);
foo.add(car.getNumber());
foo.add(move.get(0));
res.add(foo);
}
}
}
return res;
}
public boolean hasNeighbour(char direction, int x, int y)
{
for (Car car : carsList)
{
if (direction == 'U')
if ((car.getX1() == x - 1 && car.getY1() == y) ||
(car.getX2() == x - 1 && car.getY2() == y))
return true;
if (direction == 'D')
if ((car.getX1() == x + 1 && car.getY1() == y) ||
(car.getX2() == x + 1 && car.getY2() == y))
return true;
if (direction == 'L')
if ((car.getX1() == x && car.getY1() == y - 1) ||
(car.getX2() == x && car.getY2() == y - 1))
return true;
if (direction == 'R')
if ((car.getX1() == x && car.getY1() == y + 1) ||
(car.getX2() == x && car.getY2() == y + 1))
return true;
}
return false;
}
public List<Parking> getPath()
{
Parking temp_father;
List<Parking> path = new LinkedList<>();
path.add(this);
temp_father = this.father;
while (temp_father != null)
{
path.add(0, temp_father);
temp_father = temp_father.father;
}
return path;
}
}
And finally the Car class, which probably isn't very important to the problem but still
package rush.hour;
import java.util.List;
import java.util.ArrayList;
public class Car
{
char orientation;
int carNumber;
int x1;
int x2;
int y1;
int y2;
#Override
public String toString()
{
return "Car n° : " + (carNumber) + " : [(" + (x1) + ", " + y1 + ')' +
" (" + (x2) + ", " + y2 + ")]" + "\n";
}
public Car clone()
{
Car c = new Car(carNumber, x1, y1, x2, y2);
return c;
}
public Car(int n, int a, int b, int c, int d)
{
carNumber = n;
if (a <= c)
{
x1 = a;
x2 = c;
}
else
{
x1 = c;
x2 = a;
}
if (b <= d)
{
y1 = b;
y2 = d;
}
else
{
y1 = d;
y2 = b;
}
if (x1 == x2)
orientation = 'H';
else
orientation = 'V';
}
public char getNumber()
{
return Integer.toString(carNumber).charAt(0);
}
public int getX1()
{
return x1;
}
public int getX2()
{
return x2;
}
public int getY1()
{
return y1;
}
public int getY2()
{
return y2;
}
public void move(char direction)
{
if (direction == 'U')
{
--x1;
--x2;
}
if (direction == 'D')
{
++x1;
++x2;
}
if (direction == 'L')
{
--y1;
--y2;
}
if (direction == 'R')
{
++y1;
++y2;
}
}
public boolean isFinal()
{
return y2 == 4 && carNumber == 0;
}
public List<List<Character>> getPossibleMoves()
{
List<List<Character>> res = new ArrayList<>();
if (orientation == 'H')
{
if (y1 != 0)
{
List<Character> foo = new ArrayList<>(2);
foo.add('L');
foo.add(Integer.toString(x1).charAt(0));
foo.add(Integer.toString(y1).charAt(0));
res.add(foo);
}
if (y2 != 4)
{
List<Character> foo = new ArrayList<>(2);
foo.add('R');
foo.add(Integer.toString(x2).charAt(0));
foo.add(Integer.toString(y2).charAt(0));
res.add(foo);
}
}
else
{
if (x1 != 0)
{
List<Character> foo = new ArrayList<>(2);
foo.add('U');
foo.add(Integer.toString(x1).charAt(0));
foo.add(Integer.toString(y1).charAt(0));
res.add(foo);
}
if (x2 != 4)
{
List<Character> foo = new ArrayList<>(2);
foo.add('D');
foo.add(Integer.toString(x2).charAt(0));
foo.add(Integer.toString(y2).charAt(0));
res.add(foo);
}
}
return res;
}
}
Excuse me if I've made some blatant styling/coding mistakes, I am more used to coding in Python/C++. Would there be a way to make this work?
You need to use some type of data structure to keep track of paths already traversed. A hash table would be ideal and would provide a worst case of O(n) depending upon implementation. Not very familiar with Java but in C++ I would use std::unordered_map with the first field being a state of your board and the second being the number of moves at that point. I have implemented this algorithm before, and that's the approach I took. Incredibly fast.
I have a hard time to figure out one error after assigning
int evaluationNode = getMinDistances();
settled.add(evaluationNode);
checkNeighbours(evaluationNode);
The error show type mismatch: connot convert from Node to int. I am appreciated if anyone can help me this. Below is a complete code.
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.Set;
import java.util.Comparator;
public class DijkstraPriorityQueue
{
private int distances[];
private Set<Integer> settled;
private PriorityQueue<Node> priorityQueue;
private int number_of_nodes;
private int adjacencyMatrix[][];
public DijkstraPriorityQueue(int number_of_nodes)
{
this.number_of_nodes = number_of_nodes;
distances = new int[number_of_nodes + 1];
settled = new HashSet<Integer>();
priorityQueue = new PriorityQueue<Node>(number_of_nodes,new Node());
adjacencyMatrix = new int[number_of_nodes + 1][number_of_nodes + 1];
}
public void dijkstra_algorithm(int adjacency_matrix[][], int source)
{
int evaluationNode;
for (int i = 1; i <= number_of_nodes; i++)
for (int j = 1; j <= number_of_nodes; j++)
adjacencyMatrix[i][j] = adjacency_matrix[i][j];
for (int i = 1; i <= number_of_nodes; i++)
{
distances[i] = Integer.MAX_VALUE;
}
priorityQueue.add(new Node(source, 0));
distances[source] = 0;
while (!priorityQueue.isEmpty())
{
evaluationNode = getMinDistances();
settled.add(evaluationNode);
evaluateNeighbours(evaluationNode);
}
}
private int getMinDistances()
{
int node = priorityQueue.remove();
return node;
}
private void checkNeighbours(int evaluationNode)
{
int edgeDistance = -1;
int newDistance = -1;
for (int destinationNode = 1; destinationNode <= number_of_nodes; destinationNode++)
{
if (!settled.contains(destinationNode))
{
if (adjacencyMatrix[evaluationNode][destinationNode] != Integer.MAX_VALUE)
{
edgeDistance = adjacencyMatrix[evaluationNode][destinationNode];
newDistance = distances[evaluationNode] + edgeDistance;
if (newDistance < distances[destinationNode])
{
distances[destinationNode] = newDistance;
}
priorityQueue.add(new Node(destinationNode,distances[destinationNode]));
}
}
}
}
public static void main(String[] args)
{
int adjacency_matrix[][];
int number_of_vertices;
int source = 0;
Scanner scan = new Scanner(System.in);
try
{
System.out.println("Enter the number of vertices");
number_of_vertices = scan.nextInt();
adjacency_matrix = new int[number_of_vertices + 1][number_of_vertices + 1];
System.out.println("Enter the Weighted Matrix for the graph");
for (int i = 1; i <= number_of_vertices; i++)
{
for (int j = 1; j <= number_of_vertices; j++)
{
adjacency_matrix[i][j] = scan.nextInt();
if (i == j)
{
adjacency_matrix[i][j] = 0;
continue;
}
if (adjacency_matrix[i][j] == 0)
{
adjacency_matrix[i][j] = Integer.MAX_VALUE;
}
}
}
System.out.println("Enter the source ");
source = scan.nextInt();
DijkstraPriorityQueue dijkstrasPriorityQueue = new DijkstraPriorityQueue(number_of_vertices);
dijkstrasPriorityQueue.dijkstra_algorithm(adjacency_matrix, source);
System.out.println("The Shorted Path to all nodes are ");
for (int i = 1; i <= dijkstrasPriorityQueue.distances.length - 1; i++)
{
System.out.println(source + " to " + i + " is " + dijkstrasPriorityQueue.distances[i]);
}
} catch (InputMismatchException inputMismatch)
{
System.out.println("Wrong Input Format");
}
scan.close();
}
}
class Node implements Comparator<Node>
{
public int node;
public int cost;
public Node()
{
}
public Node(int node, int cost)
{
this.node = node;
this.cost = cost;
}
#Override
public int compare(Node node1, Node node2)
{
if (node1.cost < node2.cost)
return -1;
if (node1.cost > node2.cost)
return 1;
return 0;
}
}
In the getMinDistances method you are calling
int node = priorityQueue.remove();
But the priority queue contains Node objects, and not int values.
Maybe you wanted something like
private int getMinDistances()
{
Node node = priorityQueue.remove();
return node.getDistance();
}
but this is something that can not be answered by the debugging cloud (aka stackoverflow).
In order to use the PriorityQueue, you have to implement MinPQ extending the PriorityQueue and you'll also need a Comparator between nodes that returns the Node with a minimum distance in the MinPQ.
Take a look here for more details.
I am trying to implement Karger's min cut algorithm but I am unable to get the correct answer. Can someone please have a look at my code and help me figure out what I am doing wrong? Would really appreciate the help.
package a3;
import java.util.*;
import java.io.*;
public class Graph {
private ArrayList<Integer>[] adjList;
private int numOfVertices = 0;
private int numOfEdges = 0;
public Graph(String file) throws IOException {
FileInputStream wordsFile = new FileInputStream(file);
BufferedReader br = new BufferedReader(new InputStreamReader(wordsFile));
adjList = (ArrayList<Integer>[]) new ArrayList[201];
for (int i = 1; i < 201; i++) {
adjList[i] = new ArrayList<Integer>();
}
while (true) {
String s = br.readLine();
if (s == null)
break;
String[] tokens = s.split("\t");
int vertex = Integer.parseInt(tokens[0]);
this.numOfVertices++;
for (int i = 1; i < tokens.length; i++) {
Integer edge = Integer.parseInt(tokens[i]);
addEdge(vertex, edge);
this.numOfEdges++;
}
}
}
public void addEdge(int v, int w) {
adjList[v].add(w);
//this.numOfEdges++;
}
public ArrayList<Integer> getNeighbors(Integer v) {
return adjList[v];
}
public boolean hasEdge(Integer i, Integer j) {
return adjList[i].contains(j);
}
public boolean removeEdge(Integer i, Integer j) {
if (hasEdge(i, j)) {
adjList[i].remove(j);
adjList[j].remove(i);
this.numOfEdges -= 2;
return true;
}
return false;
}
public int getRandomVertex(){
Random rand = new Random();
return (rand.nextInt(this.getNumOfVertices()) + 1);
}
//Returns an array which consists of vertices connected by chosen edge
public int[] getRandomEdge(){
int arr[] = new int[2];
arr[0] = this.getRandomVertex();
while (adjList[arr[0]].size() == 0) {
arr[0] = this.getRandomVertex();
}
Random rand = new Random();
arr[1] = adjList[arr[0]].get(rand.nextInt(adjList[arr[0]].size()));
return arr;
}
//Algorithm for min cut
public int minCut() {
while (this.getNumOfVertices() > 2) {
int[] edge = this.getRandomEdge();
this.removeEdge(edge[0], edge[1]);
//Adding edges of second vertex to first vertex
for (Integer v: adjList[edge[1]]) {
if (!adjList[edge[0]].contains(v)) {
addEdge(edge[0], v);
}
}
//Removing edges of second vertex
for (Iterator<Integer> it = adjList[edge[1]].iterator(); it.hasNext();) {
Integer v = it.next();
it.remove();
this.numOfEdges--;
}
//Removing self-loops
for (Iterator<Integer> it = adjList[edge[0]].iterator(); it.hasNext();) {
Integer v = it.next();
if (v == edge[0])
it.remove();
//this.numOfEdges--;
}
this.numOfVertices--;
}
return this.numOfEdges;
}
public int getNumOfVertices() {
return this.numOfVertices;
}
public int getNumOfEdges() {
return (this.numOfEdges) / 2;
}
public String toString() {
String s = "";
for (int v = 1; v < 201; v++) {
s += v + ": ";
for (int e : adjList[v]) {
s += e + "-> ";
}
s += null + "\n";
//s += "\n";
}
return s;
}
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
int min = 1000;
//Graph test = new Graph("C:\\Users\\UE\\Desktop\\kargerMinCut.txt");
for (int i = 0; i < 10; i++) {
Graph test = new Graph("C:\\Users\\UE\\Desktop\\kargerMinCut.txt");
int currMin = test.minCut();
min = Math.min( min, currMin );
}
System.out.println(min);
}
}