Related
I have problem, because I want to generate permutations of a list (in prolog), which contains n zeros and 24 - n ones without repetitions. I've tried:findall(L, permutation(L,P), Bag) and then sort it to remove repetitions, but it causes stack overflow. Anyone has an efficient way to do this?
Instead of thinking about lists, think about binary numbers. The list will have a length of 24 elements. If all those elements are 1's we have:
?- X is 0b111111111111111111111111.
X = 16777215.
The de fact standard predicate between/3 can be used to generate numbers in the interval [0, 16777215]:
?- between(0, 16777215, N).
N = 0 ;
N = 1 ;
N = 2 ;
...
Only some of these numbers satisfy your condition. Thus, you will need to filter/test them and then convert the numbers that pass into a list representation of its binary equivalent.
Select n random numbers between 0 and 23 in ascending order. These integers give you the indexes of the zeroes and all the configurations are different. The key is generating these list of indexes.
%
% We need N monotonically increasing integer numbers (to be used
% as indexes) from [From,To].
%
need_indexes(N,From,To,Sol) :-
N>0,
!,
Delta is To-From+1,
N=<Delta, % Still have a chance to generate them all
N_less is N-1,
From_plus is From+1,
(
% Case 1: "From" is selected into the collection of index values
(need_indexes(N_less,From_plus,To,SubSol),Sol=[From|SubSol])
;
% Case 2: "From" is not selected, which is only possible if N<Delta
(N<Delta -> need_indexes(N,From_plus,To,Sol))
).
need_indexes(0,_,_,[]).
Now we can get list of indexes picked from the available possible indexes.
For example:
Give me 5 indexes from 0 to 23 (inclusive):
?- need_indexes(5,0,23,Collected).
Collected = [0, 1, 2, 3, 4] ;
Collected = [0, 1, 2, 3, 5] ;
Collected = [0, 1, 2, 3, 6] ;
Collected = [0, 1, 2, 3, 7] ;
...
Give them all:
?- findall(Collected,need_indexes(5,0,23,Collected),L),length(L,LL).
L = [[0, 1, 2, 3, 4], [0, 1, 2, 3, 5], [0, 1, 2, 3, 6], [0, 1, 2, 3, 7], [0, 1, 2, 3|...], [0, 1, 2|...], [0, 1|...], [0|...], [...|...]|...],
LL = 42504.
We are expecting: (24! / ((24-5)! * 5!)) solutions.
Indeed:
?- L is 20*21*22*23*24 / (1*2*3*4*5).
L = 42504.
Now the only problem is transforming every solution like [0, 1, 2, 3, 4] into a string of 0 and 1. This is left as an exercise!
Here is an even simpler answer to generate strings directly. Very direct.
need_list(ZeroCount,OneCount,Sol) :-
length(Zs,ZeroCount),maplist([X]>>(X='0'),Zs),
length(Os,OneCount),maplist([X]>>(X='1'),Os),
compose(Zs,Os,Sol).
compose([Z|Zs],[O|Os],[Z|More]) :- compose(Zs,[O|Os],More).
compose([Z|Zs],[O|Os],[O|More]) :- compose([Z|Zs],Os,More).
compose([],[O|Os],[O|More]) :- !,compose([],Os,More).
compose([Z|Zs],[],[Z|More]) :- !,compose(Zs,[],More).
compose([],[],[]).
rt(ZeroCount,Sol) :-
ZeroCount >= 0,
ZeroCount =< 24,
OneCount is 24-ZeroCount,
need_list(ZeroCount,OneCount,SolList),
atom_chars(Sol,SolList).
?- rt(20,Sol).
Sol = '000000000000000000001111' ;
Sol = '000000000000000000010111' ;
Sol = '000000000000000000011011' ;
Sol = '000000000000000000011101' ;
Sol = '000000000000000000011110' ;
Sol = '000000000000000000100111' ;
Sol = '000000000000000000101011' ;
Sol = '000000000000000000101101' ;
Sol = '000000000000000000101110' ;
Sol = '000000000000000000110011' ;
Sol = '000000000000000000110101' ;
....
?- findall(Collected,rt(5,Collected),L),length(L,LL).
L = ['000001111111111111111111', '000010111111111111111111', '000011011111111111111111', '000011101111111111111111', '000011110111111111111111', '000011111011111111111111', '000011111101111111111111', '000011111110111111111111', '000011111111011111111111'|...],
LL = 42504.
I am trying to write some code (as part of a larger script) to develop numpy arrays of length n, which I can use to change the sign of an input list of length n, in all possible ways.
I am trying to produce all possible permutations of 1 and -1 of length n.
If I use itertools.permutations, it will not accept a repeat length greater than 2, because of not allowing repetitions. If I use itertools.combinations_with_replacement, then not all of the permutations are produced. I need "permutations_with_replacement".
I tried to use itertools.product, but I cannot get it to work.
Here is my code so far (n is an unknown number, depending on the length of the input list).
import numpy as np
import itertools
ones = [-1, 1]
multiplier = np.array([x for x in itertools.combinations_with_replacement(ones, n)])
Perhaps this is what you want?
>>> import itertools
>>> choices = [-1, 1]
>>> n = 3
>>> l = [choices] * n
>>> l
[[-1, 1], [-1, 1], [-1, 1]]
>>> list(itertools.product(*l))
[(-1, -1, -1), (-1, -1, 1), (-1, 1, -1), (-1, 1, 1), (1, -1, -1), (1, -1, 1), (1, 1, -1), (1, 1, 1)]
The operation consists of two arrays X and idx of equal length where the values of idx can vary between 0 to (k-1) with the value of k given.
This is the general Python code to illustrate this.
import numpy as np
X = np.arange(6) # Just for a sample of elements
k = 3
idx = numpy.array([[0, 1, 2, 2, 0, 1]]).T # Can only contain values in [0..(k-1)]
np.array([X[np.where(idx==i)[0]] for i in range(k)])
Sample output:
array([[0, 4],
[1, 5],
[2, 3]])
Note that there is actually a reason for me to represent idx as a matrix and not as a vector. It was initialised to numpy.zeros((n,1)) as part of its computation, where n the size of X.
I tried implement this in Theano like so
import theano
import theano.tensor as T
X = T.vector('X')
idx = T.vector('idx')
k = T.scalar()
c = theano.scan(lambda i: X[T.where(T.eq(idx,i))], sequences=T.arange(k))
f = function([X,idx,k],c)
But I received this error at line where c is defined:
TypeError: Wrong number of inputs for Switch.make_node (got 1((<int8>,)), expected 3)
Is there a simple way to implement this in Theano?
Use nonzero() and correct the dimensions of idx.
This code solved the problem
import theano
import theano.tensor as T
X = T.vector('X')
idx = T.vector('idx')
k = T.scalar()
c, updates = theano.scan(lambda i: X[T.eq(idx,i).nonzero()], sequences=T.arange(k))
f = function([X,idx,k],c)
For the same example, through the use of Theano:
import numpy as np
X = np.arange(6)
k = 3
idx = np.array([[0, 1, 2, 2, 0, 1]]).T
f(X, idx.T[0], k).astype(int)
This gives the output as
array([[0, 4],
[1, 5],
[2, 3]])
If idx is defined as np.array([0, 1, 2, 2, 0, 1]), then f(X, idx, k) can be used instead.
Hi I have a dictionary like the below:
b = {'tat': 0, 'del': 4, 'galadriel': 0, 'sire': 0, 'caulimovirus': 4, 'retrofit': 0, 'tork': 0, 'caulimoviridae_dom2': 0, 'reina': 4, 'oryco': 2, 'cavemovirus': 1, 'soymovrius': 0, 'badnavirus': 0, 'crm': 0, 'athila': 0}
I want to find all keys with the maximum value as a list. However,
max(a, key=a.get)
only gives the first key element, 'del'.
How should I find all the keys with the maximum values? Like the below.
new_list = ['del', 'caulimovirus', 'reina']
maxv = max(b.values())
new_list = [k for k, v in b.items() if v == maxv]
I have three tables X,Y,Z. While X & Y define my grid points the Z depends on every point of X and Y.
x = Table[i, {i, 0, 10, 1}]
y = Table[j, {j, 0, 10, 1}]
z = Table[5*i + j, {i, 0, 10, 1}, {j, 0, 10, 1}]
Now I want the final list to look like this [{x1,y1,z1},{x2,y2,z2}}
I want to create a set of corresponding x,y,z values from the table given above.
In this case you can also produce your combined list with Array as follows:
Array[{##, 5 # + #2} &, {11, 11}, 0]
See Function and Slot. rcollyer has already shown how to "split out" x, y, and z from this.
When starting with unrelated lists x and y you can produce the combined list with Outer:
Outer[{##, 5 # + #2} &, x, y, 1]
Unless you need the the x and y lists, I'd combine this in one Table as follows:
Table[{i, j, 5*i + j}, {i, 0, 10}, {j, 0, 10}]
Note, I removed the step length ({i, 0, 10, 1} -> {i, 0, 10}) as it's implicitly set to 1 if it is not included.
Edit: If you wish to have the x and y lists, also, you could do the following
Table[{i, j, 5*i+j}, {i, x}, {j, y}]
As of v.7, Table accepts lists of values in addition to start and end points. This doesn't address whether you need a separate list for z, also. In that case, I'd start with the first form bit of code, and using Transpose (per your other question) to set the individual lists, as follows:
coords = Table[{i, j, 5*i + j}, {i, 0, 10}, {j, 0, 10}];
{x, y, z} = Transpose # coords;
One way to do it starting from your
x = Table[i, {i, 0, 10, 1}];
y = Table[j, {j, 0, 10, 1}];
z = Table[5*i + j, {i, 0, 10, 1}, {j, 0, 10, 1}];
is
Flatten[
MapThread[{Sequence ## #1, #2} &,
{Outer[{#1, #2} &, x, y], z},
2
],
1
]
(I'd love to see me try to understand this in a week) which gives what you want.
This also works:
p = {};
Do[
Do[
AppendTo[p, {x[[i]], y[[j]], z[[i, j]]}],
{j, 1, Length#y}
],
{i, 1, Length#x}
]
and gives the same answer.