Related
So i'm trying to figure out an algorithm problem where i've got a 2D array representing a grid in which there are multiple robots and a flag.
Robots can move one cell at a time in every direction (left, up, right, down) but every bot should move the same direction every time.
When a robot go out of the array bounds, it's eliminated.
When a robot arrives on the cell in which there is the flag, it's saved (and removed from the grid).
Example :
grid:
| R1 |
--------------
| | R2
--------------
| D |
> move(left)
grid:
R1 | |
--------------
| R2 |
--------------
| D |
> move(down)
grid:
| |
--------------
R1 | |
--------------
| D |
saved: [R2]
We can find a very simple algorithm in time complexity O(width*height) where width and height are the dimensions of the array, but i need a solution in constant time complexity that can moves all the robots in any direction.
Do you guys have an idea how could i do that ?
You have the WIDTH and HEIGHT of the grid (aka 2d array).
You have the starting positions of the "robots" X and Y.
You have the direction the "robot" is moving UP (Y - 1), DOWN (Y + 1), LEFT (X - 1), RIGHT (X + 1).
You have the position of the "flag" X and Y.
Seems like you'd have to loop through N number of the robots, so it's really not CONSTANT time but if we ignore that...
// Move the robot
IF Move == UP THEN Robot.Y -= 1
ELSE IF Move == DOWN THEN Robot.Y += 1
ELSE IF Move == LEFT THEN Robot.X -= 1
ELSE IF Move == RIGHT THEN Robot.X += 1
// Check for out of bounds
IF Robot.X < 0 OR Robot.X >= WIDTH OR Robot.Y < 0 OR Robot.Y >= HEIGHT THEN Robot.Disappear()
// Check for flag
IF Robot.X == Flag.X AND Robot.Y == Flag.Y THEN Robot.Save()
I've created the group (its GF4 algebra) that has 4 elements:
OrderMat = {0, 1, lambda, lambda + 1}
And definition of operation (.) with this Matrix realized by function:
| 0 | 1 | lambda | lambda+1 |
______________________________________________
0|| 0 | 0 | 0 | 0 |
1|| 0 | 1 | lambda | lambda+1 |
lambda|| 0 | lambda | lambda+1 | 1 |
lambda+1|| 0 |lambda+1| 1 | lambda |
OPMatrix = {{0, 0, 0, 0},
{0, 1, lambda, lambda + 1},
{0, lambda, lambda + 1, 1},
{0, lambda + 1, 1, lambda}}
GF4Mult[x_, y_] := OPMatrix[[Position[OrderMat, x][[1]][[1]]]][[Position[OrderMat, y][[1]][[1]]]]
Now I would like to Solve equations in this group.
for example:
Solve[x.lambda == 1,x] ... x=>lambda+1
or like this:
Solve[GF4Mult[x,lambda]== 1,x] ... x=>lambda+1
Is this possible ? do i have to use some other structure to define group ?
I don't know if this is a good way of doing this, but it seems closer to what you are asking for than the last couple of things I tried. And it uses the notation that you chose, except for Mathematica reordering lambda+1 to be 1+lambda on output.
First let's define your multiplication operator
times={{0,0,0},{0,1,0},{0,lambda,0},{0,lambda+1,0},
{1,0,0},{1,1,1},{1,lambda,lambda},{1,lambda+1,lambda+1},
{lambda,0,0},{lambda,1,lambda},{lambda,lambda,lambda+1},{lambda,lambda+1,1},
{lambda+1,0,0},{lambda+1,1,lambda+1},{lambda+1,lambda,1},{lambda+1,lambda+1,lambda}};
That is exactly what you had except for my flattening that into a vector.
Now lets show a method somewhat similar to Solve that might work for you.
Suppose as a first example you wonder is there a lambda+1*something=lambda+1
Cases[times,{lambda+1,x_,lambda+1}]
and that shows you there is only one value which satisfies that, the identity.
{{1+lambda,1,1+lambda}}
Another example
Cases[times,{lambda+1,x_,lambda}]
gives you
{{1+lambda,1+lambda,lambda}}
Another example, is there lambda+1*anythingBUTlambda+1=lambda
Cases[times,{lambda+1,Except[lambda+1],lambda}]
gives you
{}
which shows there is no such value.
Another example
Cases[times,{lambda+1,x_,Except[x_]}]
gives you
{{1+lambda,1,1+lambda},{1+lambda,lambda,1},{1+lambda,1+lambda,lambda}}
That has a lot of flexibility because you can have unknowns in any position. But because of that flexibility it doesn't just return a single value to you. Perhaps you can use this for what you are thinking of or perhaps you can think of ways to adapt this to what you are trying to do.
If you want to extract one value of a result then you can do things like this:
Cases[times,{lambda+1,x_,lambda}:>x]
which will return
{1+lambda}
which is the value, or values, of x which satisfied that.
Check this carefully to see if you can find any mistakes before you depend on it.
I did some triangulation tasks with the library PolyK. Just for comparison purposes for my simple polygons.
I have a Polygon with 7 vertices. But I get with this library only 9 indexes == 3 triangles that is to less I guess.
In the following code you see my implemention of PolyK.js in THREE.js
var pts3 = [];
var ids2 = PolyK.Triangulate(pts3);
for (var k = 0; k < ids2.length; k+=3)
{
geometry.faces.push(new THREE.Face3(ids2[k], ids2[k + 1], ids2[k + 2]));
}
My points array:
(7 points with x and y value)
var points = [
158.56000000005588, 336.73000000044703,
158.60000000009313, 335.21999999973923,
161.589999999851, 335.3099999995902,
161.7799999997951, 329.820000000298,
155.52000000001863, 329.62000000011176,
155.29999999981374, 336.62999999988824,
158.56000000005588, 336.73000000044703
];
This is the current result:
This is the expected result:
Is there something wrong regarding the usage of PolyK in the source code?
These are the points:
4 _______________ 3
| |
| |
| |
| |
| |
| _______|
| |1 2
|_______|
5 0/6
I tested in a fiddle here and it seems to work like you said.
I get result:
[5, 6, 0, 0, 1, 2, 0, 2, 3]
It is the same incorrect result as you showed in your drawing.
At first I thought removing the duplicated point ( 0 is same as 6 ) would solve the issue, but that also gives a incorrect result.
I would suggest using a different library like earcut or poly2tri.
Check also this triangulation adapter/library on GitHub that I made for three.js. It might be useful for you.
I have 3 variables with some possible values.
For example:
Var1 - possible values: 1,2,3
Var2 - possible values: a, b, c
var3 - possible values: false, true
Can you please help with an approach that returns all possible combinations?
The result be like:
1,a,false
1,a,true,
1,b,false
1,b,true,
1,c,false
1,c,true
2,a,false
2,a,true
2,b,false
Etc..
I wish the algorithm could apply to any levels of combinations, for example, the algorithm to work on 4 or 5 varibles with other possible values.
It looks like you're trying to enumerate Cartesian products. Assuming your items are in list_of_lists, this recursive function in pseudo-code will do it:
enumerate_cartesian_prducts(list_of_lists):
if list_of_lists is empty:
return [[]]
this_list = list_of_lists[0]
other_lists = list_of_lists[1: ]
other_cartesian_products = []
return [(e + other_cartesian_product) \
for e in this_list and other_cartesian_product in other_cartesian_products]
Note how the last line would probably be a double loop in most languages: it iterates over all the elements in the first list, all the lists in the cartesian products of the rest, and creates a list of all the appended results.
The simplest solution is to have n nested loops:
for each possible value v1 in var1
for each possible value v2 in var2
for each possible value v3 in var3
print(v1,v2,v3);
end for v3
end for v2
end for v1
In more general case, let's assume you have list of lists that contains n lists(one for every var) and each of these lists contains possible values for each variable. You can solve problem with following recursive function all_combinations.
list_of_lists=[[1...][a...][false...]];
current_comb=[];
all_combinations(list_of_lists,current_comb);
function all_combinations(list_of_lists,current_comb)
if (list_of_lists=[])
print(current_comb);
return;
end if
current_list=list_of_lists[0];
remaining_lists=list_of_lists[1:end];
for each v in current_list
tmp=current_comb;tmp.Append(v);
all_combinations(remaining_lists,tmp);
end for v
Of course when adding variables, soon you will need to deal with combinatorial explosion.
The only clean solution is:
have a function mix( A, B ) which takes two lists and returns a list. That's trivial.
Your final code just looks like this:
result = null
result = mix( result, one of your lists );
result = mix( result, another of your lists );
result = mix( result, yet another of your lists );
result = mix( result, yet another list );
result = mix( result, one more list );
example of mix(A,B) ...
mix(A,B)
result = null
for each A
for each B
result += AB
return result
Assume that each variable has a set or vector associated with is. That is:
set1 = [1, 2, 3]
set2 = [a, b, c]
set3 = [F, T]
Then, one way is to loop over these sets in nested "for" loops. Assume that your output structure is a list of 3-element lists. That is, your output desired looks like this:
[[1,a,F], [1,a,T], [1,b,F],......]
Also assume that (like in Python) you can use a function like "append" to append a 2-element list to your big list. Then try this:
myList = [] #empty list
for i in set1:
for j in set2:
for k in set3:
myList.append([i, j, k]) #Appends 3-element list to big list
You may need to do a deepcopy in the append statement so that all the i's, j's, and k's arene't updated in your master list each time you run through an iteration. This may not be the most efficient, but I think it's relatively straightforward.
Here's something in JavaScript that's pseudocode-like. (I've never coded in C#; maybe I'll try to convert it.)
var sets = [[1,2,3],["a","b","c"],[false,true]],
result = [];
function f(arr,i){
if (i == sets.length){
result.push(arr);
return;
}
for (var j=0; j<sets[i].length; j++){
_arr = arr.slice(); // make a copy of arr
_arr.push(sets[i][j]);
f(_arr,i+1);
}
}
f([],0)
Output:
console.log(result);
[[1,"a",false]
,[1,"a",true]
,[1,"b",false]
,[1,"b",true]
,[1,"c",false]
,[1,"c",true]
,[2,"a",false]
,[2,"a",true]
,[2,"b",false]
,[2,"b",true]
,[2,"c",false]
,[2,"c",true]
,[3,"a",false]
,[3,"a",true]
,[3,"b",false]
,[3,"b",true]
,[3,"c",false]
,[3,"c",true]]
You really ought to look for this elsewhere, and it's not a good stackoverflow question. It's homework and there is an algorithm for this already if you search more using the proper terms.
It's quite simple in fact, if you generalize the algorithm for generating all combinations of digits in a binary string, you should be able to get it:
0 0 0 0
0 0 0 1
0 0 1 0
0 0 1 1
0 1 0 0
0 1 0 1
0 1 1 0
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
1 0 1 1
1 1 0 0
1 1 0 1
1 1 1 0
1 1 1 1
Notice that the right-most column alternates its values every cell, while the second-from-right column alternates every 2 cells, the next column over from that alternates every 4 cells, and the final digit alternates every 8 cells.
For your case, think of the above as what happens when your sets are:
Var1 - possible values: 0,1
Var2 - possible values: 0,1
Var3 - possible values: 0,1
Var4 - possible values: 0,1
Start a counter that keeps track of your position in each set, and start by cycling through the "rightmost" set a full time before bumping the position of the "next-from-right" set by 1. Continue cycling the the sets in this way, bumping a set when the one to its "right" cycles over, until you've finished cycling the set in the "most significant position". You will have generated all possible combinations in the sets.
The other answers have focused on "give the codez", which really just rewards you for posting your homework question here... so I thought I would at least explain a little.
I have a floating point value X which is animated. When in rest it's at zero, but at times an outside source may change it to somewhere between -1 and 1.
If that happens I want it to go smoothly back to 0. I currently do something like
addToXspeed(-x * FACTOR);
// below is out of my control
function addToXspeed(bla) {
xspeed += bla;
x += xspeed;
}
every step in the animation, but that only causes X to oscillate. I want it to rest on 0 however.
(I've explained the problem in abstracts. The specific thing I'm trying to do is make a jumping game character balance himself upright in the air by applying rotational force)
Interesting problem.
What you are asking for is the stabilization of the following discrete-time linear system:
| x(t+1)| = | 1 dt | | x(t)| + | 0 | u(t)
|xspeed(t+1)| | 0 1 | |xspeed(t)| | 1 |
where dt is the sampling time and u(t) is the quantity you addToXspeed(). (Further, the system is subject to random disturbances on the first variable x, which I don't show in the equation above.) Now if you "set the control input equal to a linear feedback of the state", i.e.
u(t) = [a b] | x(t)| = a*x(t) + b*xspeed(t)
|xspeed(t)|
then the "closed-loop" system becomes
| x(t+1)| = | 1 dt | | x(t)|
|xspeed(t+1)| | a b+1 | |xspeed(t)|
Now, in order to obtain "asymptotic stability" of the system, we stipulate that the eigenvalues of the closed-loop matrix are placed "inside the complex unit circle", and we do this by tuning a and b. We place the eigenvalues, say, at 0.5.
Therefore the characteristic polynomial of the closed-loop matrix, which is
(s - 1)(s - (b+1)) - a*dt = s^2 -(2+b)*s + (b+1-a*dt)
should equal
(s - 0.5)^2 = s^2 - s + 0.25
This is easily attained if we choose
b = -1 a = -0.25/dt
or
u(t) = a*x(t) + b*xspeed(t) = -(0.25/dt)*x(t) - xspeed(t)
addToXspeed(u(t))
which is more or less what appears in your own answer
targetxspeed = -x * FACTOR;
addToXspeed(targetxspeed - xspeed);
where, if we are asked to place the eigenvalues at 0.5, we should set FACTOR = (0.25/dt).
x = x*FACTOR
This should do the trick when factor is between 0 and 1.
The lower the factor the quicker you'll go to 0.
Why don't you define a fixed step to be decremented from x?
You just have to be sure to make it small enough so that the said person doesn't seem to be traveling at small bursts at a time, but not small enough that she doesn't move at a perceived rate.
Writing the question oftens results in realising the answer.
targetxspeed = -x * FACTOR;
addToXspeed(targetxspeed - xspeed);
// below is out of my control
function addToXspeed(bla) {
xspeed += bla;
x += xspeed;
}
So simple too
If you want to scale it but can only add, then you have to figure out which value to add in order to get the desired scaling:
Let's say x = 0.543, and we want to cause it to rapidly go towards 0, i.e. by dropping it by 95%.
We want to do:
scaled_x = x * (1.0 - 0.95);
This would leave x at 0.543 * 0.05, or 0.02715. The difference between this value and the original is then what you need to add to get this value:
delta = scaled_x - x;
This would make delta equal -0,51585, which is what you need to add to simulate a scaling by 5%.