Solve "Out of local stack" in this specific constraint programming in prolog - variables

I'm currently trying to create schedules for bus drivers in prolog. I wish to find a limited number of solutions. But I get the "Out of local stack" error, and I suppose it is because I'm getting too many solutions.
How can I prevent that error given the following code? Any tips on whatever I'm not doing correctly would help immensely too.
count_drivers: counts the number of drivers with D_id as driver_id
( I need them to work less than "max_hours").
vehicle: represents the bus and respective routes.
connected: represents the connection between the relief opportunities
( a route consists of a group of relief points and the respective "connection"
between them)
workpiece: is a segment of work in the same vehicle between two relief points
spell: is a group of workpieces done by the same driver
spreadover: is the whole shift one driver has to do.
Here is the code:
?- use_module(library(clpfd)).
?- use_module(library(lists)).
?- use_module(library(aggregate)).
%workpiece(Bus,[Ro1,Ro2],Weight).
workpiece(1,[1,2],1).
workpiece(1,[2,3],2).
workpiece(1,[3,4],1).
workpiece(1,[4,5],2).
workpiece(1,[5,6],1).
workpiece(2,[7,8],2).
workpiece(2,[8,9],2).
workpiece(2,[9,10],1).
workpiece(2,[10,11],2).
workpiece(2,[11,12],1).
workpiece(3,[13,14],2).
workpiece(3,[14,15],1).
workpiece(3,[15,16],2).
workpiece(3,[16,17],1).
workpiece(3,[17,18],2).
%spell
spell(Vehicle,[[Ro1,Ro2]|Tail]):-Vars = [Ro1,Ro2], Vars in 1..18, workpiece(Vehicle,[Ro1,Ro2],_),spell(Vehicle,Tail,Ro2),labeling([],Vars).
spell(_,[],_).
spell(Vehicle,[[Ro1,Ro2]|Tail],Ro3):- Vars = [Ro3], Vars in 1..18, Ro3 #= Ro1, workpiece(Vehicle,[Ro1,Ro2],_),spell(Vehicle,Tail,Ro2), labeling([],Vars).
%spreadover de cada driver
spreadover(_,List):- Vars = I, Vars in 1..15, length(List,I), I #>= 1.
spreadover(Driver,[Head|Tail]):- Vars = [Vehicle,I], Vars in 1..9, Vehicle #>= 1, Vehicle #=< 3, spell(Vehicle,Head), length(Head,I), I #>= 1, spreadover(Driver,Tail), labeling([],Vars).
%ocupar as workpieces todas
%minimizando os shifts
%cobrir todas as routes
%length 15
%drivershifts
drivershifts(_,List):- Vars = I, Vars in 1..15, length(List,I), I #= 15.
drivershifts(NumDrivers,[[Driver|List]|Tail]):-Vars = Driver, Vars in 1..NumDrivers, Driver #>= 1, Driver #=< NumDrivers, spreadover(Driver,List), labeling([],Vars).
I thank you all in advance for any time you can spare in helping me.
EDIT: I changed the code around a bit, now I get a load of unassigned variables from a query of
forall(spreadover(1,List),writeln(List)).
or one unassigned variable from
spreadover(1,List).
I restricted the domains wherever I could, but aren't sure if I'm doing this correctly.
From the queries above I should generate spreadovers(a set of spells) for driver 1.
Not sure if I should post a new question or rewrite this one either, so decided to rewrite this one.

You have many warnings from Singleton variables, and would be good style to solve them.
At least, prefix variables you know are unused with an underscore, to avoid the warning.
Now to the loop: you're calling diagram with a free variable, causing an infinite recursion that 'construct' an infinite list of partially instantiated variables.
I can't understand what could be the intended meaning of diagram/1. For sure, you miss the base case: add something like
diagram([]).

Related

BAPI_GOODSMVT_CREATE with multiple material numbers and same PP order?

