The delay1 can only contain agent.paint. On the exit of the delay1, a new agent gets released from the delay.
But the released agent is not an agent.paint instead it is an agent.repair or agent.bwork.
The delay2, delay4, and delay7 can contain agent.repair and agent.bwork but these delays are full, so now the agent is a problem, which is not supposed to happen.
Problem:
In delay1 only agent.paint can go, after getting free from delay and In delay2, delay4 or delay7 only agent.repair or agent.bwork can go, if delay have them.
And that is not happening in the existing model.
I try to explain in the image below:
My existing approach which is no working.
There are several things that are incorrect in your model. First of all, please keep in mind that when you use the word agent in a flowchart block, it always refers to the agent contained in the current flowchart block from where you are calling it.
I assume, in the "on exit" function of delay1 you want to release an agent from delay which has a parameter paint == true. However, you wrote the function as
if (delay.size() > 0 && agent.paint == true) delay.stopDelay(delay.get(0));
The second condition agent.paint == true refers to the current agent in delay1 flowchart block and not the agent in the delay that you want to release. Additionally, you are calling stopDelay() for the agent at position 0 in the delay block, regardless of whether this agent is the correct agent.
Instead, you need to iterate over all agents contained in the delay flowchart block, find the agent that meets your condition and release this specific agent. Your code can look like this:
if (delay.size() > 0) {
Agent agentToRelease = null;
for (int i = 0; i++; i < delay.size() {
if (delay.get(i).paint == true) { // Note: The function delay.get(i) is very slow. See if you can use Collection instead.
agentToRelease = delay.get(i);
break;
}
}
if (agentToRelease != null) {
delay.stopDelay(agentToRelease);
}
}
The same goes for delay2, delay4 and delay7.
The "on enter" function of delay is always called by the agent that is currently entering the delay. Because you check the condition for this specific agent here, you can directly call stopDelay() for this agent in case the condition returns true. So the first part of your code should look like this (the same goes for the remaining conditions)
if (agent.paint == true && delay1.size() + moveTo.size() < 2) {
delay.stopDelay(agent);
} else if (...)
in delay you are using stopDelay with an agent without caring for the value of its 3 parameters.
So it's perfectly possible to release an agent that is NOT paint when delay1 is empty... and this agent will go to any of the other 3 delays... no reason why not to.
Besides this.. you have moveTo blocks that mess up your condition... so if an agent is in moveTo4 and delay2 is empty, it will go to delay 2 anyways... because why not? You don't have any restriction for that to happen
You are overcomplicating an extremely simple problem
Related
Using a selectOutput I'm facing a problem (I think it's a malfunction).
The condition is as follows:
main.controlLot[agent.orderID][workcenterID]==
main.alreadyEntered[agent.orderID][workcenterID] ||
agent.numberProductsInPallet ==
((int) selectFrom(routings)
.where(routings.work_center.eq(Name))
.where(routings.component_id.eq(agent.component))
.firstResult(routings.palletization))
On enter I'm checking self.condition(agent) and when it is verified by the first segment of the condition (main.controlLot[agent.orderID][workcenterID]==main.alreadyEntered[agent.orderID][workcenterID]) it does not go through the True port. However, self.condition(agent) returns True.
I placed the following code on exit (False) to confirm if the condition could change mid logic:
traceln(main.controlLot[agent.orderID][workcenterID] + " " + main.alreadyEntered[agent.orderID][workcenterID]);
traceln(agent.numberProductsInPallet);
traceln(self.condition(agent));
and the traceln(self.condition(agent) prints true. I don't understand why would it evaluate the condition as true but send the agent through the false port.
it might be related to the type of system you use.
if you use the "pull" protocol (see: http://www.anylogic.com/blog?page=post&id=157) the agent will look ahead and evaluate the selectoutput, before it enters it. Since the time spent in the selectoutput object is 0, it has to do that.
if the condition changes after it has evaluated the selectoutput function, it will still choose the false path even though it's true.
to fix it, depending on your code, you could use a queue object. This will give the agent 1 additional timestep to relax the parameters and evaluate the condition correctly
So I have this code and it is inside a while(MainMenu) and what i want to learn is how to restart my code.. Sometimes using MainMenu=false; and then MainMenu=true; works but sometimes it doesnt causing me to use return to crash the program because the user can cheat...
if(CitizenLoveNum<=20){
JOptionPane.showMessageDialog(null, "Your citizen are protesting against you! You need to stop them now before something really bad happens", "Citizens on Strike!", JOptionPane.WARNING_MESSAGE);
String Strike=JOptionPane.showInputDialog("Choose 1 of the options below! \n 1.Pay Them (-1000$) \n 2.Send Army (With this move you can lose from 0 to 5 men!)", "Citizens on Strike!");
if(Strike.equals("1")){
if(MoneyCount<=0){
JOptionPane.showMessageDialog(null, "Out Of Money! Try again later..", "No Money Left", JOptionPane.WARNING_MESSAGE);
return;
}
JOptionPane.showMessageDialog(null,"The Citizen's are calm once more. But try buying them recources so that won't happen again!", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
MoneyCount-=1000;
MainMenu=false;
MainMenu=true;
}else{
Random Army= new Random();
int ArmyNum = Army.nextInt(5 - 0) + 0;
JOptionPane.showMessageDialog(null,"You have sent the army. You lost "+ArmyNum+" Soldiers.", "Citizens on Strike!",JOptionPane.INFORMATION_MESSAGE);
SoldierCount1-=ArmyNum;
MainMenu=false;
MainMenu=true;
}
}
It works where i putted the MainMenu=false; MainMenu=true; but it doesnt where i used return; i had to put return; because MainMenu=false; MainMenu=true; was not working. Thank you for your time :)
Edit: it usually does not work when I use an if inside an if... hope that helps
From what I can interpret, you probably have some code like this:
while(true) {
// A: Do stuff here
while(MainMenu) {
// B: Stuff before your posted code
if(CitizenLoveNum<=20){
// C: Your posted code
}
}
// D: Do other stuff here
}
If you want to go to B, use continue;.
If you want to go to D, use break;.
If you need to go to A without touching D, then enclose D in an if statement.
If your program is ending when you use continue, you probably are missing the while(true) at the top. This part is necessary to keep your code running unconditionally, forever. Otherwise, upon exiting while (MainMenu), your program will run to completion.
Also, I would like to add that
MainMenu = false;
MainMenu = true;
Is equivalent to
MainMenu = true;
Your code executes sequentially. Once you are inside the while loop, MainMenu is not checked again until you encounter a continue or all the code inside the loop finishes executing.
If you want to return to the top of the while body, you can use the keyword
continue;
Changing the MainMenu value in the while body will not cause any action becuase it gets checked before every new loop, the continue keyword will be applied immediately.
This:
MainMenu=false;
MainMenu=true;
Is the same as this:
MainMenu=true;
You're assigning a value that will be checked when it gets back to the start of the loop. If the value is true at that point, it will continue. So if you want to continue looping, set it to true. If you want to stop, just set it to false. Do one or the other, not both. Note that MainMenu=false will continue executing the current loop, and (unless it later gets set to true) will stop it from looping again.
What the return statement does is exits the function that your while loop is enclosed in entirely. If you had cleanup code after the end of your loop, you wouldn't want to return, as that would skip it.
If you want to execute more code after the loop (not exit the function yet), but you want to immediately exit the loop without finishing the current iteration, you can use the break statement.
If you want to return to the start of your loop immediately (from anywhere in the loop) and continue executing it, use the continue statement. Whether the loop executes again will depend on the value of MainMenu.
I am wondering how to reach a compromise between fast-cancel-responsiveness and performance with my threads which body look similar to this loop:
for(int i=0; i<HUGE_NUMBER; ++i) {
//some easy computation like adding numbers
//which are result of previous iteration of this loop
}
If a computation in loop body is quite easy then adding simple check-reaction to each iteration:
if (Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Cancelled");
}
may slow down execution of the code.
Even if I change the above condition to:
if (i % 100 && Thread.currentThread().isInterrupted()) {
throw new InterruptedException("Cancelled");
}
Then compilator cannot just precompute values of i and check condition only in some specific situations since HUGE_NUMBER is variable and can have different values.
So I'd like to ask if there's any smart way of adding such check to a presented code knowing that:
HUGE_NUMBER is variable and can have different values
loop body consists of some easy-to-compute, but relying on prevoius computations code.
What I want to say is that one iteration of a loop is quite fast, but HUGE_NUMBER of iterations can take a little more time and this is what I want to avoid.
First of all, use Thread.interrupted() instead of Thread.currentThread().isInterrupted() in that case.
You should think about if checking the interruption flag really slows down your calculation too much! One the one hand, if the loop body is VERY simple, even a huge number of iterations (the upper limit is Integer.MAX_VALUE) will run in a few seconds. Even when checking the interruption flag will result in an overhead of 20 or 30%, this will not add very much to the total runtime of your algorithm.
On the other hand, if the loop body is not that simple and so it will run longer, testing the interruption flag will not be a remarkable overhead I think.
Don't do tricks like if (i % 10000 == 0), as this will slow down calculation much more than a 'short' Thread.interrupted().
There is one small trick that you could use - but think twice because it makes your code more complex and less readable:
Whenever you have a loop like that:
for (int i = 0; i < max; i++) {
// loop-body using i
}
you can split up the total range of i into several intervals of size INTERVAL_SIZE:
int start = 0;
while (start < max) {
final int next = Math.min(start + INTERVAL_SIZE, max);
for(int i = start; i < next; i++) {
// loop-body using i
}
start = next;
}
Now you can add your interruption check right before or after the inner loop!
I've done some tests on my system (JDK 7) using the following loop-body
if (i % 2 == 0) x++;
and Integer.MAX_VALUE / 2 iterations. The results are as follows (after warm-up):
Simple loop without any interruption checks: 1,949 ms
Simple loop with check per iteration: 2,219 ms (+14%)
Simple loop with check per 1 million-th iteration using modulo: 3,166 ms (+62%)
Simple loop with check per 1 million-th iteration using bit-mask: 2,653 ms (+36%)
Interval-loop as described above with check in outer loop: 1,972 ms (+1.1%)
So even if the loop-body is as simple as above, the overhead for a per-iteration check is only 14%! So it's recommended to not do any tricks but simply check the interruption flag via Thread.interrupted() in every iteration!
Make your calculation an Iterator.
Although this does not sound terribly useful the benefit here is that you can then quite easily write filter iterators that can be surprisingly flexible. They can be added and removed simply - even through configuration if you wish. There are a number of benefits - try it.
You can then add a filtering Iterator that watches the time and checks for interrupt on a regular basis - or something even more flexible.
You can even add further filtering without compromising the original calculation by interspersing it with brittle status checks.
This is the context of my program.
A function has 50% chance to do nothing, 50% to call itself twice.
What is the probability that the program will finish?
I wrote this piece of code, and it works great apparently. The answer which may not be obvious to everyone is that this program has 100% chance to finish. But there is a StackOverflowError (how convenient ;) ) when I run this program, occuring in Math.Random(). Could someone point to me where does it come from, and tell me if maybe my code is wrong?
static int bestDepth =0;
static int numberOfPrograms =0;
#Test
public void testProba(){
for(int i = 0; i <1000; i++){
long time = System.currentTimeMillis();
bestDepth = 0;
numberOfPrograms = 0;
loop(0);
LOGGER.info("Best depth:"+ bestDepth +" in "+(System.currentTimeMillis()-time)+"ms");
}
}
public boolean loop(int depth){
numberOfPrograms++;
if(depth> bestDepth){
bestDepth = depth;
}
if(proba()){
return true;
}
else{
return loop(depth + 1) && loop(depth + 1);
}
}
public boolean proba(){
return Math.random()>0.5;
}
.
java.lang.StackOverflowError
at java.util.Random.nextDouble(Random.java:394)
at java.lang.Math.random(Math.java:695)
.
I suspect the stack and the amount of function in it is limited, but I don't really see the problem here.
Any advice or clue are obviously welcome.
Fabien
EDIT: Thanks for your answers, I ran it with java -Xss4m and it worked great.
Whenever a function is called or a non-static variable is created, the stack is used to place and reserve space for it.
Now, it seems that you are recursively calling the loop function. This places the arguments in the stack, along with the code segment and the return address. This means that a lot of information is being placed on the stack.
However, the stack is limited. The CPU has built-in mechanics that protect against issues where data is pushed into the stack, and eventually override the code itself (as the stack grows down). This is called a General Protection Fault. When that general protection fault happens, the OS notifies the currently running task. Thus, originating the Stackoverflow.
This seems to be happening in Math.random().
In order to handle your problem, I suggest you to increase the stack size using the -Xss option of Java.
As you said, the loop function recursively calls itself. Now, tail recursive calls can be rewritten to loops by the compiler, and not occupy any stack space (this is called the tail call optimization, TCO). Unfortunately, java compiler does not do that. And also your loop is not tail-recursive. Your options here are:
Increase the stack size, as suggested by the other answers. Note that this will just defer the problem further in time: no matter how large your stack is, its size is still finite. You just need a longer chain of recursive calls to break out of the space limit.
Rewrite the function in terms of loops
Use a language, which has a compiler that performs TCO
You will still need to rewrite the function to be tail-recursive
Or rewrite it with trampolines (only minor changes are needed). A good paper, explaining trampolines and generalizing them further is called "Stackless Scala with Free Monads".
To illustrate the point in 3.2, here's how the rewritten function would look like:
def loop(depth: Int): Trampoline[Boolean] = {
numberOfPrograms = numberOfPrograms + 1
if(depth > bestDepth) {
bestDepth = depth
}
if(proba()) done(true)
else for {
r1 <- loop(depth + 1)
r2 <- loop(depth + 1)
} yield r1 && r2
}
And initial call would be loop(0).run.
Increasing the stack-size is a nice temporary fix. However, as proved by this post, though the loop() function is guaranteed to return eventually, the average stack-depth required by loop() is infinite. Thus, no matter how much you increase the stack by, your program will eventually run out of memory and crash.
There is nothing we can do to prevent this for certain; we always need to encode the stack in memory somehow, and we'll never have infinite memory. However, there is a way to reduce the amount of memory you're using by about 2 orders of magnitude. This should give your program a significantly higher chance of returning, rather than crashing.
We can do this by noticing that, at each layer in the stack, there's really only one piece of information we need to run your program: the piece that tells us if we need to call loop() again or not after returning. Thus, we can emulate the recursion using a stack of bits. Each emulated stack-frame will require only one bit of memory (right now it requires 64-96 times that, depending on whether you're running in 32- or 64-bit).
The code would look something like this (though I don't have a Java compiler right now so I can't test it):
static int bestDepth = 0;
static int numLoopCalls = 0;
public void emulateLoop() {
//Our fake stack. We'll push a 1 when this point on the stack needs a second call to loop() made yet, a 0 if it doesn't
BitSet fakeStack = new BitSet();
long currentDepth = 0;
numLoopCalls = 0;
while(currentDepth >= 0)
{
numLoopCalls++;
if(proba()) {
//"return" from the current function, going up the callstack until we hit a point that we need to "call loop()"" a second time
fakeStack.clear(currentDepth);
while(!fakeStack.get(currentDepth))
{
currentDepth--;
if(currentDepth < 0)
{
return;
}
}
//At this point, we've hit a point where loop() needs to be called a second time.
//Mark it as called, and call it
fakeStack.clear(currentDepth);
currentDepth++;
}
else {
//Need to call loop() twice, so we push a 1 and continue the while-loop
fakeStack.set(currentDepth);
currentDepth++;
if(currentDepth > bestDepth)
{
bestDepth = currentDepth;
}
}
}
}
This will probably be slightly slower, but it will use about 1/100th the memory. Note that the BitSet is stored on the heap, so there is no longer any need to increase the stack-size to run this. If anything, you'll want to increase the heap-size.
The downside of recursion is that it starts filling up your stack which will eventually cause a stack overflow if your recursion is too deep. If you want to ensure that the test ends you can increase your stack size using the answers given in the follow Stackoverflow thread:
How to increase to Java stack size?
Is there a way to pause a for loop in java? So is there a way to only go forward one iteration when prompted? I read this http://answers.yahoo.com/question/index?qid=20100212201605AAazS73 and the solution seems like it could have some problems mostly because I don't fully understand the order the for loop checks its header. The only method I could think of that could accomplish something similar is the following
do {
if (FLAG) {
//Do procedure
i++;
FLAG = false;
}
} while ( i < 6);
When the flag is true the procedure is done and the counter moves forward one. I don't like this, though, because it will keep looping as long as the counter is below 6, if I am not mistaken. Any ideas?
-Sorry for the lack of clarity. The FLAG in my case would be a static boolean that could be called from another class. The procedure I allude to is dependent on i.
When iterating through a for loop, for example, the one below, it does the following
for (int i = 0; i < 6; i++) {
// Do stuff
}
It declares the variable i and assigns a value of 0.
It checks the conditional i < 6. If true, then proceed to step 3. Otherwise go to step 6.
Goes through the body of the loop.
Increment the variable i due to the i++ in the for loop header.
Go to step 2.
The loop ends.
As for your objective, I'm not sure what your objective is. Are you looking to pause using a blocking method call? If so, then something like this would work:
for (int i = 0; i < 6; i++) {
System.in.readLine();
}
Alternatively, you could use some sort of flag that polls to check whether the loop should proceed, such as:
for (int i = 0; i < 6; i++) {
while (paused) {
// An infinite loop that keeps on going until the pause flag is set to false
}
}
Hope this helped.
It's not clear what sort of "prompt" you mean. You could certainly do something like:
for (int i = 0; i < 6; i++) {
System.out.println("Press return to continue...");
System.in.readLine();
// Do the body of the loop
}
That's appropriate for a console app, but obviously not for (say) a Swing app. It also doesn't address the FLAG part of your sample code, because it's not clear what that's meant to mean. Are you trying to prompt the user for more information, or just confirmation to continue? If you could clarify what you're trying to achieve, that would really help.
For the sake of testability, if this is for non-throwaway code you may want to extract the idea of a user prompt, so you can test with an implementation which doesn't actually prompt the user, but just records that it would have done so.
This would involve blocking the Thread that the for loop occupies.
You can do this simply, but not very well, with this:
for(something)
while(!FLAG)
//Do procedure
Another way would be to have another Thread going on, and have the main thread wait for that other thread.
Here's some more information: How to make a Java thread wait for another thread's output?
Your goal is somewhat unclear. I think you want your program to keep running until you get six of a certain input and if so, that approach will work, though of course you'll need to get input from the user to move the loop forward.
If your concern is that the while loop would use a lot of system resources, that will not be a problem.
Well, you could use Thread.Sleep(); to pause for a little bit between flag checks, but what you are really looking for is a function that blocks while waiting for input, System.in.readline(); blocks if I recall correctly ;) Like so:
int i = 0
do
{
if(FLAG)
{
//Do stuff
i++;
//Clear Flag
}
Thread.Sleep(50); //Sleep for 50 ms
} while (i < 6);
or like so:
for(int i = 0; i < 6; i++) //Execute readline 6 times.
{
System.in.readLine();
}
Others have covered how to use System.in.readLine() to have the program explicitly require action from the user.
If what you need is not to have the program wait for the user, but allow you - the programmer - to slow the program down, in order to be able to find and fix a bug, you might want to consider using a debugger as this is exactly what it is designed for.
Any modern Java IDE has a debugger. The keys chosen to use it, just varies.
If you are using Eclipse, you are using either F11 or Ctrl-F11 (assuming Windows) to run your program. The difference is that F11 starts your program inside a debugger and Ctrl-F11 doesn't.
Put the cursor at the first line inside the for-loop, and choose Run->Toggle Breakpoint. A blue bullet will show to the left of the line. This indicates that the breakpoint is active - the debugger will now stop your program every time it reaches that line.
Now run your program in the debugger with F11. The program stops at the line, and you can investigate your variables in the Variables pane as needed, and continue execution with F8 whenever you are ready.