How to accelerate my python looping process for A-star pathfinding? - python-2.7

I try to make an A-star Pathfinding program base on tile-graph (image raster data as graph) where each pixel values represent as cost.. This is my A-star function script so far :
def A_star(h,c,dx,dy,u,s_id,e_id,Op,Cl,Prt,CC,o,ht,w):
Op.append(s_id)
while e_id not in Op :
if Op == [ ] :
break
candidate = { }
for i in Op :
d = {i : CC[i]}
candidate.update(d)
o = min(candidate, key=candidate.get)
Cl.append(o)
Op.remove(o)
adjacent_list = adjacent_cell(o,dx,dy )
for p in adjacent_list :
if p in Cl:
adjacent_list = filter(lambda i: i != p, adjacent_list)
elif p not in Op :
Op.append(p)
d = {p : o }
Prt.update(d)
d = {p : F(p,o,h,u,w,c,dx,e_id,ht,CC)}
CC.update(d)
elif id in Op :
f1 = F(p,o,h,u,w,c,dx,e_id,ht,CC)
f2 = F(p,Prt[p],h,u,w,c,dx,e_id,ht,CC)
if f1 < f2 :
d = {p : o }
Prt.update(d)
d = {id : F(p,o,h,u,w,c,dx,e_id,ht,CC)}
CC.update(d)
return Prt
my sample code and input data can be downloaded here
https://drive.google.com/open?id=0B2zjTfTukbMvaV9BalU4ZGx4MjQ
If i use a small resolution of DEM, 25x29 ( srtm1.tif ), this program goes well. But if i try a large resolution of DEM, for example 1228 x 972 ( dem,asc ). This program took very long time to calculate a whole cell. I guest that the problem is on the looping progress where i try to use loop for iteration (Line 110, A-star function).
while e_id not in Op :
Is there any solution to make my code run faster ?
All kind of help, suggestion, comment, solution will be very appreciate..

some of optimizing will be like this:
def A_star(h,c,dx,dy,u,s_id,e_id,Op,Cl,Prt,CC,o,ht,w):
Op.append(s_id)
continu = e_id not in Op
while continu :
if Op == []:
break
candidate = {i:CC[i] for i in Op } # HERE
o = min(candidate.values()) # HERE
Cl.append(o)
Op.remove(o)
adjacent_list = adjacent_cell(o,dx,dy )
for p in adjacent_list :
if p in Cl:
adjacent_list = filter(lambda i: i != p, adjacent_list)
elif p not in Op :
Op.append(p)
if p==e_id:
continu=False # this will stop while from looping!
Prt[p]=o # HERE
CC[p]=F(p,o,h,u,w,c,dx,e_id,ht,CC) # HERE
elif id in Op :
f1 = F(p,o,h,u,w,c,dx,e_id,ht,CC)
f2 = F(p,Prt[p],h,u,w,c,dx,e_id,ht,CC)
if f1 < f2 :
Prt[p]=o # HERE
CC[id]= F(p,o,h,u,w,c,dx,e_id,ht,CC) # HERE
return Prt
using dict.update is not for setting one item! use dict[key]=value instead.
another help is to check when the p == e_id so if it added to Op the while will stopped!

Related

Dropdown query has no error, but returns no results

I'm hoping to allow others to sort through the data using some dropdowns, but they shouldn't have to use all of them if they don't need to.
My query function:
=QUERY(CATALOG!A2:I259,"SELECT * WHERE 1=1 "&IF(A2="Any",""," AND B = '"&A2&"' ")&IF(B2="ANY",""," AND C = '"&B2&"' ")&IF(C2="Any",""," AND D = '"&C2&"' ")&IF(D2="Any",""," AND E = '"&D2&"' ")&IF(E2="Any",""," AND F = '"&E2&"' ")&IF(F2="Any",""," AND G = '"&F2&"' ")&IF(G2="Any",""," AND H = '"&G2&"' "),1)
Whenever I ran this, there wasn't an error but the query didn't give any items.
I initially only tested one of the dropdowns but received nothing. I plugged in a known product into the inputs and still received nothing.
Link to copy of the spreadsheet with dataset and function
https://docs.google.com/spreadsheets/d/1s3tOm_6g8n66HT9md3EAXY7XwbkpmPggYhxdF-zv5ok/edit?usp=sharing
Some of the search parameters seem to be numbers. In that case do not use the single quotes (as that will turn them into strings). See if this works
=QUERY(CATALOG!A2:I259,"SELECT * WHERE 1=1 "&IF(A2="Any",""," AND B = "&A2&" ")&IF(B2="ANY",""," AND C = '"&B2&"' ")&IF(C2="Any",""," AND D = '"&C2&"' ")&IF(D2="Any",""," AND E = '"&D2&"' ")&IF(E2="Any",""," AND F = "&E2&" ")&IF(F2="Any",""," AND G = "&F2&" ")&IF(G2="Any",""," AND H = '"&G2&"' "),1)
try shorter:
=QUERY(CATALOG!A2:I259,
"where 1=1 "&
IF(A2="Any",," and B = "&A2)&
IF(B2="Any",," and C = '"&B2&"'")&
IF(C2="Any",," and D = '"&C2&"'")&
IF(D2="Any",," and E = '"&D2&"'")&
IF(E2="Any",," and F = "&E2)&
IF(F2="Any",," and G = "&F2)&
IF(G2="Any",," and H = '"&G2&"'"), 1)

