How to make this in a nested ifelse statement - if-statement

I am currently working on a project that requires the following: I want the port (a breed) to ask storage locations (another breed) whether they have a certain value. If not, that proceed to ask the next storage location etc. etc. until he finds that location with the correct value. If so, than it should take another action (like building something). I got this now, which seems to work but it is super long and over complicated I think.
to check-pipeline-26
ask storage 26
[ifelse pipeline < 1
[build-pipeline]
[check-pipeline-27]
]
end
to check-pipeline-27
ask storage 27
[ifelse pipeline < 1
[build-pipeline]
[check-pipeline-28]
]
end
to check-pipeline-28
ask storage 28
[ifelse pipeline < 1
[build-pipeline]
[check-pipeline-29]
]
end
to check-pipeline-29
ask storage 29
[ifelse pipeline < 1
[build-pipeline]
[check-pipeline-30]
]
end
Let me know if you have any tips to make this easier or simplified. Thanks in advance!
Max

Here's a recursive solution instead where I pass in the pipeline number as a parameter:
to check-pipeline [n]
if n <= max [who] of storages
ask storage n [ifelse pipeline < 1
[build-pipeline]
[check-pipeline n + 1]
]
end
Note: you probably keep track of your max-who in a variable rather than computing each time.
Alternatively, this may be a better solution where you could just use a for loop and sort the agents by their who to make them go in order:
to check-pipeline
foreach sort-on [who] storages
[astorage -> ask astorage[ if pipeline < 1 [build-pipeline stop]]]
]
end

Related

C++ - condition in -for loop- isn't evaluated as I think it should be

I'm quite new to C++ and I have some kind of problem. I would like to ask if someone could explain to me why the evaluation within the for condition does not work.
This is a part of a program I've written, there is a rpm value which is given by the user and gets assorted to a rpm_case to do some calculations later.
What it SHOULD do:
rpm between 800 up to 1200 ==> rpm_case = 0
rpm between 1200 up to 1800 ==> rpm_case = 1
rpm between 1800 up to 2500 ==> rpm_case = 2
rpm between 2500 to 3500 ==> rpm_case = 3
========================================================================
in the first place I had some 30-line long if-construction for that but I discarded that already and replaced it with the following much shorted and nicer way to write it (this works as expected):
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0;; rpm_case++) {
if (!(rpm > rpm_bases[rpm_case+1])) {break;}
}
but I'm still not happy because I was really trying to get rid of the if with the for loop.
But the for- loop instead always loops over the entire size of the array instead breaking at the considered point.
const float rpm_bases[known_rpm_bases] = {800, 1200, 1800, 2500, 3500};
short rpm_case;
for (rpm_case=0; (!(rpm > rpm_bases[rpm_case+1])); rpm_case++) {}
?? It somehow seems as it is not possible to evaluate a array with the counter-variable within the conditional part of an for-loop??? Or am I just doing something totally wrong I don't want to exclude that option either.
Big Thanks to everyone in advance.
The middle expression of a for statement is the condition that must be true for the loop to repeat. Therefore, it must be the opposite of the condition that must be true for the loop to break.
For this reason, you must negate the expression by removing the ! (NOT) operator, like this:
for (rpm_case=0; rpm > rpm_bases[rpm_case+1]; rpm_case++);
This expression will work for the cases stated in your question. However, if rpm is higher than 3500, it will cause the array rpm_bases to be accessed out of bounds, causing undefined behavior. Therefore, it would be safer to write the loop in the following way:
for ( rpm_case=0; rpm_case < known_rpm_bases; rpm_case++ )
{
if ( rpm <= rpm_bases[rpm_case] ) break;
}
That way, your program will just give you an additional increment of rpm_case if rpm is higher than the highest value, instead of accessing the array out of bounds causing undefinied behavior.
This is effectively just a typo.
The loop condition is for how long the loop does keep running, not to describe when it ends.
Invert it.

binary check for an operation

