Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
In some programming contest, I saw this question:
A person wants to travel some cities and come back to the city where
he/she started. Total 5 cities are present and each city is connected
to its adjacent city i.e.: c1 - c2, c2 - c3, c3 - c4, c4 - c5, c5 -
c1. The person will start the journey from city 1. Also, the person
has some limited number of trips to use for traveling. Traveling from one city to another costs him/her 1 trip. We need to find the
total number of ways a person can travel the given cities and come
back to city 1 using the allocated number of trips.
Example:
Input: 4
(means 4 trips are allowed)
Output: 6
(As the output can be large, so it should be modulo 10^9+7)
the possible ways are:
1-2-1-2-1
1-2-1-5-1
1-5-1-2-1
1-5-1-5-1
1-2-3-2-1
1-5-4-5-1
If the question has limits on the number of trips to be less than 10^9 then its easy to solve as the problem has optimal substructure and overlapping subproblems. But the constraint given was 1<=n<=10^18. I couldn't initialize an array with a dimension that long, so couldn't apply dp. Please help me on how to solve this using dp. Or is this question just a permutation or combinations type of question?
Thanks.
I would suggest:
Store the number of ways to reach each city in a vector
Work out a matrix that allows you to update this vector by 1 step
Raise the matrix to the power n using binary exponentiation
Multiple this power matrix by the starting vector (1,0,0,0,0)
Read off in entry 1 the number of ways to reach city 1 after n steps
(edit)
Sorry read your question a bit too fast.
If all cities are connected then this is a simple permutation problem.
If not you can see it as a graph problem and solve it with an extended breadth first search that caps off as soon as you have reached the limit of possible trips.
This problem is purely mathematical; the answer is a mathematical formula which, once computed on paper, you just plot in your program.
You can reach the initial point either by going back and forth (requiring a multiple of 2 steps), or by doing complete circles(requiring a multiple of 5 steps). Thus you need to check the divisibility of n with 2 and 5, or, to put it in a mathematical form, check if n=2*k or n=5*q. We will compute the number of paths independently for the 2 cases, but if n is divisible with both 2 and 5, we will add the two results (since n steps can be done in both ways, either as a multiple of 2 or multiple of 5).
If n=5*q, we will do our n steps as q cycles of 5 steps. Each cycle can be in either direction, clockwise or counter clockwise. For the first cycle, there are 2 possibilities (the 2 directions), for the second cycle, another 2 possibilities, independent of the previous cycle, and so on. Thus, the number of paths is 2*2*2... = 2q .
If n=2*k, we will do our n steps as k back-and-forth paths (one step forward, one step backward). For each of these k paths, there are two directions to go, thus, for k closed-paths, there are 2k paths.
Note: I have given the name back-and-forth path, or closed path, for paths such as 1-2-1. Actually, from the graph theory perspective, they are cycles too, but i did not name them cycles as not to confound them with the 1-2-3-4-5-1 cycles.
The above computation, however, does not take into account the paths such as 1-2-3-2-1, but only 1-2-1-2-1, or 1-2-1-5-1. I am still working on that> I will post this answer the way it is right now as to give inspiration on how the computation might look like.
Another aspect to take into account is the number of ways we could write n as 2*a + 5*b, giving 2a * 5b paths. I think n=2*a+5*b is a dyophantic equation.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 months ago.
Improve this question
I need to generate random numbers between 100 and 500 where the mean is 150.
I've been reading on distribution curves and probability density functions but can't find a concrete solution to this question.
Any help is appreciated.
I can think of two possible approaches you might take. One would be to take something like a normal distribution but that might lead to values outside your range. You could discard those samples and try again, but doing so would alter your mean. So this is probably the more complicated approach.
The other alternative, the one I would actually suggest, is to start with a uniform distribution in the range 0 to 1. Then transform that number so the result has the properties you want.
There are many such transformations you could employ. In the absence of any strong rationale for something else, I would probably go for some formula such as
y = pow(x, a) * b + c
In that formula x would be uniformly distributed in the [0, 1] range, while y should have the bounds and mean you want, once the three parameters have been tuned correctly.
Using b=400 and c=100 you can match the endpoints quite easily, because a number from the [0, 1] range raised to any power will again be a number from that range. So now all you need is determine a. Reversing the effect of b and c you want pow(x, a) to have an mean of (150 - c) / b = 1/8 = 0.125.
To compute the mean (or expected value) in a discrete distribution, you multiply each value with its probability and sum them up. In the case of a continuous distribution that becomes the integral over value times probability density function. The density function of our uniform distribution is 1 in the interval and 0 elsewhere. So we just need to integrate pow(x, a) from 0 to 1. The result of that is 1 / (a + 1) so you get
1 / (a + 1) = 1 / 8
a + 1 = 8
a = 7
So taking it all together I'd suggest
return Math.pow(random.nextDouble(), 7) * 400 + 100
If you want to get a feeling for this distribution, you can consider
x = pow((y - c) / b, 1 / a)
to be the cumulative distribution function. The density would be the derivative of that with respect to y. Ask a computer algebra system and you get some ugly formula. You might as well ask directly for a plot, e.g. on Wolfram Alpha.
That probability density is actually infinite at 100, and then drops quickly for larger values. So one thing you don't get from this approach is a density maximum at 150. If you had wanted that, you'd need a different approach but getting both density maximum and expected value at 150 feels really tricky.
One more thing to consider would be reversing the orientation. If you start with b=-400 and c=500 you get a=1/7. That's a different distribution, with different properties but the same bounds and mean. If I find the time I'll try to plot a comparison for both of these.
Create a List of numbers that have the mean value you want, they can be in any order to reach just this property (so you could just count up or whatever).
Then use Collections.shuffle to randomize the order of the list.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 8 years ago.
Improve this question
I have to write a program that gives all permutatioms of a number. For example, the user enters the number 4. I have to return all possible combinations of the numbers 1,2,3,4. I am having an issue with a good method for getting all of the permutations. I have it so my program puts the number 1-n in an array. However, I cannot think of a good way of getting permutation. I know I need to use recursion, but my issue is a way to get the permutations in the first place. I know switching the number around is probably the best way to go, but what is the best method for doing that?
The easiest way to understand the algorithm is this. To get all the permutations of 1 to 4, you want
1, followed by the permutations of 2,3,4
2, followed by the permutations of 1,3,4
3, followed by the permutations of 1,2,4
4, followed by the permutations of 1,2,3
This is a fairly standard bit of recursion. For each number, recursively find all the permutations of the other numbers, and add this number on the beginning.
We can simply use the recursion to get the possibilities by recursively selecting one element and then applying the recursion to the sub set of that array. this is an example for numbers 1 to 3
Recursion is your friend. If you have one element, your solution is obviously [[1]]. For two elements, you can take all your "one"-solutions (well, there is only one) and stick the 2 either before or after the 1, so you get [[2,1], [1,2]]. For three elements, take all your "two" solutions and put the three in first, second or third position. From [2,1] you get [3,2,1], [2,3,1] and [2,1,3]. From [1,2] you get [3,1,2], [1,3,2] and [1,2,3]. All together, your solution is [[3,2,1], [2,3,1], [2,1,3], [3,1,2], [1,3,2], [1,2,3]].
Notice how chiastic-security's algorithm for generating all permutations of n numbers relies on being able to generate all permutations of n-1 numbers? To use his algorithm, all we need is that ability, and one more thing: a way to generate all permutations of a set containing just one number.
Generating all permutations of a single number is trivial: there's only one, consisting of just that number by itself.
What about the other requirement -- the ability to generate all permutations of n-1 numbers? That seems harder, but it turns out not to be. Suppose n=2 for the problem we want to solve: then n-1 = 1, and then we're OK, because we know how to generate all permutations of 1 number. So, applying chiastic-security's algorithm here gives us a way to generate all permutations of 2 numbers. If instead n=3 for the problem we want to solve, then n-1 = 2, and we've just established that we can generate all permutations of 2 numbers, so we're still OK -- we know how to generate all permutations of 3 numbers. If instead n=4, then n-3 = 3, and we've just established that we can generate all permutations of 3 numbers, so we can also generate all permutations of 4 numbers. Clearly this reasoning can continue on forever -- so you can generate all permutations of any number of numbers this way.
That reasoning is informal, but it can be made completely precise with mathematical induction. If induction can be applied, then the surprising result is that we never have to solve any "big" problems "the hard way" -- we can always break them down into one or more small problems, which can in turn be broken into still smaller problems, until one or more "base cases" are reached that are easy to solve -- and then the solutions to the bigger problems can be pieced together from these solutions to the simpler subproblems.
I am trying to solve the following problem:
I have a list of 30 people.
These people need to be divided into groups of 6.
Each person has given the names of 3 other people who they would like to be in a group with.
I thought of solving this problem using a genetic algorithm.
The fitness function could evaluate all the groups, and assign a fitness score based on how many people per room have all their preferences met. (or a scoring system similar to that)
Example:
One of the generated solutions is: 1,3,19,5,22,2,7,8,11,12,13,14,15,13,17....etc
I would assume the first 5 people are in the first group, and the next 5 in the the next group and calculate a fitness value from that.
I think that this solution would work - does anyone see a better way of doing this?
My main question is this:
If I want to make sure person A and B are definitely in the same group, I could implement the fitness function to check for this and assign a terrible fitness if this condition isn't met. Is this the best way to do it? It seems quite inefficient.
Is there a way to 'lock' certain parts of the solution ("certain genes") and just solve or the remainder?
Any help or insights will be appreciated.
Thanks in advance.
AK
Just to clarify a bit, your problem isn't about genetic programming but genetic algorithms, which are two different things. Genetic programming is about generating (using evolutionary algorithms) executable individuals that will generate your solutions while genetic algorithms individuals represent directly your solutions.
That being said, your two assumptions are corrects. Data representation is a key element of evolutionary algorithms in general and a bad representation may hinder efficient solution space exploration. Your current data representation seems correct to me, given groups are only allowed to have exactly 5 individuals. Your second thought about the way to enforce some criteria is also right. Putting a large fitness value (preferably one that can't represent a potentially valid even if bad solution) such as infinity (if your library / language allows it easily) is the preferred way to express invalid solutions in literature. This has multiple advantages over simply deleting invalid individuals: During the selection stage, bad individuals won't be selected and thus the solution space they represent won't be explored as much as interesting ones, which is computationally good because it surely won't contain optimal solutions. Knowing a solution is bad is good knowledge, after all. At the same time, genetic diversity is really important in evolutionary algorithms in order to avoid stagnation. At least some bad individual should be kept for the sake of genetic diversity in order to explore solution spaces between currently represented zones.
The goal of genetic algorithms is to compute solutions that are either impossible or too hard to compute analytically or by brute-force. Trying to dynamically lock down some genes with heuristics would require much knowledge about the inner working of your problems as well as the underlying evolution mechanisms and would be defeating the purpose of using evolutionary algorithms. The effective goal of evolutionary algorithms is to lock down genes that seems correct.
In fact, if you are a priori absolutely positively certain that some given genes must have a given value, don't represent them in your individuals. For instance, make your first group 3 individuals long if you are sure that the 2 others must be of some given value. You can then code your evaluation function as if there was 5 individuals in the first group but won't be evolving / searching to replace the 2 fixed ones.
What does your crossover operation look like? The way you have it laid out in your description, I'm not sure how you implement it cleanly. For instance if you have two solutions:
1, 2, 3, 4, 5, ....., 30
and
1, 2, 30, 29,......,10
Assuming you're using single point crossover function, you would have the potential to get multiple assignments for the same people and other people not being assigned at all using the genomes above.
I would have a genome with 30 values, where each value defines a person's group assignment (1-6). It would look like 656324113255632....etc. So person 1 is assigned group 6, person 2 group 5, etc. This would make the crossover operation easier to implement, because you don't have to ensure that after crossover each new solution is a valid assignment regardless of whether it's optimal.
The fitness function would assign a penalty for each group not having the proper number of members (5), and additional penalties for group member assignments that are suboptimal. I would make the first penalty significantly larger than the second, and then adjust these to get the results you're looking for.
This can be modeled as a generalized quadratic assignment problem (GQAP). This problem allows to specify a number of equipment (people) that demand a certain capacity, a number of locations (groups) that offer a capacity and the weights matrix that specifies the closeness between equipment and the distance matrix specifying the distance between locations. Additionally, there are install costs, but these are not required for your problem. I have implemented this problem in HeuristicLab. It's not part of the trunk, but I can send you the plugin if you're interested (or you compile it yourself).
It seems that the most challenging part of using a genetic algorithm for this problem is implementing the crossover. Here's how I would do it:
First choose a constant, C. C will stay constant throughout all generations, and I will explain it's purpose in a moment.
I will use a smaller example than 5 groups of 6 to demonstrate this crossover, but the premise is the same. Say we have 2 parents, each consisting of 3 groups of 3. Let's make one [[1,2,3],[4,5,6],[7,8,9]], and the other [[9,4,3],[5,7,8],[6,1,2]].
Make a list of possible numbers (1 through total number of people), in this case it is simply [1,2,3,4,5,6,7,8,9]. Remove 1 random number from the list. Let's say we remove 2. The list becomes [1,3,4,5,6,7,8,9]
We assign each remaining number a probability. The probability starts at 1, and goes up by C for any matches with the parents. For example, in parent 1, 3 and 2 are in the same group so 3 would have a probability of 1+C. Same thing with 6 because it forms a match in parent 2. 1 would have a probability of 1+2C, because it is in the same group as 2 in both parents. Based on these probabilities, use a roulette wheel type selection. Let's say we pick 6.
Now, we have 2 and 6 in the same group. We similarly look for matches with these numbers and make probabilities. For each parent, we add C if it matches with only 2 or only 6, and 2C if it matches with both. Continue this until the group is done (for 3x3 this is the last selection, but for 5x6 there would be a few more)
4.Choose a new random number that has not been picked and continue for other groups
One of the good things about this crossover, is that it basically includes mutations already. There are chances built in to group people that were not grouped in their parents
Credit: I adapted the idea from the Omicron Genetic Algorithm
I'm look for the "how do you find it" because I have no idea how to approach finding the algorithm complexity of my program.
I wrote a sudoku solver using java, without efficiency in mind (I wanted to try to make it work recursively, which i succeeded with!)
Some background:
my strategy employs backtracking to determine, for a given Sudoku puzzle, whether the puzzle only has one unique solution or not. So i basically read in a given puzzle, and solve it. Once i found one solution, i'm not necessarily done, need to continue to explore for further solutions. At the end, one of three possible outcomes happens: the puzzle is not solvable at all, the puzzle has a unique solution, or the puzzle has multiple solutions.
My program reads in the puzzle coordinates from a file that has one line for each given digit, consisting of the row, column, and digit. By my own convention, the upper left square of 7 is written as 007.
Implementation:
I load the values in, from the file, and stored them in a 2-D array
I go down the array until i find a Blank (unfilled value), and set it to 1. And check for any conflicts (whether the value i entered is valid or not).
If yes, I move onto the next value.
If no, I increment the value by 1, until I find a digit that works, or if none of them work (1 through 9), I go back 1 step to the last value that I adjusted and I increment that one (using recursion).
I am done solving when all 81 elements have been filled, without conflicts.
If any solutions are found, I print them to the terminal.
Otherwise, if I try to "go back one step" on the FIRST element that I initially modified, it means that there were no solutions.
How can my programs algorithm complexity? I thought it might be linear [ O(n) ], but I am accessing the array multiple times, so i'm not sure :(
Any help is appreciated
O(n ^ m) where n is the number of possibilities for each square (i.e., 9 in classic Sudoku) and m is the number of spaces that are blank.
This can be seen by working backwards from only a single blank. If there is only one blank, then you have n possibilities that you must work through in the worst case. If there are two blanks, then you must work through n possibilities for the first blank and n possibilities for the second blank for each of the possibilities for the first blank. If there are three blanks, then you must work through n possibilities for the first blank. Each of those possibilities will yield a puzzle with two blanks that has n^2 possibilities.
This algorithm performs a depth-first search through the possible solutions. Each level of the graph represents the choices for a single square. The depth of the graph is the number of squares that need to be filled. With a branching factor of n and a depth of m, finding a solution in the graph has a worst-case performance of O(n ^ m).
In many Sudokus, there will be a few numbers that can be placed directly with a bit of thought. By placing a number in the first empty cell, you give up on a lot of opportunities to reduce the possibilities. If the first ten empty cells have lots of possibilities, you get exponential growth. I'd ask the questions:
Where in the first line can the number 1 go?
Where in the first line can the number 2 go?
...
Where in the last line can the number 9 go?
Same but with nine columns?
Same but with the nine boxes?
Which number can go into the first cell?
Which number can go into the 81st cell?
That's 324 questions. If any question has exactly one answer, you pick that answer. If any question has no answer at all, you backtrack. If every question has two or more answers, you pick a question with the minimal number of answers.
You may get exponential growth, but only for problems that are really hard.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can you answer this 2009 ACM International Collegiate Programming Contest Finals problem?
Hi,
I am attempting to do question 1 here-> http://cm.baylor.edu/ICPCWiki/attach/Problem%20Resources/2009WorldFinalProblemSet.pdf
and cannot really come up with a good algorithm to solve it :
Basically, there are n planes, n is read in from standard input. There are then n intervals for times in which the planes can arrive, you must compute the largest interval between all planes that is possible. So, say
n = 3
and you are given the inputs
0 10
5 15
10 15
The answer is : 7: 30, the largest possible interval between planes.
Not really sure how I would go about solving this. Any tips ?
For the first plane, select the earliest possible arrival time
For the last plane, select the latest possible arrival time
For elements 2 through element n-1:
Search for a midpoint plane by dividing the range between element 1 and element n
(Hopefully, that will be close to the element n/2)
recursivly call the same function for element 1 and the midpoint element
recursivly call the same function for the element after the midpoint element and element n
That will evenly divide up the time available within the constraints of the planes scheduled windows.
Once you have roughly evenly spaced windows, select the smallest window and test it with its neighboring planes to see if they can shift some to expand the smallest window. Repeat this process until the smallest window can't shift a significent amount.