Related
I try to learn MC- Monte Carlo Method applied in blackjack using openAI Gym. And I do not understand these lines:
def __init__(self, natural=False):
self.action_space = spaces.Discrete(2)
self.observation_space = spaces.Tuple((
spaces.Discrete(32),
spaces.Discrete(11),
spaces.Discrete(2)))
self.seed()
Source from: https://github.com/openai/gym/blob/master/gym/envs/toy_text/blackjack.py
The observation space and the action space has been defined in the comments here
Observation Space:
The observation of a 3-tuple of: the player's current sum,
the dealer's one showing card (1-10 where 1 is ace),
and whether or not the player holds a usable ace (0 or 1).
eg: (14, 9, False) means the current sum is 14, card shown is 9 and there is no usable ace(because ace can be used as 1 or 11)
Action Space:
The player can request additional cards (hit=1) until they decide to stop
(stick=0) or exceed 21 (bust).
Discrete spaces are used when we have a discrete action/observation space to be defined in the environment. So spaces.Discrete(2) means that we have a discrete variable which can take one of the two possible values.
In the Blackjack environment,
self.action_space = spaces.Discrete(2)
# here spaces.Discrete(2) means that action can either be True or False.
self.observation_space = spaces.Tuple((
spaces.Discrete(32),
spaces.Discrete(11),
spaces.Discrete(2)))
# here spaces.Discrete(32) corresponds to the 32 possible sum of card number possible
# here spaces.Discrete(11) corresponds to the 11 possible cards which can be dealed
# by the dealer: [1,2,3,4,5,6,7,8,9,10(king,queen,jack),11(ace if possible)]
# here spaces.Discrete(2) corresponds to the two possible uses of the ace: [True, False]
# True if it can be used as 11.
I have an integer program that schedules 'slots' of time for instructors and students using the constraint:
for req in reqs:
sked_model += sum([x[slot] for slot in slots if ('0', 'art', req[2]) == (slot[4], slot[1], slot[3])]) == 1, ""
I need to create an additional constraint that also schedules the period immediately following for the same teacher and student. Other information:
The 'slots' represent tuples of (time, course, instructor, student, grade).
The 'reqs' also represent tuples of (grade, course, student)
I would create another 0,1 variable that represents the decision that the two slots are allocated to the the student and the teacher
i.e. for the 2nd and 3rd slot for student s and teacher t
x(2,3),s,t
Then add constraints that reflect that decision
i.e
x2,s,t >= x(2,3),s,t
x3,s,t >= x(2,3),s,t
And see how it goes, if this becomes intractable you could look at a-priory defining days for students or teachers and allocating that in your formulation.
have a look at https://pdfs.semanticscholar.org/1848/cee0d33b41b765427909297d69b8956be5f2.pdf for some other formulations
I was wondering if someone can help me, I have done a lot of work on the 8 Piece puzzle program, and now I want to stretch this out, however I am struggling.
So here is the board.
The idea of this is to try and get a piece for instance P1 which is currently residing at a1 to end up at b1. There can be anywhere up to 5 other pieces on the board and each piece can only occupy and move 1 space at a time.
What I want to be able to do is calculate the moves that are needed to get, for example P1 at position B1, to P1 at position A3 (Or any finishing position to be honest) if it can only move 1 space at a time. No two pieces can occupy the same space, and no pieces can cross over to the other side if their is a piece in the t zone. How can I code it so that when I input something like
?- pmove([at(a1,p3),at(b1,p1),at(b3,p2)],
[at(a1,p1),at(b1,p3),at(b3,p2)],M).
which inputs the starting states of all the positions and where they should all end up It will output something along the lines of:
M = [move(p3,a1,t),move(p1,b1,b2),move(p3,t,b1),
move(p1,b2,t),move(p1,t,a1)]
Showing all of the moves it took to get the piece from start to finish, as well as the moves the other pieces had to take to get to their positions. I believe it would be best to use Breadth First Search for this, but I am not all too sure where to go from there.
This is an excellent problem and working through it will be an excellent way to improve at Prolog! So I commend your choice of problem.
This answer is a sketch, not a complete solution, and I hope that is sufficient for your needs.
What you want to do next is to write a predicate that expresses a single valid move from one state to another, something that looks like this:
singlemove(StartBoardState, Move, NextBoardState) :- ...
So we're going to regard lists of at(Place, Piece) as a board state, and structures like move(Piece,From,To) as a move; the former will unify with StartBoardState and NextBoardState and the latter with Move.
The rules of your game should be encoded in singlemove/3. You could think of it as the relationship between a given board state, every valid move and the resultant states.
I think once you have this, at least one inefficient way to solve your problem will become apparent to you, using a brute-force search. Once you have that working (slowly, possibly only for two-move games), you can begin to see how to improve the performance by making the search more intelligent.
How to Implement singlemove/3
From the question, the rules of this game are:
...it can only move 1 space at a time. No two pieces can occupy the same space, and no pieces can cross over to the other side if their is a piece in the t zone.
So first, let's state some facts about the board. What are the spaces called?
boardspace(b1).
boardspace(b2).
boardspace(b3).
boardspace(t).
boardspace(a1).
boardspace(a2).
boardspace(a3).
Now we need some positional information.
:- op(300, xfx, left_of).
:- op(300, xfx, right_of).
b1 left_of b2.
b2 left_of b3.
a1 left_of a2.
a2 left_of a3.
row(b1, upper).
row(b2, upper).
row(b3, upper).
row(a1, lower).
row(a2, lower).
row(a3, lower).
X right_of Y :- Y left_of X.
adjacent(X, Y) :- X left_of Y.
adjacent(X, Y) :- X right_of Y.
adjacent(t, X) :- boardspace(X), X \= t.
adjacent(X, t) :- boardspace(X), X \= t.
I'm not sure yet if I'm going to need all of this, but this seems like a plausible start. Now let's address the rules.
There are thus three rules to the game:
Only one piece may move per turn.
A piece can only move one space per turn.
No two pieces can occupy the same space.
No pieces can "cross over to the other side" if there is a piece in the t-zone.
I feel like #1 is handled adequately by having a predicate singlemove/3 at all. We call it once, we get one move.
For #2, we can construct the list of nearby spaces based on what is adjacent to the piece right now. Assuming p1 is to move and I have a board as defined above, member(at(StartLocation, p1), Board), adjacent(StartLocation, EndLocation) will unify EndLocation with places that p1 can move. Let's try it:
?- Board = [at(a1,p3),at(b1,p1),at(b3,p2)],
member(at(StartLocation, p1), Board),
adjacent(StartLocation, EndLocation).
Board = [at(a1, p3), at(b1, p1), at(b3, p2)],
StartLocation = b1,
EndLocation = b2 ;
Board = [at(a1, p3), at(b1, p1), at(b3, p2)],
StartLocation = b1,
EndLocation = t ;
false.
So this seems correct; the adjacent locations to b1 are b2 and t.
Now let's codify the next rule, no two pieces can occupy the same space.
unoccupied(Board, Location) :-
\+ member(at(Location, _), Board).
Now we can combine these two things into a good start at singlemove/3:
singlemove(Board,
move(Piece,StartLocation,EndLocation),
[at(EndLocation,Piece)|RemainingLocations]) :-
select(at(StartLocation,Piece), Board, RemainingLocations),
adjacent(StartLocation, EndLocation),
unoccupied(Board, EndLocation).
Let's try it:
?- Board = [at(a1,p3),at(a2,p1),at(a3,p2)],
singlemove(Board, Move, NextBoard).
Board = [at(a1, p3), at(a2, p1), at(a3, p2)],
Move = move(p3, a1, t),
NextBoard = [at(t, p3), at(a2, p1), at(a3, p2)] ;
Board = [at(a1, p3), at(a2, p1), at(a3, p2)],
Move = move(p1, a2, t),
NextBoard = [at(t, p1), at(a1, p3), at(a3, p2)] ;
Board = [at(a1, p3), at(a2, p1), at(a3, p2)],
Move = move(p2, a3, t),
NextBoard = [at(t, p2), at(a1, p3), at(a2, p1)] ;
false.
So what's interesting about this? I'm using select/3 to chop the list into candidates and remainders. I'm building the results in the head of the clause. But otherwise, I'm really just taking your rules, translating them into Prolog, and listing them. So you can see you just need one more predicate to implement your fourth rule and it will go right after unoccupied/2, to further filter out invalid moves.
Hopefully, you get the gist of the process. My data model may be too much, but then again, you may find you need more of it than it seemed at first. And the search strategy is weak. But this is the underpinning of the overall solution, the base case. The inductive case will be interesting—I again suggest you try it with the built-in depth-first strategy and see how horrible it is before resorting to BFS. You will probably want to use trace/0 and see when you get stuck in a trap and how you can circumvent it with better explicit reasoning. But I think this is a good start and I hope it's helpful to you.
Writing a simulation in an object-oriented language, each object has an identity--that is, a way to distinguish it from every other object in the simulation, even if other objects have the exact same attributes. An object retains its identity, no matter how much it changes over time. This is because each object has a unique location in memory, and we can express that location with pointers or references. This works even if you don't impose an additional identity system like GUIDs. (Which you would often do to support things like networking or databases which don't think in terms of pointers.)
I don't believe there is an equivalent concept in Haskell. So, would the standard approach be to use something like GUIDs?
Update to clarify the problem: Identity is an important concept in my problem domain for one reason: Objects have relationships to each other, and these must be preserved. For example, Haskell would normally say a red car is a red car, and all red cars are identical (provided color is the only attribute cars have). But what if each red car must be linked to its owner? And what if the owner can repaint his cars?
Final update synthesizing the answers: The consensus seems to be that you should only add identifiers to data types if some part of the simulation will actually use those identifiers, and there's no other way to express the same information. E.g. for the case where a Person owns multiple Cars, each of which has a color, a Person can keep a list of immutable Cars. That fully expresses the ownership relationship as long as you have access to the Person.
The Person may or may not need some kind of unique identifier. One scenario where this would occur is: There's a function that takes a Car and a collection of all Persons and imposes a ParkingTicket on the appropriate Person. The Car's color cannot uniquely identify the Person who gets the ticket. So we can give the Person an ID and have the Car store it.
But even this could potentially be avoided with a better design. Perhaps our Cars now have an additional attribute of type ParkingPosition, which can be evaluated as legal or illegal. So we pass the collection of Persons to a function that looks at each Person's list of Cars, checks each one's ParkingPosition, and imposes the ParkingTicket on that Person if appropriate. Since this function always knows which Person it's looking at, there's no need for the Car to record that info.
So in many cases, assigning IDs is not as necessary as it first may seem.
Why do you want to "solve" this non-problem? Object identity is a problem with OO languages which Haskell happily avoids.
In a world of immutable objects, two objects with identical values are the same object. Put the same immutable object twice into a list and you have two different objects wherever you want to see things that way (they "both" contribute to the total number of elements, for example, and they have unique indexes) without any of the problems that Java-style reference equality causes. You can even save that list to a database table and get two different rows, if you like. What more do you need?
UPDATE
Jarret, you seem to be convinced that the objects in your model must have genuinely separate identities just because real life ones would be distinct. However, in a simulation, this only matters in the contexts where the objects need to be differentiated. Generally, you only need unique identifiers in a context where objects must be differentiated and tracked, and not outside those contexts. So identify those contexts, map the lifecycle of an object that is important to your simulation (not to the "real" world), and create the appropriate identifiers.
You keep providing answers to your own questions. If cars have owners, then Bob's red car can be distinguished from Carol's red car. If bob can repaint his car, you can replace his red car with a blue car. You only need more if
Your simulation has cars without owners
You need to be able to distinguish between one ownerless red car and another.
In a simple model, 1 may be true and 2 not. In which case, all ownerless red cars are the same red car so why bother making them distinct?
In your missile simulation, why do missiles need to track their owning launchers? They're not aimed at their launchers! If the launcher can continue to control the missile after it is launched, then the launcher needs to know which missiles it owns but the reverse is not true. The missile just needs to know its trajectory and target. When it lands and explodes, what is the significance of the owner? Will it make a bigger bang if it was launched from launcher A rather than launcher B?
Your launcher can be empty or it can have n missiles still available to fire. It has a location. Targets have locations. At any one time there are k missiles in flight; each missile has a position, a velocity/trajectory and an explosive power. Any missile whose position is coincident with the ground should be transformed into an exploding missile, or a dud etc etc.
In each of those contexts, which information is important? Is the launcher identity really important at detonation time? Why? Is the enemy going to launch a retaliatory strike? No? Then that's not important information for the detonation. It probably isn't even important information after launch. Launching can simply be a step where the number of missiles belonging to Launcher A is decremented while the number of missiles in flight is incremented.
Now, you might have a good answer to these questions, but you should fully map your model before you start lumbering objects with identities they may not need.
My approach would be to store all state information in a data record, like
data ObjState = ObjState
{ objStName :: String
, objStPos :: (Int, Int)
, objStSize :: (Int, Int)
} deriving (Eq, Show)
data Obj = Obj
{ objId :: Int
, objState :: ObjState
} deriving (Show)
instance Eq Obj where
obj1 == obj2 = objId obj1 == objId obj2
And the state should be managed by the API/library/application. If you need true pointers to mutable structures, then there are built-in libraries for it, but they're considered unsafe and dangerous to use unless you know what you're doing (and even then, you have to be cautious). Check out the Foreign modules in base for more information.
In Haskell the concepts of values and identities are decoupled. All variables are simply immutable bindings to values.
There are a few types whose value is a mutable reference to another value, such as IORef, MVar and TVar, these can be used as identities.
You can perform identity checks by comparing two MVars and an equality check by comparing their referenced values.
An excellent talk by Rich Hickey goes in detail over the issue: http://www.infoq.com/presentations/Value-Values
You can always write:
> let mylist = take 25 $ cycle "a"
> mylist
"aaaaaaaaaaaaaaaaaaaaaaaaa"
> zip mylist [1..]
[('a',1),('a',2),('a',3),('a',4),('a',5),('a',6),('a',7),('a',8),('a',9),('a',10),
('a',11),('a',12),('a',13),('a',14),('a',15),('a',16),('a',17),('a',18),('a',19),
('a',20),('a',21),('a',22),('a',23),('a',24),('a',25)]
If we are not joking - save it as part of data
data MyObj = MyObj {id ::Int, ...}
UPDATED
If we want to work with colors and ids separately, we can do next in Haskell:
data Color = Green | Red | Blue deriving (Eq, Show)
data Car = Car {carid :: Int, color :: Color} deriving (Show)
garage = [Car 1 Green, Car 2 Green, Car 3 Red]
redCars = filter ((== Red) . color) garage
greenCars = filter ((== Green) . color) garage
paint2Blue car = car {color=Blue}
isGreen = (== Green) . color
newGarage = map (\car -> if isGreen car then paint2Blue car else car) garage
And see result in gchi:
> garage
[Car {carid = 1, color = Green},Car {carid = 2, color = Green},Car {carid = 3, color = Red}]
> redCars
[Car {carid = 3, color = Red}]
> greenCars
[Car {carid = 1, color = Green},Car {carid = 2, color = Green}]
> newGarage
[Car {carid = 1, color = Blue},Car {carid = 2, color = Blue},Car {carid = 3, color = Red}]
I have a game that one player X wants to pass a ball to player Y, but he can be playing with more than one player and the others players can pass the ball to Y.
I want to know how many different paths can the ball take from X to Y?
for example if he is playing with 3 players there are 5 different paths, 4 players 16 paths, if he is playing with 20 players there are 330665665962404000 paths, and 40 players 55447192200369381342665835466328897344361743780 that the ball can take.
the number max. of players that he can play with is 500.
I was thinking in using Catalan Numbers? do you think is a correct approach to solve this?
Can you give me some tips.
At first sight, I would say, that tht number of possible paths can be calculated the following way (I assume a "path" is a sequence of players with no player occuring more than once).
If you play with n+2 players, i.e. player X, player Y and n other players that could occur in the path.
Then the path can contain 0, 1, 2, 3, ... , n-1 or n "intermediate" players between player X (beginning) and player Y (end).
If you choose k (1 <= k <= n) players from n players in total, you can do this in (n choose k) ways.
For each of this subsets of intermediate players, there are k! possible arrangements of players.
So this yields sum(i=0 to n: (n choose i) * i!).
For "better" reading:
---- n / n \ ---- n n! ---- n 1
\ | | \ -------- \ ------
/ | | * i! = / (n-i)! = n! / i!
---- i=0 \ i / ---- i=0 ---- i=0
But I think that these are not the catalan numbers.
This is really a question in combinatorics, not algorithms.
Mark the number of different paths from player X to player Y as F(n), where n is the number of players including Y but not X.
Now, how many different paths are there? Player X can either pass the ball straight to Y (1 option), or pass it to one of the other players (n-1 options). If X passes to another player, we can pretend that player is the new X, where there are n-1 players in the field (since the 'old' X is no longer in the game). That's why
F(n) = 1 + (n-1)F(n-1)
and
F(1) = 1
I'm pretty sure you can reach phimuemue's answer from this one. The question is if you prefer a recursive solution or one with summation.
I'm somewhat of a noob at this kind of searching, but a quick run through the numbers demonstrates the more you can trim, cut out, filter out, the faster you can do it. The numbers you cite are BIG.
First thing that comes to mind is "Is it practical to limit your search depth?" If you can limit your search depth to say 4 (an arbitrary number), your worst case number of possibilities comes out to ...
499 * 498 * 497 * 496 = 61,258,725,024 (assuming no one gets the ball twice)
This is still large, but an exhaustive search would be far faster (though still too slow for a game) than your original set of numbers.
I'm sure others with more experience in this area would have better suggestions. Still, I hope this helps.
If X needs to pass to Y, and there could be P1, P2, ..., Pn players in between and you care about the order of passing then indeed
For 2 extra players you have paths: X-Y, X-P1-Y, X-P2-Y, X-P1-P2-Y, X-P2-P1-Y
Which gives a total of 5 different paths, similarly for 3 extra players you have 16 different paths
First try to reduce the problem to something known, and for this I would eliminate X-Y, they are common to all of the above translates to question: what is the sum of k-permutations for k from 0 to n, where n is the number of P.
This can be given as
f(n):=sum(n!/(n-i)!,i,0,n);
and I can confirm your findings for 19 and 39 (20 and 40 in your notation).
For f(499) I get
6633351524650661171514504385285373341733228850724648887634920376333901210587244906195903313708894273811624288449277006968181762616943058027258258920058014768423359811679381900054568501151839849768338994244697593758840394106353734267539926205845992860165295957099385939316593862710470512043836452624452665801937754479602741031832540175306674471495745716725509714798824661807396000105338256698426305553340786519843729411660457896089840381658295930455362209587765698327585913037665131195504013431486823990271059962837959407778393078276213331859189770016153265512805722812864376997337140529242894215031131618375899072989922780132488077015246576266246551484603286735418485007674249207286921801779414240854077425752351919182464902664206622037834736215298295580945851569079682952183639701057397376328170754187008425429164206646365285647875545882646729176997107332605851460212415526607757545366695048460341802079614840254694664267117469603856584752270653889630424848913719533359942725361985274851471687885265903663806182184272555073708882789845441094009797907518245726494471433964169680271980763830020431957658400573531564215436064984091520
Results obtained with wxMaxima
EDIT: After more clarification from the comments of the question, my answer is absolutely useless :) he definitely wants the number of possible routes, not the best one!
My first thought is why do you want to know these numbers? You're certainly never going to iterate through all the paths available to 500 people (would take far too long) and it's too big to display on a ui in any meaningful way.
I'm assuming that you're going to try to find the best route that the ball can take in which case I would consider looking into algorithms that don't care about the number of nodes in a route.
I'd try looking at the A star algorithm and Dijkstra's algorithm.