Suppose a class has n students due to take an exam.
We intend to devise the quickest way to find out if all students have taken the exam.
Since the state is stored in a repository - read and update operation is expensive.
Is this possible through bit shifting/toggling.
If n=5,the initial state is n bytes of 0 - 00000
Each student completing the exam pushes 1 ,starting from right.
00001
00011
00111
......
All bytes composed of 1 indicates closure.
How do we achieve this using bit operations?
Is there a more efficient way to achieve this?
You have all the steps already:
n bits of 0:
status = 0
Each student completing the exam pushes 1 ,starting from right.
status = status << 1 # push previous to left
status = status | 1 # set the lowest bit
All bytes composed of 1 indicates closure.
allOnes = (1<<num_students) -1
closure = (status == allOnes)
Is there a more efficient way to achieve this?
#Alain's comment is correct: The method you describe is just a less memory efficient way of counting from 1 to n. Why not use a simple counter instead?
takers +=1
completed = (takers == num_students)
The storage for this will take lg(n) bits instead of n bits. In either case there will be load/modify/test/store cycle for each taker, so there is no signifcant time savings. The only reason I could think to use the bitfield is if you are concerned that one person may take the test twice and throw off your count.

How to get current time in CP when using Intervals for scheduling

I am trying to schedule tasks in different machines. These machines have dynamique available ressources, for example:
machine 1: max capacity 4 core.
At T=t1 => available CPU = 2 core;
At T=t2 => available CPU = 1 core;
Each interval has a fixed time (Ex: 1 minute).
So in CPLEX, I have a cumulFunction to sum the used ressource in a machine :
cumulFunction cumuls[host in Hosts] =
sum(job in Jobs) pulse(itvs[task][host], requests[task]);
Now the problem is in the constraint:
forall(host in Hosts) {
cumuls[host] <= ftoi(available_res_function[host](**<<Current Period>>**));
}
I can't find a way to get the current period so that I could compare the used ressources to the available in that specefic period.
PS: available_res_function is a stepFunction of the available ressources.
Thank you so much for your help.
What you can do is to add a set of pulse in your cumul function.
For instance, in the sched_cumul function you could change:
cumulFunction workersUsage =
sum(h in Houses, t in TaskNames) pulse(itvs[h][t],1);
into
cumulFunction workersUsage =
sum(h in Houses, t in TaskNames) pulse(itvs[h][t],1)+pulse(1,40,3);
if you want to mention that 3 workers less are available between time 1 and 40.

Learning about multithreading. Tried to make a prime number finder

I'm studying for a uni project and one of the requirements is to include multithreading. I decided to make a prime number finder and - while it works - it's rather slow. My best guess is that this has to do with the amount of threads I'm creating and destroying.
My approach was to take the range of primes that are below N, and distribute these evenly across M threads (where M = number of cores (in my case 8)), however these threads are being created and destroyed every time N increases.
Pseudocode looks like this:
for each core
# new thread
for i in (range / numberOfCores) * currentCore
if !possiblePrimeIsntActuallyPrime
if possiblePrime % i == 0
possiblePrimeIsntActuallyPrime = true
return
else
return
Which does work, but 8 threads being created for every possible prime seems to be slowing the system down.
Any suggestions on how to optimise this further?
Use thread pooling.
Create 8 threads and store them in an array. Feed it new data each time one ends and start it again. This will prevent them from having to be created and destroyed each time.
Also, when calculating your range of numbers to check, only check up to ceil(sqrt(N)) as anything after that is guaranteed to either not go into it or the other corresponding factor has already been checked. i.e. ceil(sqrt(24)) is 5.
Once you check 5 you don't need to check anything else because 6 goes into 24 4 times and 4 has been checked, 8 goes into it 3 times and 3 has been checked, etc.

Parallelizing a nested Python for loop

