Allright, makes sense... I must have mist the 'integer only' for all 
expressions (including $nth). Using 'map' seems to be doing what I expect 
(at first sight).

Thx!


Op woensdag 7 oktober 2015 05:50:37 UTC+2 schreef Alex Engelberg:
>
> Loco's constraints and expressions only work on integers, so unfortunately 
> $nth can't handle maps in a list. $nth takes either a list of Loco 
> expressions or a list of integers. To get the nth player level, you could 
> try:
> ($nth (map :level players) [:p 0 0])
>
> Also, I should mention that all Loco constraints (anything beginning with 
> $, really) don't really return any values of substance, they just return a 
> map of constraint data to be used by other constraints and the solving 
> function. So your usage of ":level" is not going to behave how you expect 
> (it will just return "nil" because the return value of $nth has no :level 
> key).
>
> Let me know how my alternative solution works for you.
>
> Thanks!
> --Alex
>
> On Tuesday, October 6, 2015 at 7:22:55 AM UTC-7, Kurt Sys wrote:
>>
>>
>> So, the basic idea is to construct a matrix like this:
>>          spot1  spot2  spot3
>> team1      5      0      -1
>> team2      4      1      -1 
>> ...
>>
>> With the 'spots' the spaces to fill in for each team. There are max 3 
>> spots/team. If a spot is not used, -1 should be put. If it is used, I put 
>> the number of the player (index in the defined vector). For example, with a 
>> very small player vector:
>> (def players [{:level 3} {:level 4} {:level 7} {:level 1}])
>>
>>
>> The problems I'm facing so far:
>>
>> 1/ using $distinct to make sure each player is only assigned one spot on 
>> one team.
>> The value of -1 can be used more than once, because it's used as filler 
>> where no player is assigned.
>>
>> (defn base-model [players]
>>   (concat (for [team (range (quot (count players) 2)), spot (range 3)] 
>>     ($in [:p team spot] (range -1 (count players)) ))))
>>  
>> (def all (for [team (range (quot (count players) 2)), spot (range 3)] 
>>   [:p team spot]))
>>
>> (solutions (conj (base-model ps) ($distinct all) ))
>>
>>
>> doesn't give any solutions, obviously: there are always more possible 
>> spots to fill than there are players. A work-around would be to add more 
>> negative numbers as 'fillers', and adding some other constraints so that at 
>> least two of the three spots per team are positive. I'll make sure the 
>> vector is sorted anyway, on level first and experience second (with the 
>> player having the highest number in the front of each team, as captain), so 
>> that might be rather easy to do. 
>> But it feels rather hacky.
>>
>> 2/ getting player data with $nth, so constraints based on player 
>> characteristics can be added. 
>> For example, if I want player of team 1 on slot 1 having a level of more 
>> than 2, I'd expect something like this to work:
>> (solutions (conj (base-model ps) ($> (:level ($nth players [:p 0 0])) 2) 
>>  ))
>> which translates to me: take player on index given by [:p 0 0] from 
>> 'players', get the level from that player and check if it's higher than 2. 
>> This, however, does not work:
>> IllegalArgumentException No method in multimethod '->choco*' for 
>> dispatch value: null  clojure.lang.MultiFn.getFn (MultiFn.java:156)
>> I clearly misunderstand how $nth (or how loco in general) works. How I 
>> can use my player characteristics (the vector of player data maps) for 
>> adding constraints?
>>
>> Thx, qsys
>>
>>
>>
>>
>> Op dinsdag 6 oktober 2015 12:10:23 UTC+2 schreef Kurt Sys:
>>>
>>> Reading the thread: generate al possible teams 
>>> <https://groups.google.com/forum/#!searchin/clojure/generate$20all$20possible$20teams/clojure/DeCBCD_dwRo/OyjJPgHXCAAJ>,
>>>  
>>> I realized I was facing a slightly similar problem. Although many valuable 
>>> suggestions were made, I'm very interested in one made 
>>> <https://groups.google.com/d/msg/clojure/DeCBCD_dwRo/nw4aW4zwCAAJ> by 
>>> puzzler, 
>>> i.e. using loco (unless another method/library is more useful, suggestions 
>>> are welcome).
>>>
>>> Now, the problem description: 
>>> 1/ I have a set of players which must be divided in teams of two. If 
>>> only teams of two is not possible, teams of three are allowed as well.
>>> 2/ Every player has a set of characteristics. Based on these 
>>> characteristics, some teams are not allowed, some are, and some are 
>>> prefered.
>>>
>>> There are quite a few characteristics, so I'll build up the first few:
>>> 1/ The main characteristic is 'level', ranging from 0-7. Only teams of 
>>> two with total level of 5 or more are allowed. 
>>> For teams of three, there are separate rules: there must be at least one 
>>> level 3. If the highest level is 3, than no two levels 1 or less are 
>>> allowed. 
>>>
>>> 2/ There is a characteristic 'experience' as well. Taking into account 
>>> the exprience, there are more exceptions:
>>> A level 3 and a level 1 is allowed (in contrast to rule 1: total should 
>>> be at least 5), if the experience of level 1 is high enough
>>> A level 4 and a level 1 are not allowed together, if the experience of 
>>> level 1 is not high enough
>>> Two levels 2 are allowed, if both are experienced enough
>>>
>>> So far, it's still pretty easy to find a solution: rank according to 
>>> level and experience, and take each time the top and bottom from the list. 
>>> That should be pretty close to the most optimal solution. But there are 
>>> more characteristics for each player:
>>>
>>> 3/ There are preferences to put some players together, scored from 1 
>>> (avoid teaming them) to 7 (high preference to team them). Based on these 
>>> preferences, 'team preferences' might be calculated. If no 'preference' is 
>>> given, a value of 4 is assumed. In this example, I scored them per player, 
>>> but it might be done per team as well.
>>>
>>> 4/ Some players might have a 'handicap', so they need another levels to 
>>> team with. If possible, the handicaps should be used, but they may be 
>>> omitted if there is no other solution. In an extended version, a preference 
>>> level for a handicap for a certain player may be set as well.
>>>
>>> There are quite a few of handicaps (like 4) and rules (like 1 and 2, 
>>> which are just a small subset of all handicaps and rules.
>>>
>>> The number of players will not be very high, up to max 100, so max 50 
>>> teams, which might be important, since I don't think heuristics will have a 
>>> high benefit in this case (but I might be wrong).
>>>
>>> An example: 
>>>
>>> The players:
>>> P1 {:level 0 :experience 0}
>>> P2 {:level 2 :experience 17}
>>> P3 {:level 3 :experience 23 :handicap :cl }
>>> P4 {:level 3 :experience 27 :preference {P2 2, P3 6}}
>>> P5 {:level 6 :experience 50}
>>> P6 {:level 5 :experience 55 :preference {P2 1}}
>>>
>>> The handicap description: {:cl :needs-level 5}
>>>
>>> The solution?
>>> (solve [P1 P2 P3 P4 P5 P6])
>>> results in a set with possible solutions (possibly with some timeout or 
>>> after the first x solutions are found):
>>> #{ 
>>>   { [ [P6 P1] [P5 P2] [P4 P3] ]
>>>     :unmatched-handicaps 1
>>>     :team-preferences [4 4] [4 4] [4 6] }
>>>   { [ [P5 P1] [P6 P2] [P4 P3] ]
>>>     :unmatched-handicaps 1
>>>     :team-preferences [4 4] [1 4] [4 6] }
>>>   { [ [P5 P3] [P6 P1] [P4 P2] ]
>>>     :unmatched-handicaps 0
>>>     :team-preferences [4 4] [4 4] [2 4] }
>>>   ... }
>>>
>>> Since puzzler said 'I can provide an example of that if you are 
>>> interested' (for generating 'balanced teams' with restrictions with 
>>> loco)... I'm interested :).
>>>
>>> Thanks.
>>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to