How should I initialize my list of tuples

I have a function that takes a list of tuples and process it to obtain a tuple of 3 integers.
I would now like to test it with a list of the tuples type I created but I'm unable to create this list.
Here is my tuple type :
type t_votes = {valeur : string ; nombre : int };;
Here is my function :
let rec recap (l : t_votes list) : int * int * int =
let (nb_oui,nb_non,nb_blanc) = recap(tl(l)) in
if (l=[]) then
(0,0,0)
else if ((hd(l)).valeur = "oui") then
(nb_oui+(hd(l)).nombre ,nb_non,nb_blanc)
else if ((hd(l)).valeur = "non") then
(nb_oui, nb_non + (hd(l)).nombre, nb_blanc)
else if ((hd(l)).valeur = "blanc") then
(nb_oui,nb_non,nb_blanc+(hd(l)).nombre)
else
failwith("liste invalide")
;;
And here is my vain attempt at declaring a list to test my function with :
let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
recap(liste_votes );;
Here is what tuareg gives me :
# let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
Characters 34-45:
let liste_votes : t_votes list = [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)];;
^^^^^^^^^^^
Error: This expression has type 'a * 'b
but an expression was expected of type t_votes
To create a value of a record type (because it is a record type and not a tuple, a tuple doesn't name its arguments), the syntax is the following:
{ valeur = "Some string" ; nombre = 13 }
If this syntax is too heavy for you, a common practice is to write a builder function:
let mk_vote valeur nombre = { valeur ; nombre }
Here I'm using another piece of syntax to instantiate a record value without using the = symbol. In that case, it's the same as writing valeur = valeur and nombre = nombre.
You can then write:
let votes = [ mk_vote "oui" 120 ; mk_vote "non" 18 ; mk_vote "blanc" 20 ; mk_vote "oui" 20 ; mk_vote "non" 24 ; mk_vote "blanc" 25 ]
let mk_vote (valeur, nombre) = { valeur ; nombre }
would work as well and let you write
let votes = List.map mk_vote [("oui",120);("non",18);("blanc",20);("oui",20);("non",24);("blanc",25)]
For some vote of the record type you can access the fields with vote.valeur and vote.nombre.
You can also use pattern-matching:
match vote with
| { valeur = v ; nombre = n } => (* ... *)
You can also make a record value from another one like so:
let vote = { valeur = "Some string" ; nombre = 13 } in
let vote' = { vote with valeur = "Some other string" } in
(* ... *)
Then vote'.valeur is "Some other string" while vote'.nombre is vote.nombre,
or 13 in that case.
Finally I couldn't help but notice you were using strings to represent different kind of votes, since there seem to be only three cases, a dedicated type would be more relevant (you are using ocaml after all which lets you handle data properly).
type vote_kind =
| Yes
| No
| Blank
type t_votes = {
value : vote_kind ;
amount : int ;
}

Computing all values or stopping and returning just the best value if found

I have a list of items and for each item I am computing a value. Computing this value is a bit computationally intensive so I want to minimise it as much as possible.
The algorithm I need to implement is this:
I have a value X
For each item
a. compute the value for it, if it is < 0 ignore it completely
b. if (value > 0) && (value < X)
return pair (item, value)
Return all (item, value) pairs in a List (that have the value > 0), ideally sorted by value
To make it a bit clearer, step 3 only happens if none of the items have a value less than X. In step 2, when we encounter the first item that is less than X we should not compute the rest and just return that item (we can obviously return it in a Set() by itself to match the return type).
The code I have at the moment is as follows:
val itemValMap = items.foldLeft(Map[Item, Int)]()) {
(map : Map[Item, Int], key : Item) =>
val value = computeValue(item)
if ( value >= 0 ) //we filter out negative ones
map + (key -> value)
else
map
}
val bestItem = itemValMap.minBy(_._2)
if (bestItem._2 < bestX)
{
List(bestItem)
}
else
{
itemValMap.toList.sortBy(_._2)
}
However, what this code is doing is computing all the values in the list and choosing the best one, rather than stopping as a 'better' one is found. I suspect I have to use Streams in some way to achieve this?
OK, I'm not sure how your whole setup looks like, but I tried to prepare a minimal example that would mirror your situation.
Here it is then:
object StreamTest {
case class Item(value : Int)
def createItems() = List(Item(0),Item(3),Item(30),Item(8),Item(8),Item(4),Item(54),Item(-1),Item(23),Item(131))
def computeValue(i : Item) = { Thread.sleep(3000); i.value * 2 - 2 }
def process(minValue : Int)(items : Seq[Item]) = {
val stream = Stream(items: _*).map(item => item -> computeValue(item)).filter(tuple => tuple._2 >= 0)
stream.find(tuple => tuple._2 < minValue).map(List(_)).getOrElse(stream.sortBy(_._2).toList)
}
}
Each calculation takes 3 seconds. Now let's see how it works:
val items = StreamTest.createItems()
val result = StreamTest.process(2)(items)
result.foreach(r => println("Original: " + r._1 + " , calculated: " + r._2))
Gives:
[info] Running Main
Original: Item(3) , calculated: 4
Original: Item(4) , calculated: 6
Original: Item(8) , calculated: 14
Original: Item(8) , calculated: 14
Original: Item(23) , calculated: 44
Original: Item(30) , calculated: 58
Original: Item(54) , calculated: 106
Original: Item(131) , calculated: 260
[success] Total time: 31 s, completed 2013-11-21 15:57:54
Since there's no value smaller than 2, we got a list ordered by the calculated value. Notice that two pairs are missing, because calculated values are smaller than 0 and got filtered out.
OK, now let's try with a different minimum cut-off point:
val result = StreamTest.process(5)(items)
Which gives:
[info] Running Main
Original: Item(3) , calculated: 4
[success] Total time: 7 s, completed 2013-11-21 15:55:20
Good, it returned a list with only one item, the first value (second item in the original list) that was smaller than 'minimal' value and was not smaller than 0.
I hope that the example above is easily adaptable to your needs...
A simple way to avoid the computation of unneeded values is to make your collection lazy by using the view method:
val weigthedItems = items.view.map{ i => i -> computeValue(i) }.filter(_._2 >= 0 )
weigthedItems.find(_._2 < X).map(List(_)).getOrElse(weigthedItems.sortBy(_._2))
By example here is a test in the REPL:
scala> :paste
// Entering paste mode (ctrl-D to finish)
type Item = String
def computeValue( item: Item ): Int = {
println("Computing " + item)
item.toInt
}
val items = List[Item]("13", "1", "5", "-7", "12", "3", "-1", "15")
val X = 10
val weigthedItems = items.view.map{ i => i -> computeValue(i) }.filter(_._2 >= 0 )
weigthedItems.find(_._2 < X).map(List(_)).getOrElse(weigthedItems.sortBy(_._2))
// Exiting paste mode, now interpreting.
Computing 13
Computing 1
defined type alias Item
computeValue: (item: Item)Int
items: List[String] = List(13, 1, 5, -7, 12, 3, -1, 15)
X: Int = 10
weigthedItems: scala.collection.SeqView[(String, Int),Seq[_]] = SeqViewM(...)
res27: Seq[(String, Int)] = List((1,1))
As you can see computeValue was only called up to the first value < X (that is, up to 1)

