I'm tryin to implement a simple "random search algorithm" in Java
here's a piece of the code:
//execute the algorithm
double bestSolution; //INITIAL SOLUTION!
Vector bestVector=null;
for (int iter=0; iter<maxIterations; iter++) {
//generate random vector-solution
Vector v = Vector.generateRandomVector(problemSize, minOfSearchSpace, maxOfSearchSpace);
double currentObjValue = objectiveFunctionValue(v);
// if a better solution is found
if (currentObjValue < bestSolution); {
bestVector = v;
bestSolution = currentObjValue;
}
System.out.println("Iteration: "+(iter+1)+" Best solution: "+bestSolution);
} // end for
System.out.println("\n\nBest solution: "+bestVector.toString()+" Objective Value: "+bestSolution);
my problem is: somehow i have to initialize the initial solution "double bestSolution".
what initial value should i give? note that for certain objective function, values such as "0" while make the convergence harder.
It seems natural to me to use
double bestSolution = Double.MAX_VALUE
since presumably your first guess will be the best so far, no matter what it is.
or maybe even
double bestSolution = Double.POSITIVE_INFINITY
Check if you're at the first iteration (iter == 0), and initialize the bestSolution with the computed solution if it's the first iteration, else compare it with the previous bestSolution.
Related
I currently have following code:
int[][] legalForBlack = {{0,1},{1,0},{2,3},{3,2}};
for (int x=0;x<boardSize;x++) {
for (int y=0;y<boardSize;y++) {
if (x,y) in legalForBlack
methodA()
else
methodB()
}
}
Of course this code won't compile. I am looking for a fancy and compact way to check when (x,y) are in the given list.
I can do this with 4 if-statements or a loop, but this is not a proper way imo.
I am looking for something that does this in constant time.
EDIT:
I think I found a way. What do you think of this?
int[][] legalForBlack = {{0,1},{1,0},{2,3},{3,2}}; // keep in order!
int cur = 0;
for (int x=0;x<boardSize;x++) {
for (int y=0;y<boardSize;y++) {
int[] buffer = legalForBlack[cur];
if (x==buffer[0] && y==buffer[1]) {
cur++;
methodA();
} else {
methodB();
}
}
}
Heres pseudocode for arrays:
input data in array
find x with for to match first column (legalForBlack[i][0])
if x matches legalForBlack[i][0] check if legalForBlack[i][1] matches y
if yes, count it
But there is a better way, when you just want to check if they are in array. Create object Pair with variable x and y, create equals() and hashCode() functions to have unique for each pair (like get hashCode from string xy), place all inputs in Set and then check if given Pair(x,y) is in Set.
boolean isLegal = false;
for(int[] coord: legalForBlack)
if(Arrays.equals(coord, someXYArray)) {
isLegal = true;
break; //Credit to Adnan Isajbegovic
}
if(isLegal)
methodA();
else
methodB();
I have an alternative solution for your question. Judging from your code, I assume that you are writing something chess-related and your list of legalForBlack is a series of coordinates that the player is allowed to move to. Best way IMO would be to code each square on the board with an index (0 to maximum 63) and store all of these in a Map of type <Integer, Coordinate>, where Coordinate has int x and int y. If you don't have any particular use for the coordinates, you can also skip and convert your Map to a simple Array of allowed-squares. This would only require you to check whether a given value is in your allowed-square list. I hope this gives you a better approach to your problem. Good luck!
I have an array with lat and lng in the custom model . i want to sort the array so that minimum distance from my location comes at the top position and so on.
Here is what i have tried
myLocation = new Location("");
myLocation.setLatitude(Double.valueOf(MyApplication.getInstance().getLatitude()));
myLocation.setLongitude(Double.valueOf(MyApplication.getInstance().getLongitude()));
Collections.sort(pings, new DistanceComparator());
private class DistanceComparator implements java.util.Comparator<PingModel>
{
#Override
public int compare(PingModel lhs, PingModel rhs)
{
Location lhsLocation = new Location("");
lhsLocation.setLatitude(Double.valueOf(lhs.latloc));
lhsLocation.setLongitude(Double.valueOf(lhs.lngloc));
Location rhsLocation = new Location("");
rhsLocation.setLatitude(Double.valueOf(lhs.latloc));
rhsLocation.setLongitude(Double.valueOf(lhs.lngloc));
return (int)rhsLocation.distanceTo(myLocation) - (int)lhsLocation.distanceTo(myLocation);
}
}
The result is not sure what kind of sorting it is doing but its not according to distance.
You have a copy-paste error. Change these 2 lines:
rhsLocation.setLatitude(Double.valueOf(lhs.latloc));
rhsLocation.setLongitude(Double.valueOf(lhs.lngloc));
to:
rhsLocation.setLatitude(Double.valueOf(rhs.latloc)); // It's rhs!
rhsLocation.setLongitude(Double.valueOf(rhs.lngloc)); // It's rhs!
Apart from this, you shouldn't convert to int before subtracting the distances. In fact, you should avoid using subtraction as the return value of a comparator. This has some well-known flaws, in particular, as distances are float values, they might not fit into an int. And what is more important, the result of the subtraction might not fit into an int. This means that the int you'd be returning might overflow, leading to unexpected results.
I'd recommend you to use clear, understandable code, instead of smartish, tricky code. Consider changing the last line of your comparator to a common tri-state if:
float lhsDistance = lhsLocation.distanceTo(myLocation);
float rhsDistance = rhsLocation.distanceTo(myLocation);
if (lhsDistance < rhsDistance) {
return -1;
} else if (lhsDistance > rhsDistance) {
return 1;
} else {
return 0;
}
Note: if the values you're comparing are in fact equal, then you must return 0 in your comparator. Otherwise, you might experience subtle, nasty bugs, as explained in this answer.
Not sure if this will help, but I was working on a similar project and found this link to be very helpful : http://www.geodatasource.com/developers/java .
Basically if you have you location; use the distance function to calculate new position - your position, and then sort based on this. Loop through the array of locations, and sort based on results.
Hope it helps.
Dan.
Can you try following
return Float.compare(lhsLocation.distanceTo(myLocation), rhsLocation.distanceTo(myLocation))
Converting to int before substraction might not always work. For example, if your distanceTo() function return km and the distance from your point and the data points is within 1 km then the result of subtraction may be 0.
Instead of
return (int)rhsLocation.distanceTo(myLocation) - (int)lhsLocation.distanceTo(myLocation);
Try
return (rhsLocation.distanceTo(myLocation) - lhsLocation.distanceTo(myLocation)) > 0 ? 1 : -1;
I have a list of double values (distances between point p0 and a point list L) and I'm looking for their minimum. Then I'm changing the list (which now contains distances between point p1 and the point list L) and compute this new minimum.
I repeat this until the new minimum is bigger than the minimum at the previous step.
In pseudo Java code:
double minDistanceTotal = Double.MAX_VALUE;
double minDistanceCurrent = ?????;
while (minDistanceCurrent < minDistanceTotal) {
Point curPoint = ... // take another point p0, p1, p2...
// compute current minimum distance
for (Point otherPoint : pointList) {
double curDistance = distance(curPoint, otherPoint);
if (curDistance < minDistanceCurrent) {
minDistanceCurrent = curDistance;
}
}
// compare it to the total minimum distance
if (minDistanceCurrent < minDistanceTotal) {
... // do something
minDistanceTotal = minDistanceCurrent;
}
}
My problem now is that I'm not sure about how to initialize minDistanceCurrent. First I tried Double.MAX_VALUE - 1, but then the while-loop isn't executed at all.
After checked the Java API to find the actual value of Double.MAX_VALUE which is 0x1.fffffffffffffP+1023. So I tried 0x1.ffffffffffffeP+1023 as the value for minDistanceCurrent, which seems to work.
But I'm not sure if this is really the second highest double value in Java.
So, what's the value I should initialize minDistanceCurrent with? Or is there some different approach to get what I want that I missed?
EDIT: After the answer of #resueman, I realized a flaw in the code. The check of current minimum and total minimum can just be done after a new current minimum is computed and not before (as it is in the condition of the while loop).
The problem was fixed using the following code:
double minDistanceTotal = Double.MAX_VALUE;
double minDistanceCurrent = Double.MAX_VALUE;
while (true) {
Point curPoint = ... // take another point
// compute current minimum distance
for (Point otherPoint : pointList) {
double curDistance = distance(curPoint, otherPoint);
if (curDistance < minDistanceCurrent) {
minDistanceCurrent = curDistance;
}
}
// compare it to the total minimum distance
if (minDistanceCurrent < minDistanceTotal) {
... // do something
minDistanceTotal = minDistanceCurrent;
} else {
break;
}
}
An alternative would be while(!pointList.isEmpty()) to avoid an infinite loop when the list is empty.
It looks like you only want to break out of the loop after this block of code is called
if (minDistanceCurrent < minDistanceTotal) {
... // do something
minDistanceTotal = minDistanceCurrent;
}
If that's the case, then I'd suggest changing your while loop to either while(true) and putting a break in the if statement, or making it while(minDistanceTotal != minDistanceCurrent)
If I'm not wrong, your loop will execute just once. Either the distances calculated by the 'distance' method are lower than MAX_VALUE or overflow the double. In any case, your last 'if' will set current and total distances equal, hence getting you out of the loop. I doubt this is what you really want.
Probably you want just to make minDistanceTotal = minDistanceCurrent just at beginning of the loop, and probably you want to use BigDecimal instead of double to avoid overflowing and inaccurate calculations, but I can't really say as I don't get the idea behind your algorithm.
Summarizing:
Be careful on how you calculate distances inside your "distance(curPoint, otherPoint)", in particular consider overflowing effects. Maybe use BigDecimal instead of Double.
Get ride of the last if and change it for whatever you really need to do.
Hope it helps somehow.
I'm new to stack overflow so sorry for anything that might consider me a newbie.
I understand java to a certain degree, however, i am stuck on one thing i hope you guys can help me on.
I am in the process of making a floating point simulator and i am struggling on this section of the code.
I need the next part of the array [1] to reach the total length of the mantissa my knowledge with arrays in java are not exactly the best so any help would be much appreciated.
Thanks
public float toDecimal()
{
/**
* Convert Exponent and find shift
*/
char[] mantissaCharArray = mantissa.toCharArray();
int mantissaLength = mantissaCharArray.length;
float[] mantissaMultiplierArray = new float[mantissaLength];
mantissaMultiplierArray[0]= 1;
for (mantissaMultiplierArray[1];mantissaCharArray;mantissaMultiplierArray++)
{
//for loop to cover array from [1] to the lengthmantissa
}
//each one multiply current
}
Try this,
for (int i=(int)mantissaMultiplierArray[0];i< mantissaCharArray.length;i++)
{
//
}
mantissaMultiplierArray[0] will return float value.
So you want to run through each element of an array? You are right with the for loop, just wrote it wrong. It should go something like this;
for(int i = (int)mantissaMultiplierArray[0]; i < mantissaCharArray.length; i++)
{
System.out.println(mantissaMultiplierArray[i]);
}
Let me explain the setup of this for loop a bit more;
You are setting an integer value i to the first value of mantissaMultiplierArray. You are also parsing it as an int because it is a float, hence the (int)
You give i a limitation - the total size of the mantissaCharArray
increment i
In the for loop I have it set to print out the values of the mantissaMultiplierArray for each value of i, but yu can do whatever you want inside of it.
Hey guys, recently posted up about a problem with my algorithm.
Finding the numbers from a set which give the minimum amount of waste
Ive amended the code slightly, so it now backtracks to an extent, however the output is still flawed. Ive debugged this considerablychecking all the variable values and cant seem to find out the issue.
Again advice as opposed to an outright solution would be of great help. I think there is only a couple of problems with my code, but i cant work out where.
//from previous post:
Basically a set is passed to this method below, and a length of a bar is also passed in. The solution should output the numbers from the set which give the minimum amount of waste if certain numbers from the set were removed from the bar length. So, bar length 10, set includes 6,1,4, so the solution is 6 and 4, and the wastage is 0. Im having some trouble with the conditions to backtrack though the set. Ive also tried to use a wastage "global" variable to help with the backtracking aspect but to no avail.
SetInt is a manually made set implementation, which can add, remove, check if the set is empty and return the minimum value from the set.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package recursivebacktracking;
/**
*
* #author User
*/
public class RecBack {
int WASTAGE = 10;
int BESTWASTAGE;
int BARLENGTH = 10;
public void work()
{
int[] nums = {6,1,2,5};
//Order Numbers
SetInt ORDERS = new SetInt(nums.length);
SetInt BESTSET = new SetInt(nums.length);
SetInt SOLUTION = new SetInt(nums.length);
//Set Declarration
for (int item : nums)ORDERS.add(item);
//Populate Set
SetInt result = tryCutting(ORDERS, SOLUTION, BARLENGTH, WASTAGE);
result.printNumbers();
}
public SetInt tryCutting(SetInt possibleOrders, SetInt solution, int lengthleft, int waste)
{
for (int i = 0; i < possibleOrders.numberInSet(); i++) // the repeat
{
int a = possibleOrders.min(); //select next candidate
System.out.println(a);
if (a <= lengthleft) //if accecptable
{
solution.add(a); //record candidate
lengthleft -= a;
WASTAGE = lengthleft;
possibleOrders.remove(a); //remove from original set
if (!possibleOrders.isEmpty()) //solution not complete
{
System.out.println("this time");
tryCutting(possibleOrders, solution, lengthleft, waste);//try recursive call
BESTWASTAGE = WASTAGE;
if ( BESTWASTAGE <= WASTAGE )//if not successfull
{
lengthleft += a;
solution.remove(a);
System.out.println("never happens");
}
} //solution not complete
}
} //for loop
return solution;
}
}
Instead of using backtracking, have you considered using a bitmask algorithm instead? I think it would make your algorithm much simpler.
Here's an outline of how you would do this:
Let N be number of elements in your set. So if the set is {6,1,2,5} then N would be 4. Let max_waste be the maximum waste we can eliminate (10 in your example).
int best = 0; // the best result so far
for (int mask = 1; mask <= (1<<N)-1; ++mask) {
// loop over each bit in the mask to see if it's set and add to the sum
int sm = 0;
for (int j = 0; j < N; ++j) {
if ( ((1<<j)&mask) != 0) {
// the bit is set, add this amount to the total
sm += your_set[j];
// possible optimization: if sm is greater than max waste, then break
// out of loop since there's no need to continue
}
}
// if sm <= max_waste, then see if this result produces a better one
// that our current best, and store accordingly
if (sm <= max_waste) {
best = max(max_waste - sm);
}
}
This algorithm is very similar to backtracking and has similar complexity, it just doesn't use recursion.
The bitmask basically is a binary representation where 1 indicates that we use the item in the set, and 0 means we don't. Since we are looping from 1 to (1<<N)-1, we are considering all possible subsets of the given items.
Note that running time of this algorithm increases very quickly as N gets larger, but with N <= around 20 it should be ok. The same limitation applies with backtracking, by the way. If you need faster performance, you'd need to consider another technique like dynamic programming.
For the backtracking, you just need to keep track of which element in the set you are on, and you either try to use the element or not use it. If you use it, you add it to your total, and if not, you proceeed to the next recursive call without increasing your total. Then, you decrement the total (if you incremented it), which is where the backtracking comes in.
It's very similar to the bitmask approach above, and I provided the bitmask solution to help give you a better understanding of how the backtracking algorithm would work.
EDIT
OK, I didn't realize you were required to use recursion.
Hint1
First, I think you can simplify your code considerably by just using a single recursive function and putting the logic in that function. There's no need to build all the sets ahead of time then process them (I'm not totally sure that's what you're doing but it seems that way from your code). You can just build the sets and then keep track of where you are in the set. When you get to the end of the set, see if your result is better.
Hint2
If you still need more hints, try to think of what your backtracking function should be doing. What are the terminating conditions? When we reach the terminating condition, what do we need to record (e.g. did we get a new best result, etc.)?
Hint3
Spoiler Alert
Below is a C++ implementation to give you some ideas, so stop reading here if you want to work on it some more by yourself.
int bestDiff = 999999999;
int N;
vector< int > cur_items;
int cur_tot = 0;
int items[] = {6,1,2,5};
vector< int > best_items;
int max_waste;
void go(int at) {
if (cur_tot > max_waste)
// we've exceeded max_waste, so no need to continue
return;
if (at == N) {
// we're at the end of the input, see if we got a better result and
// if so, record it
if (max_waste - cur_tot < bestDiff) {
bestDiff = max_waste - cur_tot;
best_items = cur_items;
}
return;
}
// use this item
cur_items.push_back(items[at]);
cur_tot += items[at];
go(at+1);
// here's the backtracking part
cur_tot -= items[at];
cur_items.pop_back();
// don't use this item
go(at+1);
}
int main() {
// 4 items in the set, so N is 4
N=4;
// maximum waste we can eliminiate is 10
max_waste = 10;
// call the backtracking algo
go(0);
// output the results
cout<<"bestDiff = "<<bestDiff<<endl;
cout<<"The items are:"<<endl;
for (int i = 0; i < best_items.size(); ++i) {
cout<<best_items[i]<<" ";
}
return 0;
}