Find triangles in a list of random numbers - java

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());
}
}
}

Related

Find the maximum product of two non overlapping palindromic subsequences

I am trying to find the maximum product of two non overlapping palindromic sub-sequences of string s that we'll refer to as a and b. I came up with below code but it's not giving correct output:
public static int max(String s) {
int[][] dp = new int[s.length()][s.length()];
for (int i = s.length() - 1; i >= 0; i--) {
dp[i][i] = 1;
for (int j = i+1; j < s.length(); j++) {
if (s.charAt(i) == s.charAt(j)) {
dp[i][j] = dp[i+1][j-1] + 2;
} else {
dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);
}
}
}
return dp[0][s.length()-1];
}
For input string "acdapmpomp", we can choose a = "aca" and b ="pmpmp" to get a maximal product of score 3 * 5 = 15. But my program gives output as 5.
Firstly you should traverse the dp table to find out the length of longest palindromic subsequences using bottom up approach, then you can calculate the max product by multiplying dp[i][j] with dp[j+1][n-1] : Given below is the code in C++;
int longestPalindromicSubsequenceProduct(string x){
int n = x.size();
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){
dp[i][i] = 1;
}
for(int k=1;k<n;k++){
for(int i=0;i<n-k;i++){
int j = i + k;
if(x[i]==x[j]){
dp[i][j] = 2 + dp[i+1][j-1];
} else{
dp[i][j] = max(dp[i][j-1],dp[i+1][j]);
}
}
}
int maxProd = 0;
for(int i=0;i<n;i++){
for(int j=0;j<n-1;j++){
maxProd = max(maxProd,dp[i][j]*dp[j+1][n-1]);
}
}
return maxProd;
}
int multiplyPalindrome(string s) {
int n=s.size(),m=0;
vector<vector<int>> dp(n, vector<int> (n));
for(int i=0;i<n;i++) dp[i][i]=1;
for (int cl=2; cl<=n; cl++) {
for (int i=0; i<n-cl+1; i++){
int j = i+cl-1;
if (s[i] == s[j] && cl == 2) dp[i][j] = 2;
else if (s[i] == s[j]) dp[i][j] = dp[i+1][j-1] + 2;
else dp[i][j] = max(dp[i][j-1], dp[i+1][j]);
}
}
for(int i=0;i<n-1;i++){
m = max( m, dp[0][i]*dp[i+1][n-1] );
}
return m;
}
int palSize(string &s, int mask) {
int p1 = 0, p2 = s.size(), res = 0;
while (p1 <= p2) {
if ((mask & (1 << p1)) == 0)
++p1;
else if ((mask & (1 << p2)) == 0)
--p2;
else if (s[p1] != s[p2])
return 0;
else
res += 1 + (p1++ != p2--);
}
return res;
}
int maxProduct(string s) {
int mask[4096] = {}, res = 0;
for (int m = 1; m < (1 << s.size()); ++m)
mask[m] = palSize(s, m);
for (int m1 = 1; m1 < (1 << s.size()); ++m1)
if (mask[m1])
for (int m2 = 1; m2 < (1 << s.size()); ++m2)
if ((m1 & m2) == 0)
res = max(res, mask[m1] * mask[m2]);
return res;
}
You can loop through all non-overlapping palindromic subsequences and return the maximum value.
public int longestPalindromicSubsequenceProduct(String str) {
int maxProduct = 0;
for (int k = 0; k < str.length(); k++) {
String left = str.substring(0, k);
String right = str.substring(k);
int currProduct = longestPalindromicSubsequence(left) * longestPalindromicSubsequence(right);
maxProduct = Math.max(maxProduct, currProduct);
}
return maxProduct;
}
private int longestPalindromicSubsequence(String org) {
String rev = new StringBuilder(org).reverse().toString();
return longestCommonSubsequence(org, rev);
}
private int longestCommonSubsequence(String str1, String str2) {
int rows = str1.length();
int cols = str2.length();
int[][] dp = new int[rows + 1][cols + 1];
for (int r = 1; r <= rows; r++) {
for (int c = 1; c <= cols; c++) {
if (str1.charAt(r - 1) == str2.charAt(c - 1)) dp[r][c] = 1 + dp[r - 1][c - 1];
else dp[r][c] = Math.max(dp[r - 1][c], dp[r][c - 1]);
}
}
return dp[rows][cols];
}
Your algorithm returns the maximum length of a palyndrome, not the maximum of the product of two lengths.
UPDATE
Here's a possible solution:
public static int max(String s) {
int max = 0;
for (int i = 1; i < s.length()-1; ++i) {
String p1 = bestPalyndrome(s, 0, i);
String p2 = bestPalyndrome(s, i, s.length());
int prod = p1.length()*p2.length();
if (prod > max) {
System.out.println(p1 + " " + p2 + " -> " + prod);
max = prod;
}
}
return max;
}
private static String bestPalyndrome(String s, int start, int end) {
if (start >= end) {
return "";
} else if (end-start == 1) {
return s.substring(start, end);
} else if (s.charAt(start) == s.charAt(end-1)) {
return s.charAt(start) + bestPalyndrome(s, start+1, end-1)
+ s.charAt(end-1);
} else {
String s1 = bestPalyndrome(s, start, end-1);
String s2 = bestPalyndrome(s, start+1, end);
return s2.length() > s1.length() ? s2 : s1;
}
}

Libgdx Generate RogueLIke Dungeon - Algorithm Error

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 :)

Pseudo Infinite Loop (Optimally Deleting 'missing data' from a matrix)

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.

Alter Simplex Algorithm to Minimize on objective function NOT maximize [closed]

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 };

Java permutations

I am trying to run my code so it prints cyclic permutations, though I can only get it to do the first one at the moment. It runs correctly up to the point which I have marked but I can't see what is going wrong. I think it has no break in the while loop, but I'm not sure. Really could do with some help here.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPemutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPemutation(int p[])// (b)
{
System.out
.println("The permutation is represented by the cyclic notation:");
int[] B = new int[p.length];
int m = 0;
while (m < p.length)// this is the point at which my code screws up
{
if (!check(B, m)) {
B = parenthesis(p, m);
printParenthesis(B);
m++;
} else
m++;
}// if not there are then repeat
}
static int[] parenthesis(int p[], int i) {
int[] B = new int[p.length];
for (int a = p[i], j = 0; a != B[0]; a = p[a - 1], j++) {
B[j] = a;
}
return B;
}
static void printParenthesis(int B[]) {
System.out.print("( ");
for (int i = 0; i < B.length && B[i] != 0; i++)
System.out.print(B[i] + " ");
System.out.print(")");
}
static boolean check(int B[], int m) {
int i = 0;
boolean a = false;
while (i < B.length || !a) {
if ((ispresent(m, B, i))){
a = true;
break;
}
else
i++;
}
return a;
}
static boolean ispresent(int m, int B[], int i) {
return m == B[i] && m < B.length;
}
}
Among others you should check p[m] in check(B, p[m]) instead of m:
in static void printPemutation(int p[]):
while (m < p.length){
if (!check(B, p[m])) {
B = parenthesis(p, m);
printParenthesis(B);
}
m++;
}
then
static boolean check(int B[], int m) {
int i = 0;
while (i < B.length) {
if (m == B[i]) {
return true;
}
i++;
}
return false;
}
this does somehow more what you want, but not always i fear...

Categories

Resources