How to print part of a line PART 2

Using Groovy, I wish to grab two parts of a tab-separated line. Take the example line:
one fish two fish red fish blue fish ----(each character tab /t separated)
Suppose I want to print one and then I want to print red fish blue
How can I do this?
Alternatively, suppose I want to print one and then a count of the number of characters (words) following red? Or between two and blue?
A previous question yielded this response for printing everything following a certain part of the line:
c = ~/.*red(.*)/
m = line =~ c
if (m) {
println m[0][1]
}
to yield fish blue fish but I'm not comptetent enough with regex's to modify this appropriately. I've tried a few iterations, inserting /t in there and modifying my capturing expression but I've not figured it out. This is three or four questions in one, any help is appreciated. Thanks!!
def a = [:].withDefault{[]}
def b = [:].withDefault{[]}
def c = 0
def d = 0
def e = 0
def f = 0
seuss = "one\tfish\ttwo\tfish\tred\tfish\tblue\tfish"
a = seuss.split (/\t/)
for (i =0; i<a.size(); i++) {
if (d != 0) {
c = c + 1
}
if ( a[i] == "red") {
d = i
}
}
println a[4] + '\t' + c
for (i =0; i<a.size(); i++) {
if ( a[i] == "blue") {
e = 0
}
if (e != 0) {
f = f + 1
}
if ( a[i] == "two") {
e = i
}
}
println a[0] + '\t' + f

