Related
I need to draw an n sample from the uniform distribution on the interval [a,b] such that no two numbers are closer than d > 0. I can draw a sample and check this property and then throw it away and try again if not, but if n is large relative to b-a that could take a looong time. Is there a simple and nice algorithm to solve this problem? The numbers got to be uniformly distributed on [a,b], no deterministic setup.
This problem is equivalent to choosing n numbers greater than or equal to d and whose sum is equal to b - a.
There will be some solution provided that n * d <= b - a. We can write a recursive algorithm that looks for one:
b - a - X < (n - 1) * D
X > b - a - (n - 1) * d
FindSpacedSample(n, d, a, b)
1. if n * d > b - a then return "no solution"
2. avail = [d, b - a - (n - 1) * d]
3. guess = random(avail)
4. print(guess)
5. FindSpacedSample(n - 1, d, a + guess, b)
Example: n = 5, a = 0, b = 10, d = 1, assuming real numbers
FindSpacedSample(5, 1, 0, 10)
5 * 1 >? b - a? no
avail = [1, 10 - 0 - 4 * 1] = [1, 6]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(4, 1, 2, 10)
4 * 1 >? 10 - 2? no
avail = [1, 10 - 2 - 3 * 1] = [1, 5]
guess = random(avail) = 4 (for the sake of argument)
print(4)
FindSpacedSample(3, 1, 6, 10)
3 * 1 >? 10 - 6? no
avail = [1, 10 - 6 - 2 * 1] = [1, 2]
guess = random(avail) = 1 (for the sake of argument)
print(1)
FindSpacedSample(2, 1, 7, 10)
2 * 1 >? 10 - 7? no
avail = [1, 10 - 7 - 1 * 1] = [1, 2]
guess = random(avail) = 2 (for the sake of argument)
print(2)
FindSpacedSample(1, 1, 9, 10)
1 * 1 >? 10 - 9? no
avail = [1, 10 - 9 - 0 * 1] = [1, 1]
guess = 1
print(1)
We should also have stopping condition n = 0. Then we get the sequence of spaces 2, 4, 1, 2, 1; we see these sum to ten; and we can get the values as follows:
point1 = 2 = 2
point2 = 2 + 4 = 6
point3 = 2 + 4 + 1 = 7
point4 = 2 + 4 + 1 + 2 = 9
point5 = 2 + 4 + 1 + 2 + 1 = 10
Now, there are a couple of ways in which this result is less than totally uniform:
the first number will never be less than d
earlier numbers tend to be spaced further apart
We can fix these by:
shuffling the spacings before converting to points
subtracting from each point some random value from [0, point1 - a].
So, if we shuffled 2, 4, 1, 2, 1 to 4, 1, 1, 2, 2 we'd get points 4, 5, 6, 8, 10; and if we subtracted 3 from each one (taken randomly between 0 and 4) we'd get 1, 2, 3, 5, 7.
Does this give you a uniform distribution over the set of all possible solutions? I'd be surprised if it did, but I'd also be surprised if what this does give you differs from that truly uniform distribution to an appreciable degree.
Solve[{A + B = 3, 2 A + B = 5}, {A, B}]
evaluates to A = 2, B = 1.
How can I Print the result like this
W = 2 + 1 * Sinx
Study https://reference.wolfram.com/language/ref/ReplaceAll.html and then try
Print[W==A+B*Sinx/.Solve[{A+B==3, 2A+B==5}, {A,B}][[1]]]
which prints
W==2+Sinx
because Mathematica automatically simplifies 1*Sinx to Sinx
I would appreciate if someone could explain why the output of this code:
*a, b = [1, 2, 3, 4]
a[b-2] + b
is 7. Could anyone please break it down line by line so I understand what's going on here? How does this become 7?
To break anything down line by line one could use REPL:
*a, b = [1, 2, 3, 4]
#⇒ [1, 2, 3, 4]
a
#⇒ [1, 2, 3]
b
#⇒ 4
Using splat operator, we have decomposed the original array to new array and the single value. Now everything is crystal clear: a[b-2] which is a[2], which is in turn 3 (check a array.) and b is still 4.
3 + 4
#⇒ 7
when you assign array like this,
*a, b = [1, 2, 3, 4]
then it will assign
a = [1,2,3]
and b = 4
Now when you tried to print a[b-2] + b
a[b - 2] = 3
b = 4
3 + 4 = 7
for more understanding use rails console and run line by line.
*a, b = [1, 2, 3, 4]
a
=> [1, 2, 3]
b
=> 4
a[b-2] // b-2 = 2 find value at index of 2 in a, like a[2] is 3
=> 3
a[b-2]+b
=> 7
*a, b = [1, 2, 3, 4] it means a = [1,2,3] and b = 4 when you do a[b-2] + b it will be
+-----------------------+
a[b-2] + b | a[2] |
a[4-2] + 4 | | |
a[2] + 4 | a[1, 2, 3] |
3 + 4 | 0 1 2 -> index |
= 7 +-----------------------+
By using the splat operator on a we are basically letting a to scoop up all the other numbers that b does not need. So b takes one number from the array and a takes everything that is left.
b = 4
a = [1,2,3]
Now when we do this:
a[b-2] + b
It translates into:
a[4-2] + 4
a[2] + 4
Now we check what number is in position 2 in array a.
3 + 4 = 7
I know that, for a k-permutation p of size k, built from n elements, there are:
P(n, k) = n! / (n - k)!
possible k-permutations. For example:
k = 2
n = 4
l = [1, 2, 3, 4]
P(n, k) = 4! / (4 - 2)! = 12
1 2 | 2 1 | 3 1 | 4 1
1 3 | 2 3 | 3 2 | 4 2
1 4 | 2 4 | 3 4 | 4 3
And yet another example:
k = 3
n = 4
l = [1, 2, 3, 4]
P(n, k) = 4! / (4 - 3)! = 24
1 2 3 | 2 1 3 | 3 1 2 | 4 1 2
1 2 4 | 2 1 4 | 3 1 4 | 4 1 3
1 3 2 | 2 3 1 | 3 2 1 | 4 2 1
1 3 4 | 2 3 4 | 3 2 4 | 4 2 3
1 4 2 | 2 4 1 | 3 4 1 | 4 3 1
1 4 3 | 2 4 3 | 3 4 2 | 4 3 2
So, how do I find the index of the k-permutation p? Consider the permutations
to be generated lexicographically.
Edit:
I could start by finding in which "block" p is, addressing the block by the first element of p. For example, for p = [3, 2, 4], the index for p should be at least 12 (counting from 0 to P(n, k) - 1).
But then, to find the second element inside that "block", I'd have to see what are the remaining items to be found, and in which position they will be. I mean, I'd be eventually addressing the list [1, 4], and 4 would be at position 2, so simply using the element as key would require some extra manipulation.
I could use a hash to look up the elements and update their positions, but it'd give me a O(n^2) time complexity. Is it possible to do any better?
The number of permutations for a given digit in a given position is given by a formula
(n-digit position)! / (n-k)! where digit position starts on the left with 1.
To get the number of preceding permutations for a given permutation (that is, its index), multiply the formula for each digit by the number of preceding digits not already used, and add them up.
Example 1, k = 2, n = 4, p = [3,4]
First digit, 3:
(4-1)! / (4-2)! * (number of unused preceding digits, 2) = 6
There are six permutations preceding the first that has 3 in position 1.
Second digit, 4:
(4-2)! / (4-2)! * (number of unused preceding digits, 2) = 2
There are two permutations preceding the first that has 4 in position 2.
Zero based index: 6 + 2 = 8.
Example 2, k = 3, n = 4, p = [3,2,4]
First digit, 3:
(4-1)! / (4-3)! * (number of unused preceding digits, 2) = 12
There are 12 permutations preceding the first that has 3 in position 1.
Second digit, 2:
(4-2)! / (4-3)! * (number of unused preceding digits, 1) = 2
There are two permutations preceding the first that has 2 in position 2.
Third digit, 4:
(4-3)! / (4-3)! * (number of unused preceding digits, 1) = 1
There is one permutation preceding the first that has 4 in position 3.
Zero based index: 12 + 2 + 1 = 15.
TXR language:
$ txr -p "(pos '(1 4 3) (perm '(1 2 3 4) 3))"
5
It is brute force, however; of course pos knows nothing about the structure of permutations.
Use binary search tree (BST). Store all you numbers in it before you start and delete them after you use one. To find x-th element maintain .subtreeSize for every vertex and just descend the tree to find the number you need. Pseudocode:
def findXth(x):
curVertex = BST.root
while:
curPosition = curVertex.leftChild.subtreeSize
if curPosition == x: return curVertex.value
elif curPosition > x: curVertex = curVertex.leftChild
elif curPosition < x: curVertex = curVertex.rightChild
Don't forget to check for vertices existence and to delete the vertex you find.
Overall complexity is going to be O(n log n).
you can reference below function
/**
* list all k or <=k size permutation of a given list with n unique elements.
* n can be bigger than 64. this function will take O(K^N) time, Bad.
*
* #param uniqueList
* #param permutationSize
* #param permutation
* #param only Only show the permutation of permutationSize,
* else show all permutation of less than or equal to permutationSize.
*/
public static void my_permutationOf(List<Integer> uniqueList, int permutationSize, List<Integer> permutation, boolean only) {
if (permutation == null) {
assert 0 < permutationSize && permutationSize <= uniqueList.size();
permutation = new ArrayList<>(permutationSize);
if (!only) {
System.out.println(Arrays.toString(permutation.toArray()));
}
}
for (int i : uniqueList) {
if (permutation.contains(i)) {
continue;
}
permutation.add(i);
if (!only) {
System.out.println(Arrays.toString(permutation.toArray()));
} else if (permutation.size() == permutationSize) {
System.out.println(Arrays.toString(permutation.toArray()));
}
if (permutation.size() < permutationSize) {
my_permutationOf(uniqueList, permutationSize, permutation, only);
}
permutation.remove(permutation.size() - 1);
}
}
E.g. you can think the element is the index
public static void main(String[] args) throws Exception {
my_permutationOf(new ArrayList<Integer>() {
{
add(0);
add(1);
add(2);
add(3);
}
}, 3, null, true);
}
the result is
[0, 1, 2]
[0, 1, 3]
[0, 2, 1]
[0, 2, 3]
[0, 3, 1]
[0, 3, 2]
[1, 0, 2]
[1, 0, 3]
[1, 2, 0]
[1, 2, 3]
[1, 3, 0]
[1, 3, 2]
[2, 0, 1]
[2, 0, 3]
[2, 1, 0]
[2, 1, 3]
[2, 3, 0]
[2, 3, 1]
[3, 0, 1]
[3, 0, 2]
[3, 1, 0]
[3, 1, 2]
[3, 2, 0]
[3, 2, 1]
Given a n*n-sized multi-headed acyclic graph where each node has at most three children and three parents, is there an non-exponential algorithm to identify whether a n-length path exists where no two nodes share the same value, and every value of a set is accounted for?
Basically, I have an n*n maze where each space has a random value (1..n). I need to find a path (from the top to the bottom) of n nodes that includes every value.
Right now I'm using a depth-first search, but that is T(n) = 3T(n-1) + O(1), which is O(3^n), a non-ideal solution.
Either confirming my fears, or pointing me in the right direction would be much appreciated.
Edit: to make this a little bit more concrete, here is a maze with solutions (solved using the depth-first solution).
1 2 5 5 4
1 5 1 3 5
4 1 2 3 2
5 5 4 4 3
4 2 1 2 4
S3, 5, 1, 3, 4, 2, F4
S3, 5, 1, 3, 4, 2, F2
S3, 5, 1, 3, 4, 2, F4
S3, 5, 3, 2, 4, 1, F3
S3, 5, 3, 2, 4, 1, F3
S3, 5, 3, 2, 4, 1, F3
S4, 5, 3, 2, 4, 1, F3
S4, 5, 3, 2, 4, 1, F3
S4, 5, 3, 2, 4, 1, F3
S4, 5, 1, 3, 4, 2, F4
S4, 5, 1, 3, 4, 2, F2
S4, 5, 1, 3, 4, 2, F4
S5, 4, 3, 2, 5, 1, F3
13 total paths`
This problem is NP-complete, and so it is not known whether or not there is a polynomial-time solution. (The standard provisos of possibly being easy in practice, etc., all apply.) One possible reduction is from 3SAT.
Suppose we have a 3SAT instance, such as (a ∨ b ∨ c) ∧ (¬a ∨ ¬b ∨ ¬c). I will show how to use "gadgets" to build an instance of your problem. Before we begin, rewrite the 3SAT problem as (a1 ∨ b1 ∨ c1) ∧ (¬a2 ∨ ¬b2 ∨ ¬c2) together with a1 = a2, b1 = b2, and c1 = c2; that is, make each occurrence of a variable unique, but then add the condition that different occurrences of the same variable must be equal.
First, we make sure that you must pick the number 0 in the first row, so that we can use it later as a "sentinel" that you must avoid.
0 0 0
Now, we build a gadget that enforces the a1 = a2 rule: (The underscore _ here is a new unique number in every use of this gadget)
0 _ 0
a1 0 ¬a1
a2 0 ¬a2
Because of the first row, you must avoid the 0s. This means you either take the path "a1, a2" or the path "¬a1, ¬a2"; the former will correspond to (slightly confusingly) setting a to false, while the latter will correspond to a setting a to true. This is because our clause gadget is really easy then, because we simply write down the clause, e.g. (again _ here is a new variable each time):
0 _ 0
a1 b1 b2
or
0 _ 0
¬a1 ¬b1 ¬b2
Finally, since you've only used one of a1 and ¬a1, etc., we let you take the ones you haven't used freely:
0 _ 0
a1 ¬a1 0
Now, this doesn't quite work, because one of a1 and ¬a1 might have been used in the variable choice gadget, while the other could have been used in a clause. So, we include a new variable #i for each clause that you can take instead of one of the variables. So if variable a1 appears in clause 1, we have
0 _ 0
a1 ¬a1 #1
Here's the complete output of a translation of the original 3SAT clause (highlighting the path corresponding to setting a and b to true, c to false, and picking a from the first clause), with numbers on the left and gloss on the right. The gadgets are re-ordered (first clause gadgets, then for each variable, the equality gadget and then unused gadget), but this doesn't matter since they're independent anyway.
0 0 < 0 . . < .
0 8 < 0 . _ < .
2 < 4 6 a1 < b1 c1
0 16 < 0 . _ .
11 13 15 < -a2 -b2 -c2<
0 17 < 0 . _ < .
2 0 3 < a1 . -a1<
10 0 11 < a2 . -a2<
0 18 < 0 . _ < .
2 3 1 < a1 -a1 #1 <
0 19 < 0 . _ .
10 < 11 9 a2 < -a2 #2
0 20 < 0 . _ < .
4 0 5 < b1 . -b1<
12 0 13 < b2 . -b2<
0 21 < 0 . _ < .
4 < 5 1 b1 < -b1 #1
0 22 < 0 . _ < .
12 < 13 9 b2 < -b2 #2
0 23 < 0 . _ < .
6 < 0 7 c1 < . -c1
14 < 0 15 c2 < . -c2
0 24 < 0 . _ < .
6 7 < 1 c1 -c1< #1
0 25 < 0 . _ < .
14 15 9 < c2 -c2 #2 <
(If you want the whole thing to be square, just include a bunch of zeros at the end of each line.) It's fun to see that no matter how you solve this, at heart, you're solving that 3SAT problem.
At the end of my post is a hastily-written Perl program that generates one of your problems from an input of the form
a b c
-a -b -c
The number of variables in the resulting instance of your problem is 11C + V + 1. Give the program the -r switch to produce gloss instead of numbers.
# Set useful output defaults
$, = "\t"; $\ = "\n";
# Process readability option and force sentinel
my $r = "0";
if( $ARGV[0] =~ /-r/ ) { shift; $r = "."; }
print $r, $r, $r;
# Clause gadgets
my( %v, %c, $m, $c );
$m = 1;
while( <> ) {
my( #v, #m );
$c = $m++;
chomp; #v = split;
for my $v ( #v ) {
push #{$v{strip($v)}}, -1; # hack, argh!
push #m, ($r ? $v.#{$v{strip($v)}} : $m + neg($v));
$c{($r ? (strip($v).#{$v{strip($v)}}) : $m)} = $c;
$v{strip($v)}->[-1] = ($r ? (strip($v).#{$v{strip($v)}}) : $m);
$m += 2 unless $r;
}
print $r, newv(), $r;
print #m;
}
# Variable gadget
for my $v ( sort keys %v ) {
# Force equal
print $r, newv(), $r;
for my $n ( #{$v{$v}} ) {
print $n, $r, ($r ? "-".$n : $n+1);
}
# Unused
for my $n ( #{$v{$v}} ) {
print $r, newv(), $r;
print $n, ($r ? "-".$n : $n+1), ($r ? "\#".$c{$n} : $c{$n});
}
}
# Strip leading -
sub strip {
my( $v ) = #_;
return substr $v, neg($v);
}
# Is this variable negative?
sub neg {
my( $v ) = #_;
return "-" eq substr( $v, 0, 1 );
}
# New, unused variable
sub newv {
return "_" if $r;
return $m++;
}
I'm pretty sure this can be done in polynomial time. I would start with a an empty set and then loop through the rows top to bottom. I'm going to skip any kind of code and show you what the state would look like at each step you should be able to put together an algorithm from there. I'm pretty sure the best case is slightly worse than O(n^2) using a variation of breadth first search and keeping track of the current good paths in a table.
EDIT: If this still isn't fast enough you can improve it by applying Harlequin's optimization.
For Example:
1 2 3
3 2 1
1 2 1
State 0:
R = 0 // Row
P = {} // Path Set
// {{Path so far}, Column}
P' = {
{{1}, 0}
{{2}, 1}
{{3}, 2}
}
P = P'
State 1:
R = 1 // ROW
P = {
{{1}, 0}
{{2}, 1}
{{3}, 2}
}
P' = {
{{1 3}, 0}
{{1 2}, 1}
{{2 3}, 0}
{{2 1}, 2}
{{3 2}, 1}
{{3 1}, 2}
}
State 2:
R = 2
P = {
{{1 3}, 0}
{{1 2}, 1}
{{2 3}, 0}
{{2 1}, 2}
{{3 2}, 1}
{{3 1}, 2}
}
P' = {
{{1 3 2}, 1}
{{2 3 1}, 0}
{{3 2 1}, 0}
{{3 2 1}, 2}
{{3 1 2}, 1}
}
Result:
Path Count: 5
S1 1 3 2 F2
S2 2 3 1 F1
S3 3 2 1 F1
S3 3 2 1 F3
S3 3 1 2 F2
You can try the ant colony optimization. It quickly yields very good results that are very close to the perfect solution.
One optimization for Kevin Loney's solution might be to merge partial paths that contain the same elements at the same column. You would have to note the number of merges with the path if you want to know the number of solutions at the end.
Example: In your 5x5 example, when you arrive at the third row, the third column has three paths leading to it that contain (1 2 5) in some order. You don't have to follow these separately from this point, but can merge them. If you want to know the number of solutions at the end, you just have to adjust your path data structure, e.g. three (1 (1 2 5)) would merge to (3 (1 2 5)).
Look up A* search. It is your friend.