I am trying to find the farthest distance between two non -overlapping intervals represented as arraylist . Non-overlapping intervals are those in which the next start point does not lie between the starting point(inclusive) and ending point(exclusive) .
Example
Number of intervals 3
Interval 1 : 1 2
Interval 2: 3 5
Interval 3: 6 7
The pair of interval (1,2) and (6,7) is farthest as distance between these two is 6 -2 = 4
So output should be 4
My implementation
import java.util.*;
class Checker implements Comparator<ArrayList>{
public int compare(ArrayList a, ArrayList b){
int x = (Integer)a.get(0);
int y = (Integer)b.get(0);
return x-y;
}
}
class OverlappingIntervals {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
ArrayList<ArrayList<Integer>> intervals = new ArrayList<ArrayList<Integer>>(n);
for (int i = 0; i < n; i++) {
int x = sc.nextInt();
int y = sc.nextInt();
intervals.add(new ArrayList<Integer>(Arrays.asList(x, y)));
}
int result = overlappingIntervals(n, intervals);
System.out.println(result);
}
static int overlappingIntervals(int n, ArrayList<ArrayList<Integer>> intervals) {
// System.out.println(intervals);
Checker check = new Checker();
Collections.sort(intervals, check);
int ans = -1;
for(int i = 0; i < n-1;i++){
for(int j = i+1; j < n;j++){
int x = (Integer)intervals.get(j).get(0)- intervals.get(i).get(1);
if(x >= 0){
if(x > ans)
ans = Math.max(x,ans);
}
}
}
return ans;
}
}
Any better optimization for the above so to handle the constraints
1<=N<=10^5
1<=l<=r<=10^6
l and r is the starting point and ending point of interval respectively.
Try this.
Scanner in = new Scanner("3 1 2 3 5 6 7");
int n = in.nextInt();
int minTo = Integer.MAX_VALUE;
int maxFrom = Integer.MIN_VALUE;
for (int i = 0; i < n; ++i) {
maxFrom = Math.max(maxFrom, in.nextInt());
minTo = Math.min(minTo, in.nextInt());
}
if (minTo < maxFrom)
System.out.println("max disntance = " + (maxFrom - minTo));
else
System.out.println("none");
output:
max disntance = 4
We can solve this easily using Stack in O(n) + O(n*log(n)) Time & O(n) Space complexity.
The idea here is to merge the intervals and then check the corresponding gaps between the consecutive Intervals.
Here is an easy and classic approach to your problem with an illustration:
import java.util.*;
class OverlappingIntervals
{
public static void main(String args[])
{
Scanner sc = new Scanner(System.in);
//int n = sc.nextInt();
ArrayList<Interval> intervals = new ArrayList<>();
intervals.add(new Interval(5, 14));intervals.add(new Interval(6, 9));
intervals.add(new Interval(8, 17));intervals.add(new Interval(23, 25));
intervals.add(new Interval(36, 56));intervals.add(new Interval(33, 45));
intervals.add(new Interval(42, 67));intervals.add(new Interval(50, 69));
intervals.add(new Interval(81, 95));intervals.add(new Interval(99, 111));
int result = overlappingIntervals(intervals);
System.out.println(result); // 82 b/w [5 , 17] & [99 , 111]
}
static int overlappingIntervals(ArrayList<Interval> intervals)
{
// Sorting all Intervals based on there `start` time
Collections.sort(intervals, Comparator.comparingInt(a -> a.begin));
int maxDistance = -1;
Stack<Interval> stack = new Stack<>();
for (Interval currInterval : intervals)
{
// Pushing a non-overlapping Interval
if (stack.empty() || stack.peek().end < currInterval.begin)
stack.push(currInterval);
// Merging an overlapping Interval
if (stack.peek().end < currInterval.end)
stack.peek().end = currInterval.end;
}
/* Now, Stack will have following merged Intervals:
[5 , 17] <6> [23 , 25] <8> [33 , 69] <12> [81 , 95] <4> [99 , 111] */
// Checking the gap b/w consecutive Merged-Intervals :
Interval rightEnd = stack.pop();
if (stack.empty()) return -1;
Interval leftEnd = rightEnd;
while (!stack.empty())
leftEnd = stack.pop();
maxDistance = rightEnd.begin - leftEnd.end;
return maxDistance;
}
}
class Interval
{
int begin, end;
Interval(int begin, int end)
{
this.begin = begin; this.end = end;
}
#Override
public String toString()
{ return "[" +begin+ " , " +end+ "]"; }
}
/** [5========17] [23=25] [33=================================69] [81===========95] [99======111]
* 5-------14 23---25 36-----------------56 81------------95
* 6---9 42----------------------67 99------111
* 8------17 33----------45 50----------------69 */
We can even do this without merging the intervals but I believe this approach is easier to understand.
Feel free to ask any doubts.
This is my solution though in C++ can be easily written in any language.
T.C - O(n + log(n))
S.C - O(1)
int overlappingIntervals(int n, vector<pair<int, int> >& intervals){
sort(intervals.begin(),intervals.end());
int mi = INT_MAX;
for(auto it: intervals){
mi = min(it.second,mi);
}
return (intervals[n-1].first < mi ? -1 : intervals[n-1].first - mi);
}
Related
I have this question I am trying to solve. I have tried coding for the past 4 hours.
An integer is defined to be a Smart number if it is an element in the infinite sequence
1, 2, 4, 7, 11, 16 …
Note that 2-1=1, 4-2=2, 7-4=3, 11-7=4, 16-11=5 so for k>1, the kth element of the sequence is equal to the k-1th element + k-1. For example, for k=6, 16 is the kth element and is equal to 11 (the k-1th element) + 5 ( k-1).
Write function named isSmart that returns 1 if its argument is a Smart number, otherwise it returns 0. So isSmart(11) returns 1, isSmart(22) returns 1 and isSmart(8) returns 0
I have tried the following code to
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
// TODO Auto-generated method stub
int x = isSmart(11);
System.out.println(x);
}
public static int isSmart(int n) {
int[] y = new int[n];
int j = 0;
for (int i = 1; i <= n; i++) {
y[j] = i;
j++;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i <= y.length; i++) {
int diff = 0;
y[j] = y[i+1] - y[i] ;
y[i] = diff;
}
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
When I test it with 11 it is giving me 0 but it shouldn't. Any idea how to correct my mistakes?
It can be done in a simpler way as follows
import java.util.Arrays;
public class IsSmart {
public static void main(String[] args) {
int x = isSmart(11);
System.out.println("Ans: "+x);
}
public static int isSmart(int n) {
//------------ CHECK THIS LOGIC ------------//
int[] y = new int[n];
int diff = 1;
for (int i = 1; i < n; i++) {
y[0] =1;
y[i] = diff + y[i-1];
diff++;
}
//------------ CHECK THIS LOGIC ------------//
System.out.println(Arrays.toString(y));
for (int i = 0; i < y.length; i++) {
if(n == y[i])
return 1;
}
return 0;
}
}
One of the problems is the way that your populating your array.
The array can be populated as such
for(int i = 0; i < n; i++) {
y[i] = (i == 0) ? 1 : y[i - 1] + i;
}
The overall application of the function isSmart can be simplified to:
public static int isSmart(int n) {
int[] array = new int[n];
for(int i = 0; i < n; i++) {
array[i] = (i == 0) ? 1 : array[i - 1] + i;
}
for (int i = 0; i < array.length; i++) {
if (array[i] == n) return 1;
}
return 0;
}
Note that you don't need to build an array:
public static int isSmart(int n) {
int smart = 1;
for (int i = 1; smart < n; i++) {
smart = smart + i;
}
return smart == n ? 1 : 0;
}
Here is a naive way to think of it to get you started - you need to fill out the while() loop. The important thing to notice is that:
The next value of the sequence will be the number of items in the sequence + the last item in the sequence.
import java.util.ArrayList;
public class Test {
public static void main(String[] args) {
System.out.println(isSmart(11));
}
public static int isSmart(int n) {
ArrayList<Integer> sequence = new ArrayList<Integer>();
// Start with 1 in the ArrayList
sequence.add(1);
// You need to keep track of the index, as well as
// the next value you're going to add to your list
int index = 1; // or number of elements in the sequence
int nextVal = 1;
while (nextVal < n) {
// Three things need to happen in here:
// 1) set nextVal equal to the sum of the current index + the value at the *previous* index
// 2) add nextVal to the ArrayList
// 3) incriment index by 1
}
// Now you can check to see if your ArrayList contains n (is Smart)
if (sequence.contains(n)) { return 1; }
return 0;
}
}
First think of a mathematical solution.
Smart numbers form a sequence:
a0 = 1
an+1 = n + an
This gives a function for smart numbers:
f(x) = ax² + bx + c
f(x + 1) = f(x) + x = ...
So the problem is to find for a given y a matching x.
You can do this by a binary search.
int isSmart(int n) {
int xlow = 1;
int xhigh = n; // Exclusive. For n == 0 return 1.
while (xlow < xhigh) {
int x = (xlow + xhigh)/2;
int y = f(x);
if (y == n) {
return 1;
}
if (y < n) {
xlow = x + 1;
} else {
xhigh = x;
}
}
return 0;
}
Yet smarter would be to use the solution for x and look whether it is an integer:
ax² + bx + c' = 0 where c' = c - n
x = ...
I was playing around with this and I noticed something. The smart numbers are
1 2 4 7 11 16 22 29 ...
If you subtract one you get
0 1 3 6 10 15 21 28 ...
0 1 2 3 4 5 6 7 ...
The above sequence happens to be the sum of the first n numbers starting with 0 which is n*(n+1)/2. So add 1 to that and you get a smart number.
Since n and n+1 are next door to each other you can derive them by reversing the process.
Take 29, subtract 1 = 28, * 2 = 56. The sqrt(56) rounded up is 8. So the 8th smart number (counting from 0) is 29.
Using that information you can detect a smart number without a loop by simply reversing the process.
public static int isSmart(int v) {
int vv = (v-1)*2;
int sq = (int)Math.sqrt(vv);
int chk = (sq*(sq+1))/2 + 1;
return (chk == v) ? 1 : 0;
}
Using a version which supports longs have verified this against the iterative process from 1 to 10,000,000,000.
I am practicing Algorithms question on merge sort. I build a java program on merge sort. I think there is some logical error in my code.
This is my output:
Array length = 6
value of q 2
value of q 1
value of q 0
9 1073741823 left end -----m(0,0,1)
6 1073741823 right end -----m(0,0,1)
remaining element left
6 9 0 0 0 0 -------------------
9 6 1073741823 left end -----m(0,1,2)
5 1073741823 right end -----m(0,1,2)
remaining element left
5 9 6 0 0 0 -------------------
value of q 4
value of q 3
0 1073741823 left end -----m(3,3,4)
8 1073741823 right end -----m(3,3,4)
remaining element right
5 9 6 0 8 0 -------------------
0 8 1073741823 left end -----m(3,4,5)
2 1073741823 right end -----m(3,4,5)
remaining element left
5 9 6 0 2 8 -------------------
9 6 5 1073741823 left end -----m(0,2,5)
0 8 2 1073741823 right end -----m(0,2,5
remaining element left
0 8 2 9 6 5 -------------------
0 8 2 9 6 5
This is my code:
public class MergeSort{
private int[] digits;
private static int[] dummy;
private int length;
public static void main(String[] args) {
int [] digits = {9,6,5,0,8,2};
System.out.println("Array length = "+digits.length);
MergeSort ms = new MergeSort();
ms.sort(digits);
for(int a :dummy){
System.out.print(a+" ");
}
}
void sort(int [] digits){
this.digits=digits;
length=digits.length;
dummy= new int[length];
mergesort(0,length-1);
}
void mergesort(int p,int r){
int q;
if(p < r){
q = (p + r) / 2;
System.out.println("value of q "+q);
mergesort(p,q);
mergesort(q+1,r);
merge(p,q,r);
System.out.println("-------------------");
}
}
void merge(int p,int q,int r){
int i,j,k;
int n1=q-p+1;
int n2 =r-q;
int [] left = new int[n1+1];
int [] right = new int[n2+1];
int [] arr=new int[n1+n2];
for(i = 0; i<n1;i++){
left[i]= digits[p+i];
//System.out.print(left[i]+" ");
}
for(j = 0; j < n2; j++){
right[j]= digits[q+j+1];
//System.out.print(left[j]+" ");
}
left[n1] = Integer.MAX_VALUE / 2;
right[n2] = Integer.MAX_VALUE / 2;
for(i = 0; i < left.length; i++){
System.out.print(left[i] + " ");
}
System.out.println("left end -----m("+p+","+q+","+r+")");
for(j = 0; j < right.length; j++){
System.out.print(right[j]+" ");
}
System.out.println("right end -----m("+p+","+q+","+r+")");
i=0;
j=0;
for(k = p; k < r; k++){
if(left[i]<right[j]){
dummy[k]=left[i];
i++;
}
else {
dummy[k] = right[j];
j++;
}
}
while(i<n1)
dummy[k]=left[i];
i++;
k++;
System.out.println("remaining element left");
}
while(j<n2){
dummy[k]=right[j];
j++;
k++;
System.out.println("remaining element right");
}
for(int a: dummy){
System.out.print(a+" ");
}
}
}
For merge sort to work it needs to take results of previews smaller calculation and use them for next stage of calculation but your results are stored in dummy that is never used as source for the next calculation only as storage. I would sugest to make merge and mergeSort functions return values it is much more readable and cleaner here is my version if you want
public class MergeSort {
public static void main(String ...args){
int[]array = {9,6,5,0,8,2};
String sortedResultToPrint = Arrays.toString(sort(array));
System.out.println(sortedResultToPrint);
}
public static int[] sort(int[] array) {
int[] result = mergSort(array, 0, array.length-1);
return result;
}
private static int[] mergSort(int[] array, int start, int end) {
int[] result = null;
if (start < end) {
int midle = (start + end) / 2;
int[] left = mergSort(array, start, midle);
int[] right = mergSort(array, midle + 1, end);
result = merge(left, right);
} else {
result = new int[]{array[start]};
}
return result;
}
private static int[] merge(int[] left, int[] right) {
int[] result = new int[left.length + right.length];
int leftPtr = 0;
int rightPtr = 0;
for (int i = 0; i < result.length; i++) {
// Copyed all the left part only right remains
if (leftPtr >= left.length) {
result[i] = right[rightPtr++];
}
// Copyed all the right part only left remains
else if (rightPtr >= right.length) {
result[i] = left[leftPtr++];
}
//Right is smaller than left
else if (right[rightPtr] < left[leftPtr]) {
result[i] = right[rightPtr++];
}
// Left is smaller than right
else {
result[i] = left[leftPtr++];
}
}
return result;
}
}
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with and , the first 10 terms will be:
1,1,2,3,5,8,13,21,34,...
And here we should find the even numbers in Fibonacci series and add them to the sum
And the code :
import java.util.*;
public class Abhi {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
int[] n = new int[t];
int i,j;
long sum;
for(int a0 = 0; a0 < t; a0++){
n[a0] = in.nextInt();
}
//int an = n.length;
int[] nn = new int[1000];
nn[0]=1;
nn[1]=2;
for(i = 0 ; i<t;i++){
sum = 2;
for(j= 2;j<n[i];j++){
nn[j] = nn[j-2] + nn[j-1];
if(nn[j]%2==0 && nn[j]<n[i])
{
sum += nn[j];
//System.out.println(sum);
//the above line shows correct output
}
}
System.out.println(sum);//this is printing different output
}}}
Sample input :
1
100
Sample output :
44
Here problem in not with the outer System.out.println(sum); as you mentioned. It is because of int range.
Max value of int is 2 147 483 647 and in Fibonacci series 2 971 215 073 is in 47th position and as it exceeds the int range, it giving the results in unexpected manner.
In your code array nn holding -1323752223 instead of 2971215073 which is actually causing the issue.
To resolve this issue use BigInteger as below
BigInteger sum;
BigInteger[] nn = new BigInteger[1000];
nn[0] = new BigInteger("1");
nn[1] = new BigInteger("2");
for (i = 0; i < t; i++) {
sum = new BigInteger("2");
for (j = 2; j < n[i]; j++) {
nn[j] = nn[j - 2].add(nn[j - 1]);
if (nn[j].mod(new BigInteger("2")).equals(new BigInteger("0")) &&
nn[j].compareTo(new BigInteger(String.valueOf(n[i])))<0) {
sum = sum.add(nn[j]);
System.out.println(sum);
}
}
System.out.println(sum);
}
You can also achieve this by using below code:
import java.util.Scanner;
public class Fibo
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int No = sc.nextInt();
int fNo1 = 1;
int fNo2 = 1;
int fNo3 = fNo1 + fNo2;
int sumofEvenNo = 0;
int i;
while( fNo3 < No)
{
if(fNo3 % 2 == 0)
sumofEvenNo += fNo3;
fNo1 = fNo2;
fNo2 = fNo3;
fNo3 = fNo1 + fNo2;
}
System.out.println("Sum of all even nos = "+sumofEvenNo);
}
}
I suggest using naming convention, your code will be more clear and easy to debug. I'm using a static method to get the sum also.
Ask how many times the sum will be calculated.
Get the index and calculate the sum.
Print.
Class:
import java.util.*;
public class Abhi {
public static void main(String[] args) {
System.out.println ( "This program will calculate the even sum of given fibonacci series index ( index starts at 1) " );
System.out.println ( "Please enter how many times do you want to calculate the sum: " );
Scanner scan = new Scanner(System.in);
int iterationTimes = scan.nextInt() ;
for (; iterationTimes > 0; iterationTimes-- )
{
System.out.println ( "Please, enter the index on fibonacci: " );
System.out.println ( "Even sum: " + getEvenSum( scan.nextInt() ) );
}
}
private static long getEvenSum( int index)
{
if ( index <= 2 )
{
return 0;
}
long n1=1, n2=1, n3, sum = 0;
for(int i = 2; i < index; i++)
{
n3=n1+n2;
if ( n3 % 2 == 0)
{
sum += n3;
}
n1=n2;
n2=n3;
}
return sum;
}
}
I/O Example:
This program will calculate the even sum of given fibbonacci series index ( index starts at 1 )
Please enter how many times do you want to calculate the sum:
3
Please, enter the index on fibbonacci:
3
Even sum: 2
Please, enter the index on fibbonacci:
6
Even sum: 10
Please, enter the index on fibbonacci:
12
Even sum: 188
Note: Fibbonaci: 1, 1, 2, 3 ...
I'm a beginner, and I'm trying to write a working travelling salesman problem using dynamic programming approach.
This is the code for my compute function:
public static int compute(int[] unvisitedSet, int dest) {
if (unvisitedSet.length == 1)
return distMtx[dest][unvisitedSet[0]];
int[] newSet = new int[unvisitedSet.length-1];
int distMin = Integer.MAX_VALUE;
for (int i = 0; i < unvisitedSet.length; i++) {
for (int j = 0; j < newSet.length; j++) {
if (j < i) newSet[j] = unvisitedSet[j];
else newSet[j] = unvisitedSet[j+1];
}
int distCur;
if (distMtx[dest][unvisitedSet[i]] != -1) {
distCur = compute(newSet, unvisitedSet[i]) + distMtx[unvisitedSet[i]][dest];
if (distMin > distCur)
distMin = distCur;
}
else {
System.out.println("No path between " + dest + " and " + unvisitedSet[i]);
}
}
return distMin;
}
The code is not giving me the correct answers, and I'm trying to figure out where the error is occurring. I think my error occurs when I add:
distCur = compute(newSet, unvisitedSet[i]) + distMtx[unvisitedSet[i]][dest];
So I've been messing around with that part, moving the addition to the very end right before I return distMin and so on... But I couldn't figure it out.
Although I'm sure it can be inferred from the code, I will state the following facts to clarify.
distMtx stores all the intercity distances, and distances are symmetric, meaning if distance from city A to city B is 3, then the distance from city B to city A is also 3. Also, if two cities don't have any direct paths, the distance value is -1.
Any help would be very much appreciated!
Thanks!
Edit:
The main function reads the intercity distances from a text file. Because I'm assuming the number of cities will always be less than 100, global int variable distMtx is [100][100].
Once the matrix is filled with the necessary information, an array of all the cities are created. The names of the cities are basically numbers. So if I have 4 cities, set[4] = {0, 1, 2, 3}.
In the main function, after distMtx and set is created, first call to compute() is called:
int optRoute = compute(set, 0);
System.out.println(optRoute);
Sample input:
-1 3 2 7
3 -1 10 1
2 10 -1 4
7 1 4 -1
Expected output:
10
Here's a working iterative solution to the TSP with dynamic programming. What would make your life easier is to store the current state as a bitmask instead of in an array. This has the advantage that the state representation is compact and can be cached easily.
I made a video detailing the solution to this problem on Youtube, please enjoy! Code was taken from my github repo
/**
* An implementation of the traveling salesman problem in Java using dynamic
* programming to improve the time complexity from O(n!) to O(n^2 * 2^n).
*
* Time Complexity: O(n^2 * 2^n)
* Space Complexity: O(n * 2^n)
*
**/
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
public class TspDynamicProgrammingIterative {
private final int N, start;
private final double[][] distance;
private List<Integer> tour = new ArrayList<>();
private double minTourCost = Double.POSITIVE_INFINITY;
private boolean ranSolver = false;
public TspDynamicProgrammingIterative(double[][] distance) {
this(0, distance);
}
public TspDynamicProgrammingIterative(int start, double[][] distance) {
N = distance.length;
if (N <= 2) throw new IllegalStateException("N <= 2 not yet supported.");
if (N != distance[0].length) throw new IllegalStateException("Matrix must be square (n x n)");
if (start < 0 || start >= N) throw new IllegalArgumentException("Invalid start node.");
this.start = start;
this.distance = distance;
}
// Returns the optimal tour for the traveling salesman problem.
public List<Integer> getTour() {
if (!ranSolver) solve();
return tour;
}
// Returns the minimal tour cost.
public double getTourCost() {
if (!ranSolver) solve();
return minTourCost;
}
// Solves the traveling salesman problem and caches solution.
public void solve() {
if (ranSolver) return;
final int END_STATE = (1 << N) - 1;
Double[][] memo = new Double[N][1 << N];
// Add all outgoing edges from the starting node to memo table.
for (int end = 0; end < N; end++) {
if (end == start) continue;
memo[end][(1 << start) | (1 << end)] = distance[start][end];
}
for (int r = 3; r <= N; r++) {
for (int subset : combinations(r, N)) {
if (notIn(start, subset)) continue;
for (int next = 0; next < N; next++) {
if (next == start || notIn(next, subset)) continue;
int subsetWithoutNext = subset ^ (1 << next);
double minDist = Double.POSITIVE_INFINITY;
for (int end = 0; end < N; end++) {
if (end == start || end == next || notIn(end, subset)) continue;
double newDistance = memo[end][subsetWithoutNext] + distance[end][next];
if (newDistance < minDist) {
minDist = newDistance;
}
}
memo[next][subset] = minDist;
}
}
}
// Connect tour back to starting node and minimize cost.
for (int i = 0; i < N; i++) {
if (i == start) continue;
double tourCost = memo[i][END_STATE] + distance[i][start];
if (tourCost < minTourCost) {
minTourCost = tourCost;
}
}
int lastIndex = start;
int state = END_STATE;
tour.add(start);
// Reconstruct TSP path from memo table.
for (int i = 1; i < N; i++) {
int index = -1;
for (int j = 0; j < N; j++) {
if (j == start || notIn(j, state)) continue;
if (index == -1) index = j;
double prevDist = memo[index][state] + distance[index][lastIndex];
double newDist = memo[j][state] + distance[j][lastIndex];
if (newDist < prevDist) {
index = j;
}
}
tour.add(index);
state = state ^ (1 << index);
lastIndex = index;
}
tour.add(start);
Collections.reverse(tour);
ranSolver = true;
}
private static boolean notIn(int elem, int subset) {
return ((1 << elem) & subset) == 0;
}
// This method generates all bit sets of size n where r bits
// are set to one. The result is returned as a list of integer masks.
public static List<Integer> combinations(int r, int n) {
List<Integer> subsets = new ArrayList<>();
combinations(0, 0, r, n, subsets);
return subsets;
}
// To find all the combinations of size r we need to recurse until we have
// selected r elements (aka r = 0), otherwise if r != 0 then we still need to select
// an element which is found after the position of our last selected element
private static void combinations(int set, int at, int r, int n, List<Integer> subsets) {
// Return early if there are more elements left to select than what is available.
int elementsLeftToPick = n - at;
if (elementsLeftToPick < r) return;
// We selected 'r' elements so we found a valid subset!
if (r == 0) {
subsets.add(set);
} else {
for (int i = at; i < n; i++) {
// Try including this element
set |= 1 << i;
combinations(set, i + 1, r - 1, n, subsets);
// Backtrack and try the instance where we did not include this element
set &= ~(1 << i);
}
}
}
public static void main(String[] args) {
// Create adjacency matrix
int n = 6;
double[][] distanceMatrix = new double[n][n];
for (double[] row : distanceMatrix) java.util.Arrays.fill(row, 10000);
distanceMatrix[5][0] = 10;
distanceMatrix[1][5] = 12;
distanceMatrix[4][1] = 2;
distanceMatrix[2][4] = 4;
distanceMatrix[3][2] = 6;
distanceMatrix[0][3] = 8;
int startNode = 0;
TspDynamicProgrammingIterative solver = new TspDynamicProgrammingIterative(startNode, distanceMatrix);
// Prints: [0, 3, 2, 4, 1, 5, 0]
System.out.println("Tour: " + solver.getTour());
// Print: 42.0
System.out.println("Tour cost: " + solver.getTourCost());
}
}
I know this is pretty old question but it might help somebody in the future.
Here is very well written paper on TSP with dynamic programming approach
https://github.com/evandrix/SPOJ/blob/master/DP_Main112/Solving-Traveling-Salesman-Problem-by-Dynamic-Programming-Approach-in-Java.pdf
I think you have to make some changes in your program.
Here there is an implementation
http://www.sanfoundry.com/java-program-implement-traveling-salesman-problem-using-nearest-neighbour-algorithm/
I am trying to put java code for fibonacci search with my understanding gained from
http://en.wikipedia.org/wiki/Fibonacci_search :
Let k be defined as an element in F, the array of Fibonacci numbers. n = Fm is the array size. If the array size is not a Fibonacci number, let Fm be the smallest number in F that is greater than n.
The array of Fibonacci numbers is defined where Fk+2 = Fk+1 + Fk, when k ≥ 0, F1 = 1, and F0 = 0.
To test whether an item is in the list of ordered numbers, follow these steps:
Set k = m.
If k = 0, stop. There is no match; the item is not in the array.
Compare the item against element in Fk−1.
If the item matches, stop.
If the item is less than entry Fk−1, discard the elements from positions Fk−1 + 1 to n. Set k = k − 1 and return to step 2.
If the item is greater than entry Fk−1, discard the elements from positions 1 to Fk−1. Renumber the remaining elements from 1 to Fk−2, set k = k − 2, and return to step 2.
The below is my code:
package com.search.demo;
public class FibonacciSearch {
static int[] a = {10,20,30,40,50,60,70,80,90,100};
static int required = 70;
static int m = 2;
static int p = 0;
static int q = 0;
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
FibonacciSearch fs = new FibonacciSearch();
fs.findm();
fibSearch(required);
}
private void findm(){
//here you have to find Fm which matches size of searching array, or which is close to it.
int n = a.length;
int fibCurrent = 1;
int fibPrev1 = 1;
int fibPrev2 = 0;
while(n > fibCurrent){
fibPrev2 = fibPrev1;
fibPrev1 = fibCurrent;
fibCurrent = fibPrev1 + fibPrev2;
m++;
}
p = m-1;
q = m-2;
}
public static int fibSearch(int no){
for(;;){
if(m == 0){
System.out.println("not found");
return -1;
}
int j = f(p);
if(no == a[j]){
System.out.println("found at "+p);
}else if(no < a[j]){
m = p;
p = m - 1;
q = m - 2;
}else if(no > a[j]){
m = q; // as per the step 6..
p = m-1;
q = m-2;
}
}
//return m;
}
public static int f(int val){
if(val == 2 || val == 1 || val == 0){
return 1;
}
return (f(val-1) + f(val-2));
}
}
Please correct me what I am doing wrong, and help me understand it clearly..
I have seen this Fibonacci Search and http://www.cs.utsa.edu/~wagner/CS3343/binsearch/searches.html but I am not able to understand..
while(n > fibCurrent){
fibPrev2 = fibPrev1;
fibPrev1 = fibCurrent;
fibCurrent = fibPrev1 + fibPrev2;
m++;
}
This part in the findm() function is actually comparing nth fibonacci number but according to algorithm it should be cumulative sum of the fibonacci numbers upto that point.
Rather you can search for the element in while loop of findm.
Finally I am able to solve the puzzle, that's stopping me..
I think the below code should help someone who are stuck as I did.
package com.search.demo;
public class FibonacciSearch {
int a[] = {10,20,30,40,50,60,70,80,90,100};
static FibonacciSearch fs;
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
fs = new FibonacciSearch();
int location = fs.find(70);
if(location < 0){
System.out.println("number not found..");
}else{
System.out.println("found at location "+location);
}
}
private int find(int no){
int n = a.length;
int m = findFm(n); //m = Fm iff n is Fibonacci number else returns Fm+1
int p = fibSequenceIterative(m-1); //p = Fm-1, always a fibonacci number
int q = fibSequenceIterative(m -2); //q = Fm-2, always a fibonacci number
while(true){
if(no == a[m]){
return m;
}else if (no < a[m]){
if(q == 0){
return -(m - 1);// we crossed 0th index in array, number not found.
}
m = m - q; //moved to 1 step left towards a fibonacci num
int tmp = p;//hold this temporarily
p = q; //move p to 1 step left into another fibonacci num
q = tmp - q;//moved q to 1 step left....
}else if(no > a[m]){
if(p == 1){
return -m;//we reached 0th index in array again and number not found..
}
m = m + q;
p = p - q;
q = q - p;
}
}
}
private int findFm(int n){
int prev = 1;
int curr = 1;
int next = 0;
if(n == 0){
next = 0;
return -1;
}else if(n == 1 || n == 2){
next = 1;
return 1;
}else{
for(int i = 3; ; i++){
next = prev + curr;
prev = curr;
curr = next;
System.out.println("prev = "+prev+" curr = "+curr+" next = "+next);
if(n <= curr){
System.out.println("n = "+n+" curr = "+curr);
return i;
}
}
//return -1;//we should not get here..
}
}
/* Iterative method for printing Fibonacci sequence..*/
private int fibSequenceIterative(int n){
int prev = 1;
int curr = 1;
int next = 0;
if(n == 0){
next = 0;
//return 0;
}else if(n == 1 || n == 2){
next = 1;
//return 1;
}else{
for(int i = 3; i <= n; i++){
next = prev + curr;
prev = curr;
curr = next;
}
return next;
}
return next;
}
}
The bit of code what I am doing wrong is managing the indexes, which does influence the position of dividing the array at an index postion.
the m should be find first, to the value that matches n (size of array). if it doesn't match it should be the next value at which the F(x) will be > n. i.e., in my case size is 10 which doesn't match with any fibonacci number, so the next value in the fibonacci series is 13. and the index of i at which our condition satisfied is F(7) = 13 which is > 10. So m = 7
and now p and q are 2 consecutive fibonacci numbers which always determine the interval at which to divide the array.
read the below:
Take N = 54, so that N+1 = 55 = F[10]. We will be searching the sorted array: A[1], ..., A[54], inclusive. The array indexes are strictly between the two Fibonacci number: 0 < 55. Instead of the midpoint, this search uses the next Fibonacci number down from F[10] = 55, namely F[9] = 34. Instead of dividing the search interval in two, 50% on either side, we divide roughly by the golden ratio, roughly 62% to the left and 38% to the right. If y == A[34], then we've found it. Otherwise we have two smaller intervals to search: 0 to 34 and 34 to 55, not including the endpoints. If you have two successive Fibonacci numbers, it's easy to march backwards using subtraction, so that above, the next number back from 34 is 55 - 34 = 21. We would break up 0 to 34 with a 21 in the middle. The range from 34 to 55 is broken using the next Fibonacci number down: 34 - 21 = 13. The whole interval [34, 55] has length 21, and we go 13 past the start, to 34 + 13 = 47. Notice that this is not a Fibonacci number -- it's the lengths of all the intervals that are.(copied from http://www.cs.utsa.edu/~wagner/CS3343/binsearch/fibsearch.html)