I am creating a program that works with geographic information. I have data that contains what geographic units touch each other. The function that fails is intended to add neighboring units to an array based on population (for example, it starts with a unit, then adds the most populous neighboring unit to the array, and then adds the most populous unit that touches one of the units in the array, and continues this until it reaches a population limit). The way I am doing this is using a for loop, and then using an array of the total units that have been sorted by population. I then find the index of the first (and therefore most populous) neighbor using the intersection between the neighbors of the units in the array and the neighbors of each unit in the array of total units. The following is my code (please excuse the clunkiness):
func createDistrict () {
if useBoard.isEmpty == false {
useBoard.sort(by: {$0.population > $1.population})
var maxPop = useBoard.first!.population
district.removeAll()
district.append(useBoard.first!)
useBoard.removeFirst()
for i in 0...useBoard.count - 1 {
if useBoard.indices.contains(i) {
if useBoard[i] == nil || district.map({$0.population}).reduce(0,+) > districtMax {
break
}
} else {
break
}
useBoard.sort(by: {$0.population > $1.population})
var superArray:[Precinct] = []
district.forEach { (z) in
superArray += z.neighbors
Array(Set(superArray))
}
var nextPre = useBoard.firstIndex { (l) -> Bool in
Set(l.neighbors).intersection(Set(superArray)).isEmpty == false
}
if nextPre == nil {
break
}else {
var temporary = Set(useBoard[nextPre!].neighbors).intersection(Set(superArray))
var newString = ""
var newTemp = Array(temporary)
for t in 0...newTemp.count - 1 {
var next = useBoard.firstIndex { (k) -> Bool in
k == newTemp[t]
}
newString.append("\(newTemp[t]) (\(next)), ")
}
print("\(useBoard[nextPre!].precinctID) (\(nextPre!)) touches \(newString)")
}
district.append(useBoard[nextPre!])
useBoard.remove(at: nextPre!)
}
}
district.forEach { (p) in
print("\(p.precinctID)")
}
}
In this function, var nextPre = useBoard.firstIndex { (l) -> Bool in Set(l.neighbors).intersection(Set(superArray)).isEmpty == false} is used to find the index of the most populous neighbor. However, when I test it using print, I get an incorrect output. In the following excerpt, the values in the parentheses are just the indices and don't really matter. The output:
2104 (8) touches 1987 (Optional(710)), 2676 (Optional(1591)),
2387 (10) touches 2105 (Optional(2140)),
2274 (11) touches 2273 (Optional(52)), 2386 (Optional(236)),
2275 (14) touches 2276 (Optional(22)), 2105 (Optional(2138)), 2273 (Optional(51)),
2276 (21) touches 2389 (Optional(1638)), 2273 (Optional(50)), 2274 (nil), 2275 (nil), 2277 (Optional(2771)), 2386 (Optional(234)),
2067 (35) touches 2404 (Optional(76)), 2212 (Optional(944)),
2406 (40) touches 2404 (Optional(75)), 2070 (Optional(1771)),
2440 (42) touches 2212 (Optional(942)), 2388 (Optional(497)), 2441 (Optional(1364)),
2273 (46) touches 2386 (Optional(230)), 2276 (nil), 2064 (Optional(384)), 2275 (nil), 2105 (Optional(2133)), 2274 (nil), 2387 (nil),
1795 (55) touches 1891 (Optional(1212)),
1908 (41) touches 2638 (Optional(2568)), 1869 (Optional(474)),
2404 (70) touches 2212 (Optional(938)), 2070 (Optional(1766)), 2069 (Optional(365)), 2068 (Optional(581)), 1743 (Optional(2453)), 2405 (Optional(2442)), 2387 (nil), 2105 (Optional(2130)), 2284 (Optional(2792)),
2736 (70) touches 2548 (Optional(1314)), 2420 (Optional(1305)),
1798 (52) touches 2419 (Optional(270)),
1907 (45) touches 1912 (Optional(1611)), 2737 (Optional(2082)),
As you can see, the neighbors are off by 1. For example, 2104 is the first unit. Then 2387 touches 2105, which is 2104 + 1. Then 2274 touches 2386, which is 2387 - 1. Then 2275 touches 2105, which is 2104 + 1. The .intersection should find the first unit that touches the units in the array, yet it finds the first unit that touches a unit's name + 1. I have no idea how this is occurring, as the geographic units are stored in a custom object, not an integer or any other number variable. Here is the custom object:
class Precinct {
var precinctID:String
var population:Int
var neighbors:[Precinct]
init(precinctID:String, population:Int, neighbors:[Precinct]){
self.precinctID = precinctID
self.population = population
self.neighbors = neighbors
}
}
extension Precinct: Equatable {
static func == (lhs: Precinct, rhs: Precinct) -> Bool {
return lhs.precinctID == rhs.precinctID && lhs.population == rhs.population && lhs.neighbors == rhs.neighbors
}
}
extension Precinct: Hashable {
var hashValue: Int {
return precinctID.hashValue ^ population.hashValue
}
}
extension Precinct: CustomStringConvertible {
var description: String {
return "\(precinctID)"
}
}
What's going wrong and how can I fix it? Thanks.
The problem is due to the fact that you are removing elements of useBoard while at the same time iterating over useBoard. You are printing the indices "\(newTemp[t]) (\(next)), " and then five lines later removing an index; before repeating the process. While you can change the values of a collection you are iterating over, never change the size of the collection at the same time.
A first step may be to copy useBoard before running the outer loop. Keep it constant so that you iterate over all of its contents but use the copy for all of your logic. I have trouble following the intent of your code.
As far as the hash, that is not your problem. However it is not ideal. Swift provides a default hash that is almost always better. Just allow Swift to synthesize its own algorithm by changing that extension to this.
extension Precinct: Hashable {}
There are a couple of issues. Please remove the call to sort useBoard within the outer loop. That has no effect because useBoard was already sorted before entering the loop. Also Array(Set(superArray)) is not doing anything for you.
Good luck.
Shake uses various forms of matching, filepath against pattern. Is there one which can be used to exclude a pattern?
Example:
I have three directories a, b, c (somewhere in directory x) and each needs html files. There is a rule
(dir <> "//*.html") %> \out -> do -- deal with a and b
which should only deal with the directories a and b and a similar rule to process the files in c.
Is there a way (perhaps using ?>) to separate the two rules for one
(\f -> "x" prefixOf f && not "x/c" prefixOf f) <> "//*.html")
(\f -> "x/x" prefixOf f ) <> "//*.html")
and the other similarly?
The recommended approach to use xx.a.html and xx.b.html is here not possible, because files are processed with other programs which expect the regular html extension.
Alternatively
The rule:
pattern %> action
Is equivalent to:
(pattern ?==) ?> action
So you can write:
(\x -> "//*.html" ?== x && not ("c//*.html" ?== x) ?> action
To match rules matching //*.html, but not c//*.html.
More generally, there is no requirement to use the FilePattern ?== operator at all, so arbitrary matching predicates can be used instead.
With the advice (especially the hint about using **/*.html) I have it working.
The path bakedD is a prefix of staticD and the first rule deals only with files in bakedD which are not in staticD, the other only with these:
(\x -> ((bakedD <> "**/*.html") ?== x)
&& not ((staticD <> "**/*.html") ?== x)) ?> \out -> do
let md = doughD </> (makeRelative bakedD $ out -<.> "md")
runErr2action $ bakeOneFileFPs md doughD templatesD out
(staticD <> "**/*.html" ) %> \out -> do
copyFileChanged (replaceDirectory out doughD) out
There is no overlap between the two rules.
I hope this is useful for others with the same type of issue.
I'm having trouble switching to an iterate version of some loop code:
(defun get-bound-?vars-1 (tree)
(loop for item in tree
when (consp item)
if (member (car item) '(exists forall doall))
nconc (delete-if-not #'?varp
(alexandria:flatten (second item)))
else nconc (get-bound-?vars item)))
My corresponding iterate translation:
(defun get-bound-?vars-2 (tree)
(iter (for item in tree)
(when (consp item)
(if (member (car item) '(exists forall doall))
(nconc (delete-if-not #'?varp
(alexandria:flatten (second item))))
(nconc (get-bound-?vars item))))))
As test case:
(defparameter *tree*
'(if (exists (?t transmitter)
(and (connecting ?t ?connector)
(bind (color ?t $hue))))
(if (not (exists ((?t1 ?t2) transmitter)
(and (connecting ?t1 ?connector)
(connecting ?t2 ?connector)
(bind (color ?t1 $hue1))
(bind (color ?t2 $hue2))
(not (eql $hue1 $hue2)))))
(activate-connector! ?connector $hue))))
Then loop OK:
(get-bound-?vars-1 *tree*) => (?T ?T1 ?T2)
But iterate not OK:
(get-bound-?vars-2 *tree*) => NIL
Thanks for any pointers.
I'm new to the pddl. I need to find solution where a robot can put different objects in different destination cells. I'm using the software from http://www.fast-downward.org/. However, The problem is that my actions can't find the solution as required.
The restriction is that no 2 objects can be in the same room even if the robot is carrying an object.
attached: the domain file:
(define (domain gripper-strips)
(:predicates (ROOM ?x) ;iff x is a room
(OBJECT ?x) ;iff x is an onject
(HAND ?x) ;iff x is the robot's hand
(FREE ?x) ;iff x is the robot's hand and it is free of object
(ROBOT-AT ?x) ;iff x is a room and robot is located in x
(OBJECT-AT ?x ?y) ;iff x is an object + y is a room and x is located at y
(PATH ?x ?y) ;iff x and y are both room and there is no wall in-between
(CARRY ?x) ;iff x is an object and robot is carrying it
)
(:action MoveWithoutObject
:parameters (?room1 ?room2 ?hand)
:precondition (and (ROOM ?room1) (ROOM ?room1) (HAND ?hand) (not(=?room1 ?room2))
(FREE ?hand) (ROBOT-AT ?room1) (PATH ?room1 ?room2))
:effect (and (ROBOT-AT ?room2)
(not (ROBOT-AT ?room1)))
)
(:action MoveWithObject
:parameters (?room1 ?room2 ?obj ?hand)
:precondition (and (ROOM ?room1) (ROOM ?room2) (OBJECT ?obj) (HAND ?hand) (not(=?room1 ?room2))
(not (OBJECT-AT ?obj ?room1)) (not (OBJECT-AT ?obj ?room2))
(ROBOT-AT ?room1) (not(FREE ?hand))
(PATH ?room1 ?room2))
:effect (and (ROBOT-AT ?room2)
(not (ROBOT-AT ?room1)))
)
(:action Pickup
:parameters (?obj ?room ?hand)
:precondition (and (OBJECT ?obj) (ROOM ?room) (HAND ?hand)
(OBJECT-AT ?obj ?room) (ROBOT-AT ?room) (FREE ?hand) (not(CARRY ?obj)))
:effect (and (CARRY ?obj) (not (OBJECT-AT ?obj ?room)) (not (FREE ?hand)))
)
(:action Release
:parameters (?obj ?room ?hand)
:precondition (and (OBJECT ?obj) (ROOM ?room) (HAND ?hand)
(not(OBJECT-AT ?obj ?room)) (ROBOT-AT ?room) (not(FREE ?hand)) (CARRY ?obj))
:effect (and (OBJECT-AT ?obj ?room)
(not(CARRY ?obj))
(FREE ?hand))))
and the problem file:
(define (problem strips-gripper-x-8)
(:domain gripper-strips)
(:objects room1 room2 room3 room4 room5 room6 room7 room8 room9
object1 object2 object3
hand)
(:init (ROOM room1)(ROOM room2)(ROOM room3)(ROOM room4)(ROOM room5)(ROOM room6)(ROOM room7)(ROOM room8)(ROOM room9)
(OBJECT object1)(OBJECT objec21)(OBJECT object3)
(HAND hand)
(FREE hand)
(ROBOT-AT room1)
(OBJECT-AT object1 room6)(OBJECT-AT object2 room4)(OBJECT-AT object3 room7)
(PATH room1 room4)(PATH room4 room1)
(PATH room4 room5)(PATH room5 room4)
(PATH room5 room6)(PATH room6 room5)
(PATH room5 room8)(PATH room8 room5)
(PATH room6 room9)(PATH room9 room6)
(PATH room6 room3)(PATH room3 room6)
(PATH room3 room2)(PATH room2 room3)
(PATH room8 room7)(PATH room7 room8))
(:goal (and (OBJECT-AT object1 room7)(OBJECT-AT object2 room2)(OBJECT-AT object3 room9))))
Your approach is seemingly correct, but you have a couple of typos in your files that hinder the possibility of finding a solution.
problem.pddl:
change
(OBJECT object1)(OBJECT objec21)(OBJECT object3)
with
(OBJECT object1) (OBJECT object2) (OBJECT object3)
domain.pddl: change
change
(ROOM ?room1) (ROOM ?room1)
in action MoveWithoutObject with
(ROOM ?room1) (ROOM ?room2)
EDIT:
This escaped my first check since I didn't know the language in the first place and I assumed there was an universal quantification over the variables. You also need to fix MoveWithObject like this:
(:action MoveWithObject
:parameters (?room1 ?room2 ?obj1 ?obj2 ?obj3 ?hand)
:precondition (and (ROOM ?room1) (ROOM ?room2) (HAND ?hand) (not(=?room1 ?room2))
(OBJECT ?obj1) (OBJECT ?obj2) (OBJECT ?obj3)
(not (OBJECT-AT ?obj1 ?room1)) (not (OBJECT-AT ?obj1 ?room2))
(not (OBJECT-AT ?obj2 ?room1)) (not (OBJECT-AT ?obj2 ?room2))
(not (OBJECT-AT ?obj3 ?room1)) (not (OBJECT-AT ?obj3 ?room2))
(not (= ?obj1 ?obj2))
(not (= ?obj1 ?obj3))
(not (= ?obj2 ?obj3))
(ROBOT-AT ?room1) (not (FREE ?hand)) (PATH ?room1 ?room2))
:effect (and (ROBOT-AT ?room2)
(not (ROBOT-AT ?room1)))
)
Now the solver finds the following solution:
Solution found!
Actual search time: 2.23336s [t=4.41504s]
movewithoutobject room1 room4 hand (1)
movewithoutobject room4 room5 hand (1)
movewithoutobject room5 room6 hand (1)
pickup object1 room6 hand (1)
movewithobject room6 room3 object1 object2 object3 hand (1)
release object1 room3 hand (1)
movewithoutobject room3 room6 hand (1)
movewithoutobject room6 room5 hand (1)
movewithoutobject room5 room8 hand (1)
movewithoutobject room8 room7 hand (1)
pickup object3 room7 hand (1)
movewithobject room7 room8 object1 object2 object3 hand (1)
movewithobject room8 room5 object1 object2 object3 hand (1)
movewithobject room5 room6 object1 object2 object3 hand (1)
movewithobject room6 room9 object1 object2 object3 hand (1)
release object3 room9 hand (1)
movewithoutobject room9 room6 hand (1)
movewithoutobject room6 room3 hand (1)
pickup object1 room3 hand (1)
movewithobject room3 room6 object1 object2 object3 hand (1)
movewithobject room6 room5 object1 object2 object3 hand (1)
movewithobject room5 room8 object1 object2 object3 hand (1)
movewithobject room8 room7 object1 object2 object3 hand (1)
release object1 room7 hand (1)
movewithoutobject room7 room8 hand (1)
movewithoutobject room8 room5 hand (1)
movewithoutobject room5 room4 hand (1)
pickup object2 room4 hand (1)
movewithobject room4 room5 object1 object2 object3 hand (1)
movewithobject room5 room6 object1 object2 object3 hand (1)
movewithobject room6 room3 object1 object2 object3 hand (1)
movewithobject room3 room2 object1 object2 object3 hand (1)
release object2 room2 hand (1)
Plan length: 33 step(s).
Plan cost: 33
I used the following strategy for finding this solution, other strategies might find longer paths:
$ fast-downward.py --alias seq-opt-bjolp problem.pddl
I've written a domain and a test problem in PDDL, but apparently the graphplan implementation can't find a plan. Here's the domain:
(define (domain aperture)
(:requirements :strips :typing :negative-preconditions)
(:types
cube
hallway room - location
)
(:predicates
(at ?l - location)
(has ?c - cube)
(connected ?l1 - location ?l2 - location)
(in ?c - cube ?l - location)
)
(:action enter
:parameters (?h - hallway ?r - room)
:precondition (and (connected ?h ?r) (connected ?r ?h) (at ?h)
(not (at ?r)))
:effect (and (at ?r) (not (at ?h)))
)
(:action exit
:parameters (?r - room ?h - hallway)
:precondition (and (connected ?r ?h) (connected ?h ?r) (at ?r)
(not (at ?h)))
:effect (and (at ?h) (not (at ?r)))
)
(:action move
:parameters (?h1 ?h2 - hallway)
:precondition (and (connected ?h1 ?h2) (connected ?h2 ?h1)
(at ?h1) (not (at ?h2)))
:effect (and (at ?h2) (not (at ?h1)))
)
(:action pickup
:parameters (?c - cube ?l - location)
:precondition (and (at ?l) (not (has ?c)) (in ?c ?l))
:effect (and (has ?c) (not (in ?c ?l)))
)
(:action drop
:parameters (?c - cube ?l - location)
:precondition (and (at ?l) (has ?c) (not (in ?c ?l)))
:effect (and (not (has ?c)) (in ?c ?l))
)
)
and here's the problem:
(define (problem pb1)
(:domain aperture)
(:requirements :strips :typing)
(:objects h1 - hallway
h2 - hallway
h3 - hallway
r1 - room
c1 - cube)
(:init (at h1)
(connected h1 h2)
(connected h2 h1)
(connected h2 h3)
(connected h3 h2)
(connected h2 r1)
(connected r1 h2)
(in c1 r1)
)
(:goal (and
(has c1)
)
)
)
For this particular problem the set of states for the solution should be:
move(h1,h2)
enter(h2,r1)
pickup(c1,r1)
but, as I've said, the graphplan implementation that I'm using (graphplan) can't find any plan.
I was able to find a solution plan using strips. However, I had to tweak your domain slightly. Specifically, I changed the domain actions "pickup" and "drop" to replace the parameter type "location" with "room". With this change, I was able to find the following solution:
1. move h1 h2
2. enter h2 r1
3. pickup c1 r1
Maybe this could be the reason graphplan was unable to find a solution as well? Here are the modified domain and problem pddl files.
domain.pddl
(define (domain aperture)
(:requirements :strips :typing :negative-preconditions)
(:types
cube
hallway room - location
)
(:action enter
:parameters (?h - hallway ?r - room)
:precondition (and (connected ?h ?r) (connected ?r ?h) (at ?h)
(not (at ?r)))
:effect (and (at ?r) (not (at ?h)))
)
(:action exit
:parameters (?r - room ?h - hallway)
:precondition (and (connected ?r ?h) (connected ?h ?r) (at ?r)
(not (at ?h)))
:effect (and (at ?h) (not (at ?r)))
)
(:action move
:parameters (?h1 - hallway ?h2 - hallway)
:precondition (and (connected ?h1 ?h2) (connected ?h2 ?h1)
(at ?h1) (not (at ?h2)))
:effect (and (at ?h2) (not (at ?h1)))
)
(:action pickup
:parameters (?c - cube ?l - room)
:precondition (and (at ?l) (not (has ?c)) (in ?c ?l))
:effect (and (has ?c) (not (in ?c ?l)))
)
(:action drop
:parameters (?c - cube ?l - room)
:precondition (and (at ?l) (has ?c) (not (in ?c ?l)))
:effect (and (not (has ?c)) (in ?c ?l))
)
)
problem.pddl
(define (problem pb1)
(:domain aperture)
(:objects h1 - hallway
h2 - hallway
h3 - hallway
r1 - room
c1 - cube)
(:init (at h1)
(connected h1 h2)
(connected h2 h1)
(connected h2 h3)
(connected h3 h2)
(connected h2 r1)
(connected r1 h2)
(in c1 r1)
)
(:goal (and
(has c1)
)
)
)