What type of parallel Python approach would be suited to efficiently spreading the CPU bound workload shown below. Is it feasible to parallelize the section? It looks like there is not much tight coupling between the loop iterations i.e. portions of the loop could be handled in parallel so long as an appropriate communication to reconstruct the store variable is done at the end. I'm currently using Python2.7, but if a strong case could be made that this problem can be easily handled in a newer version, then I will consider migrating the code base.
I have tried to capture the spirit of the computation with the example below. I believe that it has the same connectedness between the loops/variables as my actual code.
nx = 20
ny = 30
myList1 = [0]*100
myList2 = [1]*25
value1 = np.zeros(nx)
value2 = np.zeros(ny)
store = np.zeros(nx,ny,len(myList1),len(myList2))
for i in range(nx):
for j in range(ny):
f = calc(value1[i],value2[j]) #returns a list
for k,data1 in enumerate(myList1):
for p,data2 in enumerate(myList2):
meanval = np.sum(f[:]/data1)*data2
store[i,j,k,p] = meanval
Here are two approaches you can take. What's wise also depends on where the bottleneck is, which is something that can best be measured rather than guessed.
The ideal option would be to leave all low level optimization to Numpy. Right now you have a mix of native Python code and Numpy code. The latter doesn't play well with loops. They work, of course, but by having loops in Python, you force operations to take place sequentially in the order you specified. It's better to give Numpy operations that it can perform on as many elements at once as possible, i.e. matrix transformations. That benefits performance, not only because of automatic (partial) parallelization; even single threads will be able to get more out of the CPU. A highly recommended read to learn more about this is From Python to Numpy.
If you do need to parallelize pure Python code, you have few options but to go with multiple processes. For that, refer to the multiprocessing module. Rearrange the code into three steps:
Preparing the inputs for every job
Dividing those jobs between a pool of workers to be run in parallel (fork/map)
Collecting the results (join/reduce)
You need to strike a balance between enough processes to make parallelizing worthwhile, and not so many that they will be too short-lived. The cost of spinning up processes and communicating with them would then become significant by itself.
A simple solution would be to generate a list of (i,j) pairs, so that there will nx*ny jobs. Then make a function that takes such pair as input and returns a list of (i,j,k,p,meanval). Try to only use the inputs to the function and return a result. Everything local; no side effects et cetera. Read-only access to globals such as myList1 is okay, but modification requires special measures as described in the documentation. Pass the function and the list of inputs to a worker pool. Once it has finished producing partial results, combine all those into your store.
Here's an example:
from multiprocessing import Pool
import numpy as np
# Global variables are OK, as long as their contents are not modified, although
# these might just as well be moved into the worker function or an initializer
nx = 20
ny = 30
myList1 = [0]*100
myList2 = [1]*25
value1 = np.zeros(nx)
value2 = np.zeros(ny)
def calc_meanvals_for(pair):
"""Process a reasonably sized chunk of the problem"""
i, j = pair
f = calc(value1[i], value2[j])
results = []
for k, data1 in enumerate(myList1):
for p, data2 in enumerate(myList2):
meanval = np.sum(f[:]/data1)*data2
results.append((i,j,k,p,meanval))
return results
# This module will be imported by every worker - that's how they will be able
# to find the global variables and the calc function - so make sure to check
# if this the main program, because without that, every worker will start more
# workers, each of which will start even more, and so on, in an endless loop
if __name__ == '__main__':
# Create a pool of worker processes, each able to use a CPU core
pool = Pool()
# Prepare the arguments, one per function invocation (tuples to fake multiple)
arg_pairs = [(i,j) for i in range(nx) for j in range(ny)]
# Now comes the parallel step: given a function and a list of arguments,
# have a worker invoke that function with one argument until all arguments
# have been used, collecting the return values in a list
return_values = pool.map(calc_meanvals_for, arg_pairs)
# Since the function also returns a list, there's now a list of lists - consider
# itertools.chain.from_iterable to flatten them - to be processed further
store = np.zeros(nx, ny, len(myList1), len(myList2))
for results in return_values:
for i, j, k, p, meanval in results:
store[i,j,k,p] = meanval