I have used Libgdx to generate a dungeon out of keyboard characters. I have decided to print out the array as a text file.
However this is what I got:
Furthermore, It isn't consistent
I don't get what is wrong?
I checked over my algorithm and didn't find anything wrong.
Here is my code:
public class test1 extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
int X = 50;
int Y = 25;
////////// # wall
////////// . ground
char[][][] mapChars = new char[1000][1000][1000];
private void genDung() {
int clearance = 4;
for (int i = 0; i < Y; i++) {
for (int j = 0; j <= X; j++) {
if(j == X)
mapChars[0][i][j] = '\n';
else
mapChars[0][i][j] = '#';
}
}
int roomCount = MathUtils.random(2, 2);
int[] roomPosX = new int[roomCount];
int[] roomPosY = new int[roomCount];
int[] roomCenterPosX = new int[roomCount];
int[] roomCenterPosY = new int[roomCount];
int[] roomSizeX = new int[roomCount];
int[] roomSizeY = new int[roomCount];
for (int i = 0; i < roomCount; i++) {
int attempts = 0;
while(true) {
boolean rePosition = false;
roomPosX[i] = MathUtils.random(1, X-1);
roomPosY[i] = MathUtils.random(1, Y-1);
roomSizeX[i] = MathUtils.random(2, 12);
roomSizeY[i] = MathUtils.random(2, 8);
for(int j = 0; j <= i; j++) {
if(i != j) {
if(roomPosX[i] >= roomPosX[j] && roomPosX[i] <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if(roomPosY[i] >= roomPosY[j] && roomPosY[i] <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]) >= roomPosX[j] && (roomPosX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]+roomSizeY[i]) >= roomPosY[j] && (roomPosY[i]+roomSizeY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
if((roomPosX[i]+roomSizeX[i]) >= roomPosX[j] && (roomPosX[i]+roomSizeX[i]) <= (roomPosX[j] + roomSizeX[j] + clearance)) {
if((roomPosY[i]) >= roomPosY[j] && (roomPosY[i]) <= (roomPosY[j] + roomSizeY[j] + clearance)) {
rePosition = true;
break;
}
}
}
else if(roomPosX[j] + roomSizeX[j] >= X-1){
rePosition = true;
}
else if(roomPosY[j] + roomSizeY[j] >= Y-1){
rePosition = true;
}
}
attempts++;
if(attempts >= 10000) break;
if(!rePosition) break;
}
}
for(int r = 0; r < roomCount; r++) {
for (int a = roomPosX[r]; a <= (roomPosX[r] + roomSizeX[r]); a++) {
for (int b = roomPosY[r]; b <= (roomPosY[r] + roomSizeY[r]); b++) {
mapChars[0][b][a] = '.';
}
}
}
Gdx.app.log("roomCount", String.valueOf(roomCount)+"\n\n\n");
for(int i =0; i< roomCount; i++) {
roomCenterPosX[i] = roomPosX[i] + roomSizeX[i]/2;
roomCenterPosY[i] = roomPosY[i] + roomSizeY[i]/2;
Gdx.app.log("room", String.valueOf(i)+"\n");
Gdx.app.log("roomPosX", String.valueOf(roomPosX[i]));
Gdx.app.log("roomPosY", String.valueOf(roomPosY[i]));
Gdx.app.log("roomSizeX", String.valueOf(roomSizeX[i]));
Gdx.app.log("roomSizeY", String.valueOf(roomSizeY[i])+"\n");
Gdx.app.log("RoomCenterPosX", String.valueOf(roomCenterPosX[i]));
Gdx.app.log("RoomCenterPosY", String.valueOf(roomCenterPosY[i])+"\n\n");
}
int difference = X;
int[] roomNum = new int[2];
for(int i = 0; i < roomCount; i++) {
for(int j = 0; j < roomCount; j++) {
if(i != j) {
if(abs(roomCenterPosX[i] - roomCenterPosX[j]) < difference) {
difference = abs(roomCenterPosX[i] - roomCenterPosX[j]);
roomNum[0] = i;
roomNum[1] = j;
}
}
}
}
Gdx.app.log("FarthestRooms", String.valueOf(roomNum[0]));
Gdx.app.log("FarthestRooms", String.valueOf(roomNum[1]));
int differenceX = X;
int differenceY = Y;
int[] connectRooms = new int[2];
// int[] roomsConnected = new int[roomCount];
connectRooms[0] = MathUtils.random(0, roomCount - 1);
// roomsConnected[0] = connectRooms[0];
int count;
for(int i = 0; i < roomCount-1; i++) {
int j;
while(true) {
connectRooms[1] = MathUtils.random(0, roomCount - 1);
/* while (true) {
connectRooms[1] = MathUtils.random(0, roomCount - 1);
count = 0;
for (j = 0; j < i; j++) {
if (connectRooms[1] != roomsConnected[j] && connectRooms[0] != roomsConnected[j]){
count++;
}
}
if(count >= i-2)
break;
}*/
if(connectRooms[0] != connectRooms[1])
break;
}
// roomsConnected[i+1] = connectRooms[1];
differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
differenceX *= -1;
if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
differenceY *= -1;
int k;
try {
if (differenceX > 0) {
for (k = 0; k < differenceX; k++) {
mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
}
} else if (differenceX < 0) {
for (k = 0; k > differenceX; k--) {
mapChars[0][roomCenterPosY[i]][roomCenterPosX[i] + k] = '.';
}
} else k = 0;
if (differenceY < 0) {
for (int z = 0; z > differenceY; z--) {
mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
}
} else if (differenceY > 0) {
for (int z = 0; z < differenceY; z++) {
mapChars[0][roomCenterPosY[i] + z][roomCenterPosX[i] + k] = '.';
}
} else {
}
}
catch (ArrayIndexOutOfBoundsException e) {
Gdx.app.log("Non Fatal Exception", String.valueOf(e));
}
Gdx.app.log("Connect", String.valueOf(connectRooms[0]));
Gdx.app.log("Connect", String.valueOf(connectRooms[1]));
Gdx.app.log("DifferenceX", String.valueOf(differenceX));
Gdx.app.log("DifferenceY", String.valueOf(differenceY)+"\n");
}
for(int q = 0; q < Y; q++) {
mapChars[0][q][X] = '\n';
}
for(int w = 0; w < Y; w++) {
mapChars[0][w][X-1] = '#';
}
for(int e = 0; e < Y; e++) {
mapChars[0][Y-1][e] = '#';
}
}
private void export() {
if(Gdx.files.isLocalStorageAvailable()) {
FileHandle fileHandle = Gdx.files.local("map.txt");
if(Gdx.files.local("map.txt").exists())
fileHandle.writeString("", false);
for(int i = 0; i<= Y; i++) {
for (int j = 0; j <= X; j++) {
fileHandle.writeString(""+mapChars[0][i][j] , true);
}
}
}
}
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
// genMap();
// for(int i = 0; i< 4; i++)
// refineMap();
genDung();
export();
}
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
if(Gdx.input.isTouched()) {
// genMap();
// for(int i = 0; i< 4; i++)
// refineMap();
genDung();
export();
}
}
}
I want the two rooms to connect properly every time.
As you can see, one of the time, the rooms connected
The other time the rooms don't connect.
Thanks in advance
The whole thing can be simplified and definitely needs refactoring. Regarding the 2 room connection - check this piece carefully
differenceX = roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]];
differenceY = roomCenterPosY[connectRooms[0]] - roomCenterPosY[connectRooms[1]];
if(roomCenterPosX[connectRooms[0]] < roomCenterPosX[connectRooms[1]])
differenceX *= -1;
if(roomCenterPosY[connectRooms[0]] < roomCenterPosY[connectRooms[1]])
differenceY *= -1;
As #kiheru pointed out it is equivalent to Math.abs(roomCenterPosX[connectRooms[0]] - roomCenterPosX[connectRooms[1]]) (same for Y). So you always "dig" to right and down, never up or left.
Drop that invertion and have fun with the rest of your algorithm :)
Related
The userGuess[y, x] gets compared to ship1[][] but only updates the board[][] at the matching index with "!" when I enter a user guess that equals (ship1[2][0], ship1[2][1]).
In other words, I feed updateBoard() the int[] userGuess, updateBoard loops through the int[][] ship1 and compares userGuess[0] to ship1[0][0] and userGuess[1] to ship1[0][1]...ship1[2][0], ship1[2][1], looking to see if they match, but the only match I am getting is if I enter a userGuess that equals the values at (ship1[2][0], ship1[2][1]).
Does anyone see what I have done wrong?
package assignment_8;
import java.util.Scanner;
public class Battleship {
private String[][] board = new String[8][8];
private int[][] ship1 = new int[3][2];
private int[][] ship2 = new int[4][2];
private int counter;
Battleship() {
}
public void makeBoard() {
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[i].length; j++) {
board[i][j] = "| ";
board[i][7] = "| |";
}
}
}
public void makeShips() {
int ship1Y = (int)Math.floor(Math.random() * 7);
int ship1X = (int)Math.floor(Math.random() * 7);
int ship2Y = (int)Math.floor(Math.random() * 7);
int ship2X = (int)Math.floor(Math.random() * 7);
int coinToss = (int)Math.floor(Math.random() * 2) + 1;
if(coinToss == 1) {
if(ship1X >= 5) {
ship1X = 4;
}
for(int i = 0; i < ship1.length; i++) {
ship1[i][0] = ship1Y;
ship1[i][1] = ship1X + i;
}
if(ship2Y >= 4) {
ship2Y = 3;
}
for(int i = 0; i < ship2.length; i++) {
ship2[i][0] = ship2Y + i;
ship2[i][1] = ship2X;
}
} else {
if(ship1Y >= 5) {
ship1Y = 4;
}
for(int i = 0; i < ship1.length; i++) {
ship1[i][0] = ship1Y + i;
ship1[i][1] = ship1X;
}
if(ship2X >= 4) {
ship2X = 3;
}
for(int i = 0; i < ship2.length; i++) {
ship2[i][0] = ship2Y;
ship2[i][1] = ship2X + i;
}
}
}
public String[][] getBoard() {
return board;
}
public int[][] getShip1() {
return ship1;
}
public int[][] getShip2() {
return ship2;
}
public int getCounter() {
return counter;
}
public void updateBoard(int[] userInput) {
for(int i = 0; i < ship1.length; i++) {
if(ship1[i][0] == userInput[0] && ship1[i][1] == userInput[1] && board[userInput[0]][userInput[1]] == "| ") {
counter++;
} else if (ship1[i][0] == userInput[0] && ship1[i][1] == userInput[1] && board[userInput[0]][userInput[1]] == "| |") {
counter++;
}
if(ship1[i][0] == userInput[0] && ship1[i][1] == userInput[1]) {
board[userInput[0]][userInput[1]] = "|!";
if(userInput[1] == 7) {
board[userInput[0]][userInput[1]] = "|!|";
}
} else {
board[userInput[0]][userInput[1]] = "|X";
if(userInput[1] == 7) {
board[userInput[0]][userInput[1]] = "|X|";
}
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Battleship bs = new Battleship();
bs.makeBoard();
bs.makeShips();
int[][] ship1 = bs.getShip1();
//int[][] ship2 = bs.getShip2();
for(int i = 0; i < ship1.length; i++) {
System.out.println("[" + ship1[i][0] + "][" + ship1[i][1] + "]");
}
System.out.println();
/*for(int i = 0; i < ship2.length; i++) {
System.out.println("[" + ship2[i][0] + "][" + ship2[i][1] + "]");
}*/
System.out.println();
int[] userGuess = new int[2];
int counter = 0;
String[][] board = bs.getBoard();
do {
for(int i = 0; i < board.length; i++) {
for(int j = 0; j < board[i].length; j++) {
System.out.print(board[i][j]);
}
System.out.println();
}
counter = bs.getCounter();
System.out.println("Counter = " + counter);
System.out.print("Enter Y coordinate (0 - 7): ");
userGuess[0] = sc.nextInt();
System.out.print("Enter X coordinate(0 - 7): ");
userGuess[1] = sc.nextInt();
bs.updateBoard(userGuess);
System.out.println();
} while(counter < 8);
}
}
The issue is with the following condition check:
if(ship1[i][0] == userInput[0] && ship1[i][1] == userInput[1]) {
board[userInput[0]][userInput[1]] = "|!";
if(userInput[1] == 7) {
board[userInput[0]][userInput[1]] = "|!|";
}
} else {
board[userInput[0]][userInput[1]] = "|X";
if(userInput[1] == 7) {
board[userInput[0]][userInput[1]] = "|X|";
}
}
If the user gives co-ordinates that match with ship1[0][0] and ship[0][1], it assigns ! to it but the loop continues and next two ship1 array values won't match thereby resetting it to X
The fix is to break out of the loop when the match is found.
if(ship1[i][0] == userInput[0] && ship1[i][1] == userInput[1]) {
board[userInput[0]][userInput[1]] = "|!";
if(userInput[1] == 7) {
board[userInput[0]][userInput[1]] = "|!|";
}
break; // that's it!
}
I have written adaptive merge sort in java. But as a mapreduce program there are three class . one is map , two is reducer and third is driver . I am not understaing how to convert this code to mapreduce so that I can run this on hadoop multi node cluster?
here is the code :
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class MainClass {
public static void main(String args[]) throws Exception {
MainClass mainClass = new MainClass();
MainClass.SortClass sortClass = mainClass.new SortClass();
sortClass.sortMainFunction();
}
public class Constant {
public static final int MAX = 10000;
public static final int max = 10000;
}
public class Values {
int st_index;
int ed_index;
boolean as_ds;
public Values(int st_index, int ed_index, boolean as_ds) {
this.st_index = st_index;
this.ed_index = ed_index;
this.as_ds = as_ds;
}
}
public class SortClass {
int[] a = new int[Constant.MAX];
int[] b = new int[Constant.MAX];
int index1 = 0;
int i = 0;
int numberOfItem = 0, first_ind, end_ind, tem, k, g, h;
boolean flag;
Values node[] = new Values[Constant.max];
int p, q, r, low, high, j;
void insert(int st_ind, int end_ind, boolean fl) {
node[index1] = new Values(st_ind, end_ind, fl);
index1++;
}
public void sortMainFunction() throws Exception {
addDataIntoArray();
first_ind = 0;
end_ind = 0;
flag = false;
tem = a[0];
k = 1;
while (true) {
while (true) {
if (k < i && tem >= a[k]) {
end_ind = k;
tem = a[k];
k++;
flag = true;
continue;
}
break;
}
if (flag) {
node[index1] = new Values(first_ind, end_ind, flag);
index1++;
first_ind = k;
end_ind = k;
if (k >= i) {
} else {
tem = a[k++];
}
}
while (true) {
if (k < i && tem <= a[k]) {
tem = a[k];
end_ind = k;
flag = false;
k++;
continue;
}
break;
}
if (!flag) {
insert(first_ind, end_ind, flag);
first_ind = end_ind = k;
if (k >= i) {
} else {
tem = a[k++];
}
}
if (end_ind == i)
break;
}
g = index1 - 1;
h = 0;
while (true) {
if (g / 2 <= 0) {
break;
}
g /= 2;
h++;
}
System.out.println(h);
h = (int) ((double) Math.log((double) index1 - 1) / (double) Math.log(2.0));
System.out.println(h);
p = 1;
for (q = 0; q <= h; q++, p *= 2) {
for (r = 0; r < index1; r++) {
if (2 * r * p + p >= index1)
break;
else {
low = 2 * p * r;
high = 2 * p * r + p;
k = node[low].st_index;
if (node[low].as_ds == false && node[high].as_ds == false) {
i = node[low].st_index;
j = node[high].st_index;
while (i <= node[low].ed_index && j <= node[high].ed_index) {
if (a[i] <= a[j])
b[k++] = a[i++];
else
b[k++] = a[j++];
}
if (i > node[low].ed_index)
while (j <= node[high].ed_index)
b[k++] = a[j++];
else
while (i <= node[low].ed_index)
b[k++] = a[i++];
} else if (node[low].as_ds == false && node[high].as_ds == true) {
i = node[low].st_index;
j = node[high].ed_index;
while (i <= node[low].ed_index && j >= node[high].st_index) {
if (a[i] <= a[j])
b[k++] = a[i++];
else
b[k++] = a[j--];
}
if (i > node[low].ed_index)
while (j >= node[high].st_index)
b[k++] = a[j--];
else
while (i <= node[low].ed_index)
b[k++] = a[i++];
} else if (node[low].as_ds == true && node[high].as_ds == false) {
i = node[low].ed_index;
j = node[high].st_index;
while (i >= node[low].st_index && j <= node[high].ed_index) {
if (a[i] <= a[j])
b[k++] = a[i--];
else
b[k++] = a[j++];
}
if (j > node[high].ed_index)
while (i >= node[low].st_index)
b[k++] = a[i--];
else
while (j <= node[high].ed_index)
b[k++] = a[j++];
} else if (node[low].as_ds == true && node[high].as_ds == true) {
i = node[low].ed_index;
j = node[high].ed_index;
while (i >= node[low].st_index && j >= node[high].st_index) {
if (a[i] <= a[j])
b[k++] = a[i--];
else
b[k++] = a[j--];
}
if (i < node[low].st_index)
while (j >= node[high].st_index)
b[k++] = a[j--];
else
while (i >= node[low].st_index)
b[k++] = a[i--];
}
for (k = node[low].st_index; k <= node[high].ed_index; k++)
a[k] = b[k];
node[low].ed_index = node[high].ed_index;
node[high].st_index = node[low].st_index;
node[low].as_ds = false;
node[high].as_ds = false;
}
}
}
BufferedWriter output = null;
File file = new File("output.txt");
output = new BufferedWriter(new FileWriter(file));
for (k = 0; k < numberOfItem; k++) {
String s = String.valueOf(a[k]);
output.write(s);
output.newLine();
}
if (output != null) {
output.close();
}
}
public void addDataInt
oArray() throws Exception {
Scanner scanner;
scanner = new Scanner(new File("input.txt"));
while (scanner.hasNextInt()) {
a[i] = scanner.nextInt();
i++;
numberOfItem++;
}
}
}
}
I'm taking each element as "sum", "first" and "sec". If (first + sec < sum) I'll make a hashset(tmp) of these 3 and put this hashset into a larger hashset(triangle) containing all tmp hashsets. This removes duplicate combinations of 3 numbers. Here's my code. It works but is there any better solution?
public void findTriangle(int[] a){
HashSet<HashSet<Integer>> triangle = new HashSet<HashSet<Integer>>();
HashSet<Integer> tmp;
for(int i=0;i<a.length;i++){
int sum=a[i];
for(int j=0;j<a.length;j++){
int first = a[j];
if(first!=sum){
for(int k=0;k<a.length;k++){
int sec = a[k];
if(sec!=first && sec!=sum && (first + sec < sum)){
tmp = new HashSet<Integer>();
tmp.add(first);
tmp.add(sec);
tmp.add(sum);
triangle.add(tmp);
}
}
}
}
}
for(HashSet<Integer> hs : triangle)
System.out.println(hs);
}
Sort the array and add the triplets to a list -
public static ArrayList<ArrayList<Integer>> get(int[] input) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if (input.length < 3) {
return result;
}
Arrays.sort(input);
for (int i = 0; i < input.length - 2; i++) {
int k = i + 2;
for (int j = i + 1; j < input.length; j++) {
while (k < input.length && input[i] + input[j] > input[k]) {
ArrayList<Integer> inner = new ArrayList<Integer>();
inner.add(input[i]);
inner.add(input[j]);
inner.add(input[k]);
result.add(inner);
k++;
}
}
}
return result;
}
Not so optimal works yet. I tried testing the above two solutions and they seemed to not work. May be i was missing something. Hence decided to post my tested solution here. It does not check for duplicates.
Condition to find a triangle: http://www.wikihow.com/Determine-if-Three-Side-Lengths-Are-a-Triangle
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Arrays;
class Triangle {
int a;
int b;
int c;
public Triangle(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
#Override
public String toString() {
return this.a + " " + this.b + " " + this.c;
}
}
public class FindTriangle {
public List<Triangle> findTriangle(List<Integer> points) {
List<Triangle> result = new ArrayList<Triangle>();
System.out.println("Entered");
for (int i = 0; i < points.size(); i++) {
int pt0 = points.get(i);
System.out.println("Entered i:" + i);
for (int j = i + 1; j < points.size() - 2; j++) {
int pt1 = points.get(j);
int pt2 = points.get(j + 1);
Boolean isTri = isTriangle(pt0, pt1, pt2);
if (isTri.equals(Boolean.TRUE)) {
Triangle t = new Triangle(pt0, pt1, pt2);
result.add(t);
}
}
for (int j = 0; j < (i - 1) && j > 0; j++) {
int pt1 = points.get(j);
int pt2 = points.get(j + 1);
Boolean isTri = isTriangle(pt0, pt1, pt2);
if (isTri.equals(Boolean.TRUE)) {
Triangle t = new Triangle(pt0, pt1, pt2);
result.add(t);
}
}
// final
int pt1, pt2;
if (i == 0) {
pt1 = points.get(i + 1);
pt2 = points.get(points.size() - 1);
} else if (i == points.size() - 1) {
pt1 = points.get(0);
pt2 = points.get(i - 1);
} else {
pt1 = points.get(i + 1);
pt2 = points.get(i - 1);
}
Boolean isTri = isTriangle(pt0, pt1, pt2);
if (isTri.equals(Boolean.TRUE)) {
Triangle t = new Triangle(pt0, pt1, pt2);
result.add(t);
}
}
return result;
}
public Boolean isTriangle(Integer pt1, Integer pt2, Integer pt3) {
System.out.println("Pt1, Pt2, Pt3: " + pt1 + ":" + pt2 + ":" + pt3);
if ((pt1 + pt2) > pt3 && (pt1 + pt3) > pt2 && (pt2 + pt3) > pt1) {
System.out.println("This is triangle");
return Boolean.TRUE;
}
return Boolean.FALSE;
}
public ArrayList<ArrayList<Integer>> getTri(int[] input) {
ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();
if (input.length < 3) {
return result;
}
Arrays.sort(input);
for (int i = 0; i < input.length - 2; i++) {
int k = i + 2;
for (int j = i + 1; j < input.length; j++) {
while (k < input.length && input[i] + input[j] > input[k]) {
ArrayList<Integer> inner = new ArrayList<Integer>();
inner.add(input[i]);
inner.add(input[j]);
inner.add(input[k]);
result.add(inner);
k++;
}
}
}
return result;
}
public void findTriangleW(int[] a) {
HashSet<HashSet<Integer>> triangle = new HashSet<HashSet<Integer>>();
HashSet<Integer> tmp;
for (int i = 0; i < a.length; i++) {
int sum = a[i];
for (int j = 0; j < a.length; j++) {
int first = a[j];
if (first != sum) {
for (int k = 0; k < a.length; k++) {
int sec = a[k];
if (sec != first && sec != sum && (first + sec < sum)) {
tmp = new HashSet<Integer>();
tmp.add(first);
tmp.add(sec);
tmp.add(sum);
triangle.add(tmp);
}
}
}
}
}
for (HashSet<Integer> hs : triangle)
System.out.println(hs);
}
public static void main(String[] args) {
FindTriangle f = new FindTriangle();
List<Integer> points = new ArrayList<Integer>();
points.add(1);
points.add(5);
points.add(10);
points.add(7);
System.out.println("Printing final results");
List<Triangle> result = f.findTriangle(points);
for (int i = 0; i < result.size(); i++) {
System.out.println(result.get(i).toString());
}
}
}
When I use a random matrix (class Determine), my program runs successfully in 1700 miliseconds. However, when I create a matrix by reading a file through a buffered reader (class Construct) my program experiences a logic error and enters and infinite loop.
Again, it works for a random matrix, but does not work for a 'real' matrix of the same size. I've checked my work and cannot find an error in my reading of the file. Does anyone know what may be causing this logic error? I will append my code with comments if it helps!
Update: OK the problem was from my own silly oversight (see my answer below). This did not occur with random data due to my 'haveIt' method and the probability of getting missing data. As such, my code has been updated to reflect this logic error and I will be happy to explain in detail how this code works if anyone asks:
import java.util.Random;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.*;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.BufferedReader;
class ValMax {
public static int valMax;
}
class Construct {
private static int colEnd;
private static int colStart;
private static int[] colSkip;
public static List<List<Integer>> rFile(String[] args){
if (args.length != 4) {
System.out.println("Format: FileName colStart colEnd colSkipped");
System.exit(0);
}
BufferedReader reader = null;
try {
List<List<Integer>> matrix = new ArrayList<List<Integer>>();
Construct.colEnd = Integer.parseInt(args[2]);
Construct.colStart = Integer.parseInt(args[1]);
String[] colSkipped = args[3].split(",");
Construct.colSkip = new int[colSkipped.length];
for (int x = 0; x < colSkipped.length; x++) {
Construct.colSkip[x] = Integer.parseInt(colSkipped[x]);
}
String line;
reader = new BufferedReader(new FileReader(new File(args[0])));
while ((line = reader.readLine()) != null) {
String[] tokens = line.split(",");
List<Integer> rows = new ArrayList<Integer>(colEnd - colStart + 1 - colSkip.length);
for (int x = 1; x <= tokens.length; x++) {
if (x >= colStart && x <= colEnd && contains(x, colSkip) == false) {
try {
Double.parseDouble(tokens[x - 1]);
} catch (NumberFormatException e3) {
break;
}
if (tokens[x - 1].equals("-999")) { //
rows.add(2);
} else {
rows.add(1);
}
}
}
if (rows.size() == colEnd - colStart + 1 - colSkip.length) {
matrix.add(rows);
}
}
System.out.println(matrix.size() + "\t" + matrix.get(0).size());
return matrix;
} catch (IOException e1) {
System.out.println("IOEXCEPTION!!");
System.exit(0);
} catch (NumberFormatException e2) {
System.out.println("NumberFormatException!!");
System.exit(0);
} finally {
try {
reader.close();
} catch (IOException e5) {
e5.printStackTrace();
}
}
return null;
}
private static boolean contains(int a, int[] colSkip) {
boolean bluejay = false;
for (int skip : colSkip) {
if (a == skip) {
bluejay = true;
}
}
return bluejay;
}
}
class Determine {
private static Integer gen(int a, int b, Random r) {
Integer rand = r.nextInt(a) + b;
return rand;
}
public static List<List<Integer>> rando() {
Random r = new Random();
int k = gen(1, 24, r), l = gen(1, 33, r); //userinput
List<List<Integer>> matrix = new ArrayList<List<Integer>>(k);
for (int x = 1; x <= k; x++) {
List<Integer> row = new ArrayList<Integer>(l);
for (int y = 1; y <= l; y++) {
double bias = Math.random();
if (bias > 0.7) {
row.add(2);
} else {
row.add(1);
}
}
matrix.add(row);
}
return matrix;
}
}
class Search {
public static void finalize(List<List<Integer>> matTan, boolean gumDrop, int minimum) {
final int A = matTan.size();
final int B = matTan.get(0).size();
boolean judge = true;
if (minimum > A && gumDrop == false || minimum > B && gumDrop == true) {
System.out.print("\nMinimum too high\n\n");
System.exit(0);
}
ValMax.valMax = 1; //userinput
int[] rows = new int[2 + A + B];
List<int[]> combination = new ArrayList<int[]>(100);
int threads = Runtime.getRuntime().availableProcessors();
ExecutorService service = Executors.newFixedThreadPool(threads);
List<List<int[]>> ranTime = new ArrayList<List<int[]>>(2 * threads);
for (int x = 0; x < 2 * threads; x++) {
List<int[]> jobs = new ArrayList<int[]>(90);
ranTime.add(jobs);
}
if (gumDrop == false) {
for (int x = 1; x <= minimum; x++) {
rows[x] = 1;
}
} else {
rows[1] = 1;
}
rows[A + 1] = 999;
int y = 0, z = 0;
System.out.println(threads);
while (rows[A + 1] == 999) {
y++;
int[] copy = Arrays.copyOf(rows, rows.length);
if (y == 91) {
z++;
y = 1;
if (z < 2* threads) {
ranTime.get(z).clear();
}
}
if (z == 2 * threads) {
processInputs(ranTime, combination, matTan, minimum, gumDrop, service);
z = 0;
ranTime.get(0).clear();
ranTime.get(0).add(copy);
} else {
ranTime.get(z).add(copy);
}
nextComb(A, rows);
}
if (ranTime.get(0).size() > 0) {
for (int x = 0; x < 2 * threads; x++) {
if (judge == false) {
ranTime.remove(x);
threads--;
x--;
}
if (ranTime.get(x).size() != 90 && judge == true) {
judge = false;
}
}
processInputs(ranTime, combination, matTan, minimum, gumDrop, service);
}
service.shutdown();
try {
service.awaitTermination(60, TimeUnit.SECONDS);
} catch (InterruptedException e6) {
System.out.print("Termination Error!");
}
developed(matTan, combination, gumDrop);
}
private static void processInputs(List<List<int[]>> ranTime, List<int[]> combination, List<List<Integer>> matTan, int minimum, boolean gumDrop, ExecutorService service) {
Collection<StringTask> collection = new ArrayList<StringTask>(ranTime.size());
for (List<int[]> jobs : ranTime) {
StringTask analysis = new StringTask(jobs, combination, matTan, minimum, gumDrop);
collection.add(analysis);
}
try {
List<Future<Integer>> futures = service.invokeAll(collection);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void developed(List<List<Integer>> matTan, List<int[]> combination, boolean gumDrop) {
System.out.print("\n\n\n");
for (int[] e : combination) {
if (e[0] == ValMax.valMax) { // == ValMax.valMax
Optimize10.prin(e);
List<List<Integer>> complete = Multi.reduct1(e, matTan);
if (gumDrop == true) {
System.out.println("Solution Matrix, transposed [above data works on column]");
Optimize10.prin(Multi.transpose(complete)); //The solution matrix, reorientated
} else {
System.out.println("Solution Matrix");
Optimize10.prin(complete); //The solution matrix, reorientated
}
}
}
}
private static void nextComb(int bounds, int[] rows) {
int kappas = findMax(rows);
if (rows[bounds] == 0) {
rows[kappas + 1] = 1;
rows[kappas] = 0;
} else {
int y = 1;
int x = bounds;
while (rows[x] == 1) {
rows[x] = 0;
y++;
x--;
}
kappas = findMax(rows);
if (kappas != -1) {
rows[kappas] = 0;
}
int z = kappas + 1;
while (y > 0) {
rows[z] = 1;
z++;
y--;
}
}
}
private static int findMax(int[] rows) {
int y = 0;
for (int x = rows.length - 1; x >= 0; x--) {
if (rows[x] == 1) {
return x;
}
}
return y;
}
}
class StringTask implements Callable<Integer> {
private List<List<Integer>> matTan;
private List<int[]> combination;
private List<int[]> jobs;
private boolean gumDrop;
private int minimum;
StringTask(List<int[]> a, List<int[]> b, List<List<Integer>> c, int d, boolean e) {
this.combination = b;
this.minimum = d;
this.gumDrop = e;
this.matTan = c;
this.jobs = a;
}
public Integer call() {
for (int[] e : jobs) {
int temp = Multi.reduct2(e, matTan, minimum, gumDrop);
if (temp > ValMax.valMax) { //ValMax.valMax //userinput
ValMax.valMax = e[0]; //userinput
combination.add(e);
System.out.print(ValMax.valMax + " ");
}
}
return null;
}
}
class Multi {
public static int[] inverse;
public static void halveIt(int[] col, List<List<Integer>> matCop) {
int size = matCop.size(), a = 0;
inverse = new int[size];
for (int x = 0; x < size; x++) {
for (int y = 0; y < matCop.get(0).size(); y++) {
if (col[y] == 1 && matCop.get(x).get(y) == 2) {
inverse[x + a] = 1;
matCop.remove(x);
size--;
x--;
a++;
break;
}
}
}
}
public static List<List<Integer>> reduct1(int[] row, List<List<Integer>> matCan) {
List<List<Integer>> matTan = new ArrayList<List<Integer>>(matCan);
int with = matTan.size(), high = inverse.length, a = 0;
final int B = matCan.get(0).size() - 1;
final int A = matCan.size();
for (int x = 0; x < A; x++) {
List<Integer> value = new ArrayList<Integer>(matCan.get(x));
matTan.set(x, value);
}
int y = 0, size = 0;
for (int x = 0; x < high; x++) {
if (x < with) {
if (row[x + a + 1] > 0) {
size = matTan.get(0).size();
for (y = 0; y < size; y++) {
if (matTan.get(x).get(y) == 2) {
for (int z = 0; z < with ; z++) {
matTan.get(z).remove(y);
}
size--;
y--;
}
}
} else {
matTan.remove(x);
with--;
high--;
x--;
a++;
}
}
}
return matTan;
}
public static int reduct2(int[] row, List<List<Integer>> matCan, int minimum, boolean gumDrop) {
int b = 0, c = 0, d = 0, e = 0, g = 0, high = inverse.length;
final int B = matCan.get(0).size() - 1;
final int A = matCan.size();
for (int x = 0; x < high; x++) {
if (x < A) {
if (row[x + 1] > 0) {
b++;
for (int y = 0; y < B + 1; y++) {
if (matCan.get(x).get(y) == 2 && row[2 + A + y] == 0) {
row[2 + A + y] = 1; // 1s mean that a column was deleted, 0 is kept.
d -= e;
} else if (row[2 + A + y] == 0) {
d++;
}
}
e++;
}
}
if (inverse[x] == 0 && x < high || gumDrop == true && x < high) {
if (row[x - c + 1] == 1) {
row[x - c + 1] = 1 + c + g;
g++;
} else {
g++;
}
} else {
c++;
}
}
if (d / b < minimum && gumDrop == true) {
row[0] = 0;
d = 0;
} else {
row[0] = d;
}
return d;
}
public static List<List<Integer>> transpose(List<List<Integer>> matTan) {
int d = matTan.get(0).size();
List<List<Integer>> matFlip = new ArrayList<List<Integer>>(d);
for (int y = 0; y < d; y++) {
List<Integer> row = new ArrayList<Integer>();
for (int x = 0; x < matTan.size(); x++) {
row.add(matTan.get(x).get(y));
}
matFlip.add(row);
}
return matFlip;
}
}
// ########## Main Method Start ##########
public class Optimize10 {
public static void main(String[] args) {
double startTime = System.nanoTime() / 1000000;
List<List<Integer>> matrix = Determine.rando();
// List<List<Integer>> matrix = Construct.rFile(args);
List<List<Integer>> matTan = contract(new int[matrix.get(0).size()], matrix);
int a = matTan.size(), b = matTan.get(0).size();
System.out.println(a + "\t" + b);
boolean gumDrop = false;
int minimum = 40; //userinput
BigInteger aNew = new BigInteger("2");
BigInteger bNew = new BigInteger("2");
aNew = aNew.pow(a);
bNew = bNew.pow(b);
for (int x = 1; x < minimum; x++) {
aNew = aNew.subtract(binomial(a, x));
}
if (aNew.compareTo(bNew) > 0) {
gumDrop = true;
matTan = Multi.transpose(matTan);
}
System.out.println(gumDrop);
prin(matrix);
prin(matTan);
Search.finalize(matTan, gumDrop, minimum);
double endTime = System.nanoTime() / 1000000;
double duration = (endTime - startTime);
System.out.println(duration);
}
// ########## MAIN METHOD END ############
private static BigInteger binomial(final int N, final int K) {
BigInteger ret = BigInteger.ONE;
for (int k = 0; k < K; k++) {
ret = ret.multiply(BigInteger.valueOf(N-k)).divide(BigInteger.valueOf(k+1));
}
return ret;
}
private static List<List<Integer>> contract(int[] col, List<List<Integer>> matrix) {
List<List<Integer>> matCop = new ArrayList<List<Integer>>(matrix);
col[0] = 1; //userinput 1 means don't delete!
col[1] = 1; //userinput
col[2] = 1;
col[12] = 1;
col[14] = 1;
col[22] = 1;
col[28] = 1;
col[29] = 1;
Multi.halveIt(col, matCop);
return matCop;
}
public static void prin(List<List<Integer>> matrix) {
for (int x = 0; x < matrix.size(); x ++) {
System.out.print("[" + matrix.get(x).get(0));
for (int y = 1; y < matrix.get(0).size(); y++) {
System.out.print(" " + matrix.get(x).get(y));
}
System.out.print("]\n");
}
System.out.print("\n\n");
}
public static void prin(int[] a) {
System.out.print("[" + a[0]);
for (int x = 1; x < a.length; x ++) {
System.out.print(" " + a[x]);
}
System.out.print("]\n\n");
}
public static void prin(String[] a) {
System.out.print("[" + a[0]);
for (int x = 1; x < a.length; x ++) {
System.out.print(" " + a[x]);
}
System.out.print("]\n\n");
}
public static void prin2(List<Integer> a) {
System.out.print("[" + a.get(0));
for (int x = 1; x < a.size(); x ++) {
System.out.print(" " + a.get(x));
}
System.out.print("]\n\n");
}
}
OK, so there actually was no infinite loop in this code whatsoever. The problem was with line 466 of my code; specifically, I was basing whether I analyzed the original matrix or its transpose on the number of rows after truncation on the original matrix and subtracting the minimum. This is wrong because, for example,
sum_{i = 40)^{54}(54 choose i) >> 2^32.
My program was taking forever because it was told to traverse through over a trillion combinations instead of 'just' a few billion. Granted it can do 10 billion in about 2 hours, and I can save more time by inverting a few nested for loops (another time).
I Guess it's time to learn profiling to see where my code slows down.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I have created the following Simplex Algorithm that maximises on the objective function. I want the opposite to happen. In this example there are two variables and the algorithm must figure out what to multiply these two variables here (13.0 and 23.0) by in order to get the maximum possible result within the constraints set. I want the algorithm to figure out the lowest possible result instead.
My Code:
import java.util.*;
public class Simplex
{
private static final double EPSILON = 1.0E-10;
private double[][] tableaux;
private int numOfConstraints;
private int numOfVariables;
private int[] basis;
/**
* Constructor for objects of class Simplex
*/
public Simplex()
{
double[][] thisTableaux = {
{ 5.0, 15.0 },
{ 4.0, 4.0 },
{ 35.0, 20.0 },
};
double[] constraints = { 480.0, 160.0, 1190.0 };
double[] variables = { 13.0, 23.0 };
numOfConstraints = constraints.length;
numOfVariables = variables.length;
tableaux = new double[numOfConstraints+1][numOfVariables+numOfConstraints+1];
//adds all elements from thisTableaux to tableaux
for(int i=0; i < numOfConstraints; i++)
{
for(int j=0; j < numOfVariables; j++)
{
tableaux[i][j] = thisTableaux[i][j];
}
}
//adds a slack variable for each variable there is and sets it to 1.0
for(int i=0; i < numOfConstraints; i++)
{
tableaux[i][numOfVariables+i] = 1.0;
}
//adds variables into the second [] of tableux
for(int j=0; j < numOfVariables; j++)
{
tableaux[numOfConstraints][j] = variables[j];
}
//adds constraints to first [] of tableaux
for(int k=0; k < numOfConstraints; k++)
{
tableaux[k][numOfConstraints+numOfVariables] = constraints[k];
}
basis = new int[numOfConstraints];
for(int i=0; i < numOfConstraints; i++)
{
basis[i] = numOfVariables + i;
}
//show();
//optimise();
//assert check(thisTableaux, constraints, variables);
}
public void optimise() {
while(true) {
int q = findLowestNonBasicCol();
if(q == -1) {
break;
}
int p = getPivotRow(q);
if(p == -1) throw new ArithmeticException("Linear Program Unbounded");
pivot(p, q);
basis[p] = q;
}
}
public int findLowestNonBasicCol() {
for(int i=0; i < numOfConstraints + numOfVariables; i++)
{
if(tableaux[numOfConstraints][i] > 0) {
return i;
}
}
return -1;
}
public int findIndexOfLowestNonBasicCol() {
int q = 0;
for(int i=1; i < numOfConstraints + numOfVariables; i++)
{
if(tableaux[numOfConstraints][i] > tableaux[numOfConstraints][q]) {
q = i;
}
}
if(tableaux[numOfConstraints][q] <= 0) {
return -1;
}
else {
return q;
}
}
/**
* Finds row p which will be the pivot row using the minimum ratio rule.
* -1 if there is no pivot row
*/
public int getPivotRow(int q) {
int p = -1;
for(int i=0; i < numOfConstraints; i++) {
if (tableaux[i][q] <=0) {
continue;
}
else if (p == -1) {
p = i;
}
else if((tableaux[i][numOfConstraints+numOfVariables] / tableaux[i][q] < tableaux[p][numOfConstraints+numOfVariables] / tableaux[p][q])) {
p = i;
}
}
return p;
}
public void pivot(int p, int q) {
for(int i=0; i <= numOfConstraints; i++) {
for (int j=0; j <= numOfConstraints + numOfVariables; j++) {
if(i != p && j != q) {
tableaux[i][j] -= tableaux[p][j] * tableaux[i][q] / tableaux[p][q];
}
}
}
for(int i=0; i <= numOfConstraints; i++) {
if(i != p) {
tableaux[i][q] = 0.0;
}
}
for(int j=0; j <= numOfConstraints + numOfVariables; j++) {
if(j != q) {
tableaux[p][j] /= tableaux[p][q];
}
}
tableaux[p][q] = 1.0;
show();
}
public double result() {
return -tableaux[numOfConstraints][numOfConstraints+numOfVariables];
}
public double[] primal() {
double[] x = new double[numOfVariables];
for(int i=0; i < numOfConstraints; i++) {
if(basis[i] < numOfVariables) {
x[basis[i]] = tableaux[i][numOfConstraints+numOfVariables];
}
}
return x;
}
public double[] dual() {
double[] y = new double[numOfConstraints];
for(int i=0; i < numOfConstraints; i++) {
y[i] = -tableaux[numOfConstraints][numOfVariables];
}
return y;
}
public boolean isPrimalFeasible(double[][] thisTableaux, double[] constraints) {
double[] x = primal();
for(int j=0; j < x.length; j++) {
if(x[j] < 0.0) {
StdOut.println("x[" + j + "] = " + x[j] + " is negative");
return false;
}
}
for(int i=0; i < numOfConstraints; i++) {
double sum = 0.0;
for(int j=0; j < numOfVariables; j++) {
sum += thisTableaux[i][j] * x[j];
}
if(sum > constraints[i] + EPSILON) {
StdOut.println("not primal feasible");
StdOut.println("constraints[" + i + "] = " + constraints[i] + ", sum = " + sum);
return false;
}
}
return true;
}
private boolean isDualFeasible(double[][] thisTableaux, double[] variables) {
double[] y = dual();
for(int i=0; i < y.length; i++) {
if(y[i] < 0.0) {
StdOut.println("y[" + i + "] = " + y[i] + " is negative");
return false;
}
}
for(int j=0; j < numOfVariables; j++) {
double sum = 0.0;
for(int i=0; i < numOfConstraints; i++) {
sum += thisTableaux[i][j] * y[i];
}
if(sum < variables[j] - EPSILON) {
StdOut.println("not dual feasible");
StdOut.println("variables[" + j + "] = " + variables[j] + ", sum = " + sum);
return false;
}
}
return true;
}
private boolean isOptimal(double[] constraints, double[] variables) {
double[] x = primal();
double[] y = dual();
double value = result();
double value1 = 0.0;
for(int j=0; j < x.length; j++) {
value1 += variables[j] * x[j];
}
double value2 = 0.0;
for(int i=0; i < y.length; i++) {
value2 += y[i] * constraints[i];
}
if(Math.abs(value - value1) > EPSILON || Math.abs(value - value2) > EPSILON) {
StdOut.println("value = " + value + ", cx = " + value1 + ", yb = " + value2);
return true;
}
return true;
}
private boolean check(double[][] thisTableaux, double[] constraints, double [] variables) {
return isPrimalFeasible(thisTableaux, constraints) && isDualFeasible(thisTableaux, variables) && isOptimal(constraints, variables);
}
}
If you need any more info just ask. Any help appreciated thanks.
If you want to minimize f(x), this is equivalent to maximizing -f(x), so if your posted code solves maximization problems correctly, you can use it to minimize any objective function f(x) simply by maximizing its additive inverse -f(x).
Note that you do not change the constraints, only the objective function.
For example, minimizing f(x) = 3x + 5, x >= 1 is equivalent to maximizing -f(x) = -3x -5, x >= 1.
min[f(x), x>=1] = f(1) = 8 = -(-8) = -[-f(1)] = -max[-f(x), x>=1].
In general, min[f(x)] = f(Xmin) = -[-f(Xmax)] = -max[-f(x)] and Xmin = Xmax.
In the above example, min[f(x)] = -max[-f(x)] = 8 and Xmin = Xmax = 1.
In the particular example you give, you would simply need to change the line
double[] variables = { 13.0, 23.0 };
to
double[] variables = { -13.0, -23.0 };
The values of the variables returned should then be the same as for the minimum of the case where
double[] variables = { 13.0, 23.0 };
and multiplying the value of the objective function by -1 will give the minimum of the objective for the case where
double[] variables = { 13.0, 23.0 };