As I know of, When you're using BAPI_GOODSMVT_CREATE at the same time(by loop or just coincidence), Using same material number puts you an error about locked object (Material XXXX is locked by USER YYYY).
But, as i know of, using BAPI_GOODSMVT_CREATE at the same time, but different material number WITH same production order makes no error.
Issue
Recently I found an error about M3/897 (Plant Data of Material XXXX is locked by user XXXX) when I'm doing BAPI_GOODSMVT_CREATE when I'm trying GI for Production order, by parallel processing, which are putting different Material number to same production order.
Question
So, I'm asking about constraint of BAPI_GOODSMVT_CREATE.
So far I know is -
A. You can't issue GI for Production Order(Mvt 261) at the same time, when you're putting same material number for different production order.
B. (I'm not sure about this) You can't issue GI for Production Order(Mvt 261) at the same time, when you're putting different material number for same production order.
Is both is right, or just A is right? Any help from experienced ABAPer or MM consultant would be appreciated!
To post GI in a loop you need to make commit after each run, and unlock the object explicitly, otherwise you will get the PP lock.
Try like this:
LOOP AT lt_orders ASSIGNING <fs>.
...
CALL FUNCTION 'BAPI_GOODSMVT_CREATE'
EXPORTING
goodsmvt_header = ls_header
goodsmvt_code = ls_code
IMPORTING
goodsmvt_headret = ls_headret
materialdocument = ls_retmtd
TABLES
goodsmvt_item = lt_item
return = lt_return.
IF line_exists( lt_return[ type = 'E' ] ).
CALL FUNCTION 'BAPI_TRANSACTION_ROLLBACK'.
ELSE.
COMMIT WORK AND WAIT.
CALL FUNCTION 'DEQUEUE_ALL'.
ENDIF.
ENDLOOP.
Always use BAPI_TRANSACTION_COMMIT with WAIT parameter or COMMIT WORK with the same after each BAPI call.
Also there can be tricky issues with the GR and implicit GI movements, see the note 369518 about this.
You can check the presence of existing lock at runtime using this FM - "ENQUE_READ2".
data: RAW_ENQ like LOCKSEDX_ENQ_TAB,
SUBRC type SY-SUBRC,
NUMBER type I.
clear : RAW_ENQ[], SUBRC, NUMBER.
add 1 to COUNTER.
call function 'ENQUE_READ2'
importing
SUBRC = SUBRC
NUMBER = NUMBER
tables
ENQ = RAW_ENQ.
But if you have to prevent a failure of GOODS mvt. in general you have instead to implement some reprocessing logic to store errors.
The steps would be : Catch errors --> store bapi information or header doc number --> retry later

Optaplanner:Add Dynamic visits without changing the already created visits

I am saving the best solution into the DB, and we display that on the web page. I am looking for some solution where a user can add more visits, but that should not change already published trips.
I have checked the documentation and found ProblemFactChange can be used, but only when the solver is already running.
In my case solver is already terminated and the solution is also published. Now I want to add more visits to the vehicle without modifying the existing visits of the Vehicle. Is this possible with Optaplanner? if yes any example of documentation would be very helpful.
You can use PlanningPin annotation for avoiding unwanted changes.
Optaplanner - Pinned planning entities
If you're not looking for pinning (see Ismail's excellent answer), take a look at the OptaPlanner School Timetabling example, which allows adding lessons between solver runs. The lessons simply get stored in the database and then get loaded when the solver starts.
The difficulty with VRP is the chained model complexity (we're working on an alternative): If you add a visit X between A and B, then make sure that afterwards A.next = X, B.previous = X, X.previous = A, X.next = B and X.vehicle = A.vehicle. Not the mention the arrival times etc.
My suggestion would be to resolve what is left after the changes have been introduced. Let's say you are you visited half of your destinations (A -> B -> C) but not yet (C - > D -> E) when two new possible destinations (D' and E') are introduced. Would not this be the same thing as you are starting in C and trying plan for D, D', E and E'? The solution needs to be updated on the progress though so the remainder + changes can be input to the next solution.
Just my two cent.

Understanding PsychoPy codes for trialHandler and responses

I am new to coding, and would like help in understanding the script used by the PsychoPy program.
To be more specific, I would like to understand the codes that are in line 6 to 15. I am aware that this is used to manage the multiple trials, but I am hoping someone can help me clarify those bits? I also noted that removing the codes from line 6-8 doesn't change the experiment, but removing the codes from line 10-15 essentially stop the experiment from running.
trialsAll = data.TrialHandler(trialList=data.importConditions('trialType.xlsx'), nReps=10, method='random', name='trialsAll', dataTypes='corr')
thisExp = data.ExperimentHandler(name='Ours')
thisExp.addLoop(trialsAll) #adds a loop to the experiment
thisTrial = trialsAll.trialList[0]
if thisTrial != None:
for paramName in thisTrial.keys():
exec(paramName + '= thisTrial.' + paramName)
# Loop through trials
for thisTrial in trialsAll:
currentLoop=trialsAll
if thisTrial != None:
for paramName in thisTrial.keys():
exec(paramName + '=thisTrial.' + paramName)
My second question would be about getting responses. Is there a reason that thisResp is equalled to None?
#get response
thisResp=None
while thisResp==None:
allKeys=event.waitKeys()
Thanks a lot for any help. I appreciate it.
Regards,
Cash
if thisTrial != None:
for paramName in thisTrial.keys():
exec(paramName + '= thisTrial.' + paramName)
This code allows the use of abbreviations. For example, say your conditions file has a field called 'angle', you can refer to this directly rather than via the keys of that trial's dictionary (e.g. thisTrial['angle'] ) or using dot notation ( thisTrial.angle ). i.e., in this example:
angle = thisTrial.angle
for thisTrial in trialsAll:
is fundamental to running a psychoPy trial loop. It will cycle though each trial that is contained in the TrialHandler object that is created to manage trials, connected to a given conditions file.
#get response
thisResp=None
while thisResp==None:
allKeys=event.waitKeys()
The line 'while thisResp==None:' requires that the variable 'thisResp' actually exists if we are going to be able to check its value. So in the immediately preceding line, it is created and given an initial null value so that the next line will run OK. Note that at this stage, it is just an arbitrary variable, which doesn't have any actual connection to the subject's response. That will presumably occur later in the code, when it gets assigned a value other than None.

Neo4j: "ghost" node in label index throws error

I have a neo4j database with a set of nodes with label :EXAMPLE.
There are two operations. First I delete one node and then I look for another one. They are done separately using neo4j API.
MATCH (n:EXAMPLE {Name: { name1 }}) DELETE n;
and
MATCH (n:EXAMPLE {Name: { name2 }}) RETURN n;
Sometimes, when I execute second query, it throws an error "Node with id 123". Node with id 123 is the same node that was deleted in the first query.
It happens when there is a lot of requests are coming to the database simultaneously.
I guess that it could happen if node was deleted, but EXAMPLE label index wasn't updated yet. There are two facts that prove such theory.
1) The error is unstable.
2) If I change second query like this (remove the label), I won't get the error:
MATCH (n {Name: { name2 }}) RETURN n;
Neo4j version is 2.1.5, Java - OpenJDK Runtime Environment (IcedTea 2.5.3) (7u71-2.5.3-2~deb7u1) and operation system is Debian. There are no other indexes in the database except the label.
The question is how can I fix this, but still use labels?
What ends up happening is that (simplified) the operations will order like so:
Q1: MATCH (n)
Q2: DELETE (n), COMMIT
Q1: RETURN n # Error, n no longer exists
For implementation reasons, this is much more likely to happen if cypher is going via an index. The database will eventually handle this for you, but for now, you'll need to wrap that read query in a retry block - if it fails with this type of error, you simply run it again.
On that note, there are other errors that are easily recoverable from by retrying, such as deadlock errors, so wrapping your statements and/or transactions in retry-blocks is a useful thing to do in general.
This is a possible workaround:
Mark nodes as deleted instead of deleting. Ignore nodes that are marked as deleted. Delete all such nodes at once with a garbage collector.