validate integer is some enum class item (C++11)

i have some enum class
enum class Foo { A=1, B=18 , Z=42 };
i want to check if some integer can be converted into a Foo.
What would be the ideal way to do this? this is for runtime check (the integer is not known yet at compile-time)
Obviously i can do this the hard way (write a function bool CheckEnum(Foo); with a big-ass switch returning true for all cases except the default one), but i was hoping a more elegant mechanism that avoided so much writing. MPL or Boost.Preprocessor would be a perfectly acceptable solution, but one of which i sadly know very little about
A solution to this problem is to ditch the enums, and replace it with some arrays which are created using XMACROs.
There is no "ideal" way to do it. All ways are going to have to involve some manual work.
You need to create a data structure that contains all of the acceptable values. Then search that data structure with the runtime value you need. A std::set or std::unordered_set would be adequate for this purpose.
Your main difficulty will be in maintaining that list, as it will need to be updated every time you change your enum class.
Ok i'm a little bit fed up with this issue (some of my enums are nearly 100 items)
so i decided to tackle it with code generation, which might not be everyone's cup of tea, but i've realised that is really no such a big deal.
Basically i went for Python Cog, which allows me to embed python snippets inside comments in my .h and .cpp files and auto-generate code. I use it basically like a really smart, imperative macro system:
i added the following to Test.h
/*[[[cog
#----------- definitions
import cog
def createCategoryConstants( enumVar , bitShift ):
categoryIndex = 0
for cat in enumVar:
cog.outl(' const unsigned int %s_op_mask = (%d << %d); ' %(cat[0] , categoryIndex , bitShift))
categoryIndex += 1
cog.outl('\n\n')
def createMultiCategoryEnum( enumVar , enumTypename ):
cog.outl(' enum class %s { ' % enumTypename )
categoryIndex = 0
for i in enumVar:
itemIndex = 0
catName = 'NotExpected'
remainingCategories = len(enumVar)- categoryIndex - 1
for j in i:
if (itemIndex == 0):
catName = j
itemIndex = 1
continue
enumItemIndex = 0
for enumItem in j:
remainingEnums = len(j) - enumItemIndex - 1
currentLine = ' %s = %s_op_mask | %d ' %(enumItem, catName, enumItemIndex)
if (remainingCategories != 0 or remainingEnums != 0):
currentLine += ' , '
cog.outl(currentLine)
enumItemIndex += 1
itemIndex += 1
cog.outl('') #empty line to separate categories
categoryIndex += 1
cog.outl(' };\n\n')
def createIndexFromEnumFunction( enumVar , enumTypename , functionName ):
cog.outl('uint32_t %s(%s a) { \n switch (a)\n {' % (functionName , enumTypename) )
absoluteIndex = 0
for cat in enumVar:
elemInCat = 0
for i in cat:
if elemInCat != 0:
for enumItem in i:
cog.outl('case %s:' % enumItem)
cog.outl(' return %d; \n' % absoluteIndex)
absoluteIndex += 1
elemInCat += 1
cog.outl(' } \n } \n\n ')
def createMultiEnum( enumVar , enumTypename ):
createCategoryConstants( enumVar , 4)
createMultiCategoryEnum( enumVar , enumTypename )
createIndexFromEnumFunction( enumVar , enumTypename , 'FromOpToIndex' )
#------------- generation
multiEnum =[ ['CatA', ['A1', 'A2' , 'A3_foo']] , ['CatSuper8' , ['Z1_bla' , 'Z10' , 'Z11']] ]
createMultiEnum( multiEnum , 'multiFooEnum')
]]]*/
//[[[end]]]
Then i added cog invocation in my Makefile pre-build step:
.build-pre:
# Add your pre 'build' code here...
python /usr/local/bin/cog.py -I../../../tools/cog/ -r *.h
And the results show up just below:
]]]*/
const unsigned int CatA_op_mask = (0 << 4);
const unsigned int CatSuper8_op_mask = (1 << 4);
enum class multiFooEnum {
A1 = CatA_op_mask | 0 ,
A2 = CatA_op_mask | 1 ,
A3_foo = CatA_op_mask | 2 ,
Z1_bla = CatSuper8_op_mask | 0 ,
Z10 = CatSuper8_op_mask | 1 ,
Z11 = CatSuper8_op_mask | 2
};
uint32_t FromOpToIndex(multiFooEnum a) {
switch (a)
{
case A1:
return 0;
case A2:
return 1;
case A3_foo:
return 2;
case Z1_bla:
return 3;
case Z10:
return 4;
case Z11:
return 5;
}
}
//[[[end]]]
So, now my enum validation is about making sure the code generation (invoked at compile time) is done correctly