I was wondering if anyone could help me go through this question. I looked up the Min Max theory, but I still don't know how to apply this concept to this question below.
The following tree represents possible moves in a competitive game, showing that player X currently has a choice between move A and move B.
Following the move of player X, player Y is allowed to select a move, and then player X is allowed to select the last move of the game.
The leaf nodes of the tree are labeled W, L, or T, depending on whether that ending represents a win, loss, or tie for player X.
Use the min-max search to determine if player X should move A or B to obtain the best result X can expect.
To review min-max search, see http://www.nada.kth.se/kurser/kth/2D1350/progp02/lecture2.pdf
Player X should move A.
Player X should move B.
I added numbers for the nodes, and highlighted the "max" rows. The non-highlighted rows are "min" rows (i.e., the player wants to minimize the result). Obviously an L is the lowest value, and a W is the highest value. We usually assign a 1 to a win, a -1 to a loss, and a 0 to a tie. Player Y wants to make the number as low as possible (they win if the player X gets an L). Player X wants to make the number as high as possible (he wants a W).
If the game plays out to node 4, you know that player X will win no matter what. Therefore, 4 is marked W (or 1). If the game plays out to node 5, you know that he loses, so it's marked L. Same happens for 6 (which gets a W).
To assign to node 2, we note that 2 is on a "min" row (it's player Y's turn). 4, 5, 6, have W, L, W, respectively. Player Y can minimize this by choosing node 5, therefore winning. Therefore, Player X knows that if Player Y is intelligent, Player X will lose if he chooses A.
We can do the same thing on the other side to show that if Player X chooses B, he will tie. Therefore, Player X should choose B.
When code is written for minimax, the code does a post-order tree traversal and assigns values to the nodes as it goes by looking at the descendants.
Related
A Naive Shedding Card Game
Given a simple version of a shedding type card game (which is actually a naive version of Dou Di Zhu(https://en.wikipedia.org/wiki/Dou_dizhu), the most popular game in china), how can we determine the winner (each player can have up to 20 cards) (is there exists a linear algorithm to solve the problem)?
The object of the game is to get rid of all cards on hand before the opponent. The players are called A and B. The card ranks are:
3 < 4 < 5 < 6 < 7 < 8 < 9 < T < J < Q < k < A < 2 < r < R (where T is 10, r, R is small and big joker)
Definition1: Player who can discard any card compile with the Give-Out-Rule is called FirstDiscard player, while player who can only discard a card that has a higher rank then previous discarded card is called BeatDiscard player.
A is the first player to discard a card, so A is always a FirstDiscard player at the beginning. If one choose not to discard a card (because he chooses not to discard or he can not find a valid card to discard), then another become FirstDiscard player.
Give out Rule1: Each player can discard a single card at most, Even if you have multiple cards that is the same rank, you can only discard only one of them.
Example1: B winner 4,4,5 < B: 3,4,4,8,T
Explain: B is always the winner, because for any strategy A can possible choose to
play, B can always find a strategy to discard card that leads to winning of B.
Example2: A winner 4,4,5,R > B: 3,4,4,8,T
Explain: A is always the winner, because there exists a strategy A can choose to use that leads to winning of A regardless of strategies B choose to react.
The red and blue indicate the state(the cards left in hand) of A and
B.
The polygon and box shape indicate the player is at FirstDiscard
player state and BeatDiscard player state.
A Relative Graph of tow card sets(A: 4,4,5,R > B: 3,4,4,8,T)
The Bp value of each card indicates how may opponent's card that this card can be used to beat.
Cards with the same Bp value form a block.
The research progress
For now, I can only use the game search tree methods to determine the winner, but the methods takes too long time to process. Give out Rule1 is Actually the first step of my research, the following research give out rule is:
Definition2: solo-card is defined as card with a specific rank whose count is one. while pair-card, trio-card, four-card are defined as card with a specific rank whose count is two, three, four.
Definition3: solo-card, pair-card, trio-card, four-card are also called independent-card
Give out Rule2: Each player can only discard a kind of independent-card each time, if player is at BeatDiscard player state, he can only discard the same kind of independent-card of previous discarded cards with a higher rank.
SplitCard is not allowed. (if you have a trio-card 555, you can not split the card to be a solo-card 5 and a pair-card 55)
Give out Rule3: The same as Give out Rule2 except SplitCard is allowed.
Definition4: trio-card with a solo-card is called trio-solo-kicker-card, the rank is the same of trio-card.
Definition5: trio-card with a pair-card is called trio-pair-kicker-card, the rank is the same of trio-card.
Definition6: four-card with two solo-card is called four-2-solo-kicker-card, the rank is the same of four-card.
Definition7: four-card with two pair-card is called four-2-pair-kicker-card, the rank is the same of four-card.
Give out Rule4: The same as Give out Rule3 and four additional card types (from Def4 ~ Def7) are allowed to discard.
Definition8: four-card is also called bomb-card, it can be used to beat all other card type and four-card with a lower rank (6666 can beat 33, 5555, 3331, 8888KJ)
Definition9: rocket-card is a combination of r and R, it can beat all other card type.
Give out Rule5: The same as Give out Rule4 and tow additional card types (from Def8 ~ Def9) are allowed to discard.
Give out Rule6: Player C is added as a teammate of B, he will discard card following B, either B or C discards all hand cards first will be winner of B and C.
I believe there exists an linear algorithm for Give out Rule1 ~ Rule3, someone can provide such a method and related informations, or prove that the problem is exponential.
I am both new to this website and new to C. I need a program to find the average 'jumps' it takes from all points.
The idea is this: Find "jump" distance from 1 to 2, 1 to 3, 1 to 4 ... 1 to 9, or find 2 to 1, 2 to 3, 2 to 4 2 to 5 etc.
Doing them on the first row is simple, just (2-1) or (3-1) and you get the correct number. But if I want to find the distance between 1 and 4 or 1 to 8 then I have absolutely no idea.
The dimensions of the matrix should potentially be changeable. But I just want help with a 3x3 matrix.
Anyone could show me how to find it?
Jump means vertical or horizontal move from one point to another. from 1 to 2 = 1, from 1 to 9 = 4 (shortest path only)
The definition of "distance" on this kind of problems is always tricky.
Imagine that the points are marks on a field, and you can freely walk all over it. Then, you could take any path from one point to the other. The shortest route then would be a straight line; its length would be the length of the vector that joins the points, which happens to be the difference vector among two points' positions. This length can be computed with the help of Pythagora's theorem: dist = sqrt((x2-x1)^2 + (y2-y1)^2). This is known as the Euclidian distance between the points.
Now imagine that you are in a city, and each point is a building. You can't walk over a building, so the only options are to go either up/down or left/right. Then, the shortest distance is given by the sum of the components of the difference vector; which is the mathematical way of saying that "go down 2 blocks and then one block to the left" means walking 3 blocks' distance: dist = abs(x2-x1) + abs(y2-y1). This is known as the Manhattan distance between the points.
In your problem, however, it looks like the only possible move is to jump to an adjacent point, in a single step, diagonals allowed. Then the problem gets a bit trickier, because the path is very irregular. You need some Graph Theory here, very useful when modeling problems with linked elements, or "nodes". Each point would be a node, connected to their neighbors, and the problem would be to find the shortest path to another given point. If jumps had different weights (for instance, is jumping in diagonal was harder), an easy way to solve this is would be with the Dijkstra's Algorithm; more details on implementation at Wikipedia.
If the cost is always the same, then the problem is reduced to counting the number of jumps in a Breadth-First Search of the destination point from the source.
Let's define the 'jump' distance : "the number of hops required to reach from Point A [Ax,Ay] to Point B [Bx,By]."
Now there can be two ways in which the hops are allowed :
Horizontally/VerticallyIn this case, you can go up/down or left/right. As you have to travel X axis and Y axis independently, your ans is:jumpDistance = abs(Bx - Ax) + abs(By - Ay);
Horizontally/Vertically and also Diagonally
In this case, you can go up/down or left/right and diagonally as well. How it differs from Case 1 is that now you have the ability to change your X axis and Y axis together at the cost of only one jump . Your answer now is:jumpDistance = Max(abs(Bx - Ax),abs(By - Ay));
What is the definition of "jump-distance" ?
If you mean how many jumps a man needs to go from square M to N, if he can only jumps vertically and horizontally, one possibility can:
dist = abs(x2 - x1) + abs(y2 - y1);
For example jump-distance between 1 and 9 is: |3-1|+|3-1| = 4
There are two ways to calculate jump distance.
1) when only horizontal and vertical movements are allowed, in that case all you need to do is form a rectangle in between the two points and calculate the length of two adjacent side. Like if you want to move from 1 to 9 then first move from 1 to 3 and then move from 3 to 9. (Convert it to code)
2) when movements in all eight directions are allowed, things get tricky. Like if you want to move from 1 to 6 suppose. What you'll need to do is you'll have to more from 1 to 5. And then from 5 to 6. The way of doing it in code is to find the maximum in between the difference in x and y coordinates. In this example, in x coordinate, difference is 2 (3-1) and in y coordinate, difference is 1 (2-1). So the maximum of this is 2. So here's the answer. (Convert to code)
I need to read some objects from console.It is a bit like the battleship game written in C.
Think of it I have a platform of 6x6 array.I am taking the user input from the user and the char 'X' means it is a shaded area in the two dimensional array.I am assigning the chars for the 36 place.The example of the array after user has given the inputs is;
0,0 0,6
X XXX
X X
XX X
X
6,0 6,6
Sorry the output is not too clear.It is the output of the X chars that user had entered.The 'x' chars in the two groups are unioned and so, there are 2 objects in the graph.I need to count the number of the groups.The direction of the X chars is not able to be symetric, all the thing is there may be group of x chars that are unioned and i want to count the groups
Model the problem as the graph (as you already understood): G=(V,E), where V is your grid (or only the x's to be more exact), and E = { (u,v) | there is X in both u and v }
During parsing, save all your coordinates in an container, and map each to a boolean value indicating if it was visited or not.
Now, repeat while there are still non visited x's:
Run a graph discovery algorithm (BFS is an example) from this (not visited) x, and mark all visited x's encountered during the run of the discovery algorithm
The number of iterations (number of times BFS was invoked) is the number of groups.
I have a weighted graph with (in practice) up to 50,000 vertices. Given a vertex, I want to randomly choose an adjacent vertex based on the relative weights of all adjacent edges.
How should I store this graph in memory so that making the selection is efficient? What is the best algorithm? It could be as simple as a key value store for each vertex, but that might not lend itself to the most efficient algorithm. I'll also need to be able update the network.
Note that I'd like to take only one "step" at a time.
More Formally: Given a weighted, directed, and potentially complete graph, let W(a,b) be the weight of edge a->b and let Wa be the sum of all edges from a. Given an input vertex v, I want to choose a vertex randomly where the likelihood of choosing vertex x is W(v,x) / Wv
Example:
Say W(v,a) = 2, W(v,b) = 1, W(v,c) = 1.
Given input v, the function should return a with probability 0.5 and b or c with probability 0.25.
If you are concerned about the performance of generating the random walk you may use the alias method to build a datastructure which fits your requirements of choosing a random outgoing edge quite well. The overhead is just that you have to assign each directed edge a probability weight and a so-called alias-edge.
So for each note you have a vector of outgoing edges together with the weight and the alias edge. Then you may choose random edges in constant time (only the generation of th edata structure is linear time with respect to number of total edges or number of node edges). In the example the edge is denoted by ->[NODE] and node v corresponds to the example given above:
Node v
->a (p=1, alias= ...)
->b (p=3/4, alias= ->a)
->c (p=3/4, alias= ->a)
Node a
->c (p=1/2, alias= ->b)
->b (p=1, alias= ...)
...
If you want to choose an outgoing edge (i.e. the next node) you just have to generate a single random number r uniform from interval [0,1).
You then get no=floor(N[v] * r) and pv=frac(N[v] * r) where N[v] is the number of outgoing edges. I.e. you pick each edge with the exact same probability (namely 1/3 in the example of node v).
Then you compare the assigned probability p of this edge with the generated value pv. If pv is less you keep the edge selected before, otherwise you choose its alias edge.
If for example we have r=0.6 from our random number generator we have
no = floor(0.6*3) = 1
pv = frac(0.6*3) = 0.8
Therefore we choose the second outgoing edge (note the index starts with zero) which is
->b (p=3/4, alias= ->a)
and switch to the alias edge ->a since p=3/4 < pv.
For the example of node v we therefore
choose edge b with probability 1/3*3/4 (i.e. whenever no=1 and pv<3/4)
choose edge c with probability 1/3*3/4 (i.e. whenever no=2 and pv<3/4)
choose edge a with probability 1/3 + 1/3*1/4 + 1/3*1/4 (i.e. whenever no=0 or pv>=3/4)
In theory the absolutely most efficient thing to do is to store, for each node, the moral equivalent of a balanced binary tree (red-black, or BTree, or skip list all fit) of the connected nodes and their weights, and the total weight to each side. Then you can pick a random number from 0 to 1, multiply by the total weight of the connected nodes, then do a binary search to find it.
However traversing a binary tree like that involves a lot of choices, which have a tendency to create pipeline stalls. Which are very expensive. So in practice if you're programming in an efficient language (eg C++), if you've got less than a couple of hundred connected edges per node, a linear list of edges (with a pre-computed sum) that you walk in a loop may prove to be faster.
On a circle, N arbitrary points are chosen on its circumference. The complete graph formed with those N points would divide the area of the circle into many pieces.
What is the maximum number of pieces of area that the circle will get divided into when the points are chosen along its circumference?
Examples:
2 points => 2 pieces
4 points => 8 pieces
Any ideas how to go about this?
This is known as Moser's circle problem.
The solution is:
i.e.
The proof is quite simple:
Consider each intersection inside the circle. It must be defined by the intersection of two lines, and each line has two points, so every intersection inside the circle defines 4 unique sets of points on the circumference. Therefore, there are at most n choose 4 inner vertices, and obviously there are n vertices on the circumference.
Now, how many edges does each vertex touch? Well, it's a complete graph, so each vertex on the outside touches n - 1 edges, and of course each vertex on the inside touches 4 edges. So the number of edges is given by (n(n - 1) + 4(n choose 4))/2 (we divide by two because otherwise each edge would be counted twice by its two vertices).
The final step is to use Euler's formula for the number of faces in a graph, i.e.: v - e + f = 1 (the Euler characteristic is 1 in our case).
Solving for f gives the formulae above :-)