orientdb sql update edge?

I have been messing around with orientdb sql, and I was wondering if there is a way to update an edge of a vertex, together with some data on it.
assuming I have the following data:
Vertex: Person, Room
Edge: Inside (from Person to Room)
something like:
UPDATE Persons SET phone=000000, out_Inside=(
select #rid from Rooms where room_id=5) where person_id=8
obviously, the above does not work. It throws exception:
Error: java.lang.ClassCastException: com.orientechnologies.orient.core.id.ORecordId cannot be cast to com.orientechnologies.orient.core.db.record.ridbag.ORidBag
I tried to look at the sources at github searching for a syntax for bag with 1 item,
but couldn't find any (found %, but that seems to be for serialization no for SQL).
(1) Is there any way to do that then? how do I update a connection? Is there even a way, or am I forced to create a new edge, and delete the old one?
(2) When writing this, it came to my mind that perhaps edges are not the way to go in this case. Perhaps I should use a LINK instead. I have to say i'm not sure when to use which, or what are the implications involved in using any of them. I did found this though:
https://groups.google.com/forum/#!topic/orient-database/xXlNNXHI1UE
comment 3 from the top, of Lvc#, where he says:
"The suggested way is to always create an edge for relationships"
Also, even if I should use a link, please respond to (1). I would be happy to know the answer anyway.
p.s.
In my scenario, a person can only be at one room. This will most likely not change in the future. Obviously, the edge has the advantage that in case I might want to change it (however improbable that may be), it will be very easy.
Solution (partial)
(1) The solution was simply to remove the field selection. Thanks for Lvca for pointing it out!
(2) --Still not sure--
CREATE EDGE and DELETE EDGE commands have this goal: avoid the user to fight with underlying structure.
However if you want to do it (a little "dirty"), try this one:
UPDATE Persons SET phone=000000, out_Inside=(
select from Rooms where room_id=5) where person_id=8
update EDGE Custom_Family_Of_Custom
set survey_status = '%s',
apply_source = '%s'
where #rid in (
select level1_e.#rid from (
MATCH {class: Custom, as: custom, where: (custom_uuid = '%s')}.bothE('Custom_Family_Of_Custom') {as: level1_e} .bothV('Custom') {as: level1_v, where: (custom_uuid = '%s')} return level1_e
)
)
it works well