Discrete-event Simulation Algorithm 1.2.1 in C++ - c++

I'm currently trying to work and extend on the Algorithm given in "Discrete-event Simulation" text book pg 15. My C++ knowledge is limited, It's not homework problem just want to understand how to approach this problem in C++ & understand what going.
I want to be able to compute 12 delays in a single-server FIFO service node.
Algorithm in the book is as follow:
Co = 0.0; //assumes that a0=0.0
i = 0;
while (more jobs to process) {
i++;
a_i = GetArrival ();
if (a_i < c_i - 1)
d_i = c_i - 1 - a_i; //calculate delay for job i
else
d_i = 0.0; // job i has no delay
s_i = GetService ();
c_i = a_i + d_i + s_i; // calculate departure time for job i
}
n = i;
return d_1, d_2,..., d_n
The GetArrival and GetService procedures read the next arrival and service time from a file.

Just looking at the pseudo-code, it seems that you just need one a which is a at step i, one c which is c at step i-1, and an array of ds to store the delays. I'm assuming the first line in your pseudo-code is c_0 = 0 and not Co = 0, other wise the code doesn't make a lot of sense.
Now here is a C++-ized version of the pseudo-code:
std::vector<int> d;
int c = 0;
int a, s;
while(!arrivalFile.eof() && !serviceFile.eof())
{
arrivalFile >> a;
int delay = 0;
if (a < c)
delay = c - a;
d.push_back(delay);
serviceFile >> s;
c = a + delay + s;
}
return d;

If I understand the code right, d_1, d_2, ..., d_n are the delays you have, number of delays depends on number of jobs to process. while (more jobs to process)
thus if you have 12 processes you will have 12 delays.
In general if arrival time is less than previous departure time then the delay is the previous departure time - current arrival time
if (a_i < c_i-1)
d_i = c_i-1 - a_i;
the first departure time is set to zero
if something is not clear let me know

Related

How is myArray.size() implemented in Salesforce Apex? Does the method retrieve a value stored on the List.class object, or calculated at time of call?

Often when I'm writing a loop in Apex, i wonder if it's inefficient to call myArray.size() inside of a loop. My question is really: should I use myArray.size() inside the loop, or store myArray.Size() in an Integer variable before starting the loop and reuse that instead (assuming the size of myArray remains constant).
Under the hood, the method either counts each element of an array by iterating through it and incrementing a size variable which it then returns, or the List/Set/Map etc class stores the size variable inside itself and updates the value any time the array is changed. Different languages handle this in different ways, so how does Apex work?
I went searching but couldn't find an answer. The answer could change the way I code, since calling myArray.size() could exponentially increase the number of operations performed when called inside a loop.
I tried running a benchmark of the two scenarios as laid out below and found that myList.size() does take longer, but didn't really answer my question. Especially since the code was too simple to really make much of a difference.
In both samples, the list has ten thousand elements, and I only started timing once the list is fully created. The loop itself doesn't do anything interesting. It just counts up. That was the least resource heavy thing I could think of.
Sample 1 - store size of list in an integer before entering loop:
List<Account> myArray = [SELECT Id FROM Account LIMIT 10000];
Long startTime = System.now().getTime();
Integer size = myArray.size();
Integer count = 0;
for (Integer i = 0; i < 100000; i++) {
if (count < size) {
count++;
}
}
Long finishTime = System.now().getTime();
Long benchmark = finishTime - startTime;
System.debug('benchmark: ' + benchmark);
Results after running 5 times: 497, 474, 561, 445, 474
Sample 2 - use myArray.size() inside loop:
List<Account> myArray = [SELECT Id FROM Account LIMIT 10000];
Long startTime = System.now().getTime();
Integer count = 0;
for (Integer i = 0; i < 100000; i++) {
if (count < myArray.size()) {
count++;
}
}
Long finishTime = System.now().getTime();
Long benchmark = finishTime - startTime;
System.debug('benchmark: ' + benchmark);
Results after running 5 times: 582, 590, 667, 742, 730
Sample 3 - just for good measure (control), here's the loop without the if condition:
Long startTime = System.now().getTime();
Long count = 0;
for (Integer i = 0; i < 100000; i++) {
count++;
}
Long finishTime = System.now().getTime();
Long benchmark = finishTime - startTime;
System.debug('benchmark: ' + benchmark);
Results after running 5 times: 349, 348, 486, 475, 531

Counting active tasks using start time and duration in C++

The input consists of a set of tasks given in increasing order of start time, and each task has a certain duration associated.
The first line is number of tasks, for example
3
2 5
4 23
7 4
This means that there are 3 tasks. The first one starts at time 2, and ends at 7 (2+5). Second starts at 4, ends at 27. Third starts at 7, ends at 11.
We assume each task starts as soon as it is ready, and does not need to wait for a processor or anything else to free up.
This means we can keep track of number of active tasks:
Time #tasks
0 - 2 0
2 - 4 1
4 - 11 2
11 - 27 1
I need to find 2 numbers:
Max number of active tasks at any given time (2 in this case) and
Average number of active tasks over the entire duration computed here as :
[ 0*(2-0) + 1*(4-2) + 2*(11-4) + 1*(27-11) ] / 27
For this,
I have first found the time when all tasks have come to an end using the below code:
#include "stdio.h"
#include "stdlib.h"
typedef struct
{
long int start;
int dur;
} task;
int main()
{
long int num_tasks, endtime;
long int maxtime = 0;
scanf("%ld",&num_tasks);
task *t = new task[num_tasks];
for (int i=0;i<num_tasks;i++)
{
scanf("%ld %d",&t[i].start,&t[i].dur);
endtime = t[i].start + t[i].dur;
if (endtime > maxtime)
maxtime = endtime;
}
printf("%ld\n",maxtime);
}
Can this be done using Priority Queues implemented as heaps ?
Your question is rather broad, so I am going to just give you a teaser answer that will, hopefully, get you started, attempting to answer your first part of the question, with a not necessarily optimized solution.
In your toy input, you have:
2 5
4 23
7 4
thus you can compute and store in the array of structs that you have, the end time of a task, rather than its duration, for later usage. That gives as an array like this:
2 7
4 27
7 11
Your array is already sorted (because the input is given in that order) by start time, and that's useful. Use std::sort to sort the array, if needed.
Observe how you could check for the end time of the first task versus the start time of the other tasks. With the right comparison, you can determine the number of active tasks along with the first task. Checking whether the end time of the first task is greater than the start time of the second task, if true, denotes that these two tasks are active together at some point.
Then you would do the same for the comparison of the first with the third task. After that you would know how many tasks were active in relation with the first task.
Afterwards, you are going to follow the same procedure for the second task, and so on.
Putting all that together in code, we get:
#include "stdio.h"
#include "stdlib.h"
#include <algorithm>
typedef struct {
int start;
int dur;
int end;
} task;
int compare (const task& a, const task& b) {
return ( a.start < b.start );
}
int main() {
int num_tasks;
scanf("%d",&num_tasks);
task *t = new task[num_tasks];
for (int i=0;i<num_tasks;i++) {
scanf("%d %d",&t[i].start,&t[i].dur);
t[i].end = t[i].start + t[i].dur;
}
std::sort(t, t + num_tasks, compare);
for (int i=0;i<num_tasks;i++) {
printf("%d %d\n", t[i].start, t[i].end);
}
int max_noOf_tasks = 0;
for(int i = 0; i < num_tasks - 1; i++) {
int noOf_tasks = 1;
for(int j = i + 1; j < num_tasks; j++) {
if(t[i].end > t[j].start)
noOf_tasks++;
}
if(max_noOf_tasks < noOf_tasks)
max_noOf_tasks = noOf_tasks;
}
printf("Max. number of active tasks: %d\n", max_noOf_tasks);
delete [] t;
}
Output:
2 7
4 27
7 11
Max. number of active tasks: 2
Now, good luck with the second part of your question.
PS: Since this is C++, you could have used an std::vector to store your structs, rather than a plain array. That way you would avoid dynamic memory allocation too, since the vector takes care that for you automatically.

Bit-wise shift for Matrix iteration?

Ok some background
I have been working on this project, which I had started back in college, (no longer in school but want to expand on it to help me improve my understanding of C++). I digress... The problem is to find the Best path through a matrix. I generate a matrix filled with a set integer value lets say 9. I then create a path along the outer edge (Row 0, Col length-1) so that all values along it are 1.
The goal is that my program will run through all the possible paths and determine the best path. To simplify the problem I decide to just calculate the path SUM and then compare that to what the SUM computed by the application.
(The title is miss leading S=single-thread P=multi-threads)
OK so to my question.
In one section the algorithm does some simple bit-wise shifts to come up with the bounds for iteration. My question is how exactly do these shifts work so that the entire matrix (or MxN array) is completely traversed?
void AltitudeMapPath::bestPath(unsigned int threadCount, unsigned int threadIndex) {
unsigned int tempPathCode;
unsigned int toPathSum, toRow, toCol;
unsigned int fromPathSum, fromRow, fromCol;
Coordinates startCoord, endCoord, toCoord, fromCoord;
// To and From split matrix in half along the diagonal
unsigned int currentPathCode = threadIndex;
unsigned int maxPathCode = ((unsigned int)1 << (numRows - 1));
while (currentPathCode < maxPathCode) {
tempPathCode = currentPathCode;
// Setup to path iteration
startCoord = pathedMap(0, 0);
toPathSum = startCoord.z;
toRow = 0;
toCol = 0;
// Setup from path iteration
endCoord = pathedMap(numRows - 1, numCols - 1);
fromPathSum = endCoord.z;
fromRow = numRows - 1;
fromCol = numCols - 1;
for (unsigned int index = 0; index < numRows - 1; index++) {
if (tempPathCode % 2 == 0) {
toCol++;
fromCol--;
}
else {
toRow++;
fromRow--;
}
toCoord = pathedMap(toRow, toCol);
toPathSum += toCoord.z;
fromCoord = pathedMap(fromRow, fromCol);
fromPathSum += fromCoord.z;
tempPathCode = tempPathCode >> 1;
}
if (toPathSum < bestToPathSum[threadIndex][toRow]) {
bestToPathSum[threadIndex][toRow] = toPathSum;
bestToPathCode[threadIndex][toRow] = currentPathCode;
}
if (fromPathSum < bestFromPathSum[threadIndex][fromRow]) {
bestFromPathSum[threadIndex][fromRow] = fromPathSum;
bestFromPathCode[threadIndex][fromRow] = currentPathCode;
}
currentPathCode += threadCount;
}
}
I simplified the code since all the extra stuff just detracts from the question. Also if people are wondering I wrote most of the application but this idea of using the bit-wise operators was given to me by my past instructor.
Edit:
I added the entire algorithm for which each thread executes on. The entire project is still a work a progress but here is the source code for the whole thing if any one is interested [GITHUB]
A right bit shift is equivalent to dividing by 2 to the power of the number of bits shifted. IE 1 >> 2 = 1 / (2 ^ 2) = 1 / 4
A left bit shift is equivalent to multiplying by 2 to the power of the number of bits shifted. IE 1 << 2 = 1 * 2 ^ 2 = 1 * 4
I'm not entirely sure what that algorithm does and why it needs to multiply by 2^ (num rows - 1) and then progressively divide by 2.

How to make this code shorter to do faster

I am new c++ learner.I logged in Codeforces site and it is 11A question:
A sequence a0, a1, ..., at - 1 is called increasing if ai - 1 < ai for each i: 0 < i < t.
You are given a sequence b0, b1, ..., bn - 1 and a positive integer d. In each move you may choose one element of the given sequence and add d to it. What is the least number of moves required to make the given sequence increasing?
Input
The first line of the input contains two integer numbers n and d (2 ≤ n ≤ 2000, 1 ≤ d ≤ 106). The second line contains space separated sequence b0, b1, ..., bn - 1 (1 ≤ bi ≤ 106).
Output the minimal number of moves needed to make the sequence increasing.
I write this code for this question:
#include <iostream>
using namespace std;
int main()
{
long long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
while(a[i]>=a[i+1])
{
a[i+1]+=d;
s+=1;
}
}
cout<<s;
return 0;
}
It work good.But In a test codeforces server enter 2000 number.Time limit is 1 second.But it calculate up to 1 second.
How to make this code shorter to calculate faster?
One improvement that can be made is to use
std::ios_base::sync_with_stdio(false);
By default, cin/cout waste time synchronizing themselves with the C library’s stdio buffers, so that you can freely intermix calls to scanf/printf with operations on cin/cout. By turning this off using the above call the input and output operations in the above program should take less time since it no longer initialises the sync for input and output.
This is know to have helped in previous code challenges that require code to be completed in a certain time scale and which the c++ input/output was causing some bottleneck in the speed.
You can get rid of the while loop. Your program should run faster without
#include <iostream>
using namespace std;
int main()
{
long int n,d,ci,i,s;
s=0;
cin>>n>>d;
int a[n];
for(ci=0;ci<n;ci++)
{
cin>>a[ci];
}
for(i=0;i<(n-1);i++)
{
if(a[i]>=a[i+1])
{
int x = ((a[i] - a[i+1])/d) + 1;
s+=x;
a[i+1]+=x*d;
}
}
cout<<s;
return 0;
}
This is not a complete answer, but a hint.
Suppose our seqence is {1000000, 1} and d is 2.
To make an increasing sequence, we need to make the second element 1,000,001 or greater.
We could do it your way, by repeatedly adding 2 until we get past 1,000,000
1 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + 2 + ...
which would take a while, or we could say
Our goal is 1,000,001
We have 1
The difference is 1,000,000
So we need to to do 1,000,000 / 2 = 500,000 additions
So the answer is 500,000.
Which is quite a bit faster, because we only did 1 addition (1,000,000 + 1), one subtraction (1,000,001 - 1) and one division (1,000,000 / 2) instead of doing half a million additions.
Just as #molbdnilo said, Use math to get rid of the loop, and it's simple.
Here is my code, accepted on Codeforces.
#include <iostream>
using namespace std;
int main()
{
int n = 0 , b = 0;
int a[2001];
cin >> n >> b;
for(int i = 0 ; i < n ; i++){
cin >> a[i];
}
int sum = 0;
for(int i = 0 ; i < n - 1 ; i++){
if(a[i] >= a[i + 1]){
int minus = a[i] - a[i+1];
int diff = minus / b + 1;
a[i+1] += diff * b;
sum += diff;
}
}
cout << sum << endl;
return 0;
}
I suggest you profile your code to see where the bottlenecks are.
One of the popular areas of time wasting is with input. The fewer input requests, the faster your program will be.
So, you could speed up your program by reading from cin using read() into a buffer and then parse the buffer using istringstream.
Other techniques include loop unrolling and optimizing for data cache. Reducing the number of branches or if statements will also speed up your programs. Processor prefer crunching data and moving data around to jumping to different areas in the code.

counters updated according to two different conditions within a loop

I am trying to make a call billing program in c++. One of the features of this small program is the ability to update discount minutes spoken within discount hours and normal-priced minutes during business hours, depending on which time stretch is entered.
The user first enters the time as a string like this 22:00
Then I have a function which takes the string and turns it into an integer. For example the 22:00 above is turned into 2200
I have then another help function that takes an int, the int above and turns it to the decimal time.
double turnTimeToDecimal(int timeRaw){
double decimalTime;
decimalTime = timeRaw * 0.01;
return decimalTime;
}
The business hours which bear no discount and are between 8.00 am and 18.30am in order to deal with this feature I update two counters inside a for loop that goes from 0 to 1417minutes (24hrs):
double myStartDecimal = 0.0;
double myStopDecimal = 0.0;
myStartDecimal = turnTimeToDecimal(myStartRaw);
myStopDecimal = turnTimeToDecimal(myStopRaw);
//hours and minutes start
int hourStart = (int)floor(myStartDecimal);
int minuteStart = (int)round(100*(myStartDecimal - hourStart));
//hours and minutes stop
int hourStop = (int)floor(myStopDecimal);
int minuteStop = (int) round(100*(myStopDecimal - hourStop));
int totalMinutesPremium = 0;
int totalMinutesDiscount = 0;
int i = 0;
int k = 0;
for(k = (hourStart* 60) + minuteStart; k < (hourStop * 60) + minuteStop + round(((double)minuteStop/100)); k++){
//will update the corresponding counter depending
//on the time stretch, business hours 8.00 - 18.30.
if(hourStart >= 8 && hourStop < 18.5){
totalMinutesPremium++;
}else{
totalMinutesDiscount++;
}
}
//will give total minutes
cout << " k is: " << k << endl;
//will give the total number of minutes during the business hours and
//the total number of minutes during the discount hours(non-bussiness hours)
cout << "Total minutes premium " << round(totalMinutesPremium) <<
" Total Minutes discount " << round(totalMinutesDiscount) << endl;
However, the program does detects whether the time stretch entered is within business hours or not, except in one case. If the time for example lies between 7:30 and 8:30 (business hours between 7:59-18:30) it does not return the combination of minutes within the business hours which I would expect to be 30 min and minutes within the discount hours which I would expect to be 30 minutes as well, since the discount stretch ends at 07:59 and it starts again at 18:31.
Hopefully I made myself clear.
Inside the for loop, you allocate the given minute depending on hourStart and hourStop, not on whether the given minute is during business hours. If the call encroaches on discount hours, then the whole call will be discounted.
"However HourStop is an int. same thing goes for hourStart"
Then it's not going to work, if can't use decimal values with ints like you do here:
hourStop < 18.5
well.. you can but it's not going to work the way you want it to. If you have int hourStop = 18.5 then it's going to get truncated to 18 since it can't be a fractional number. You need to use a different type, such as double
Also, the condition in your loop depends on hourStart and hourStop which are never changing in the loop:
if(hourStart >= 8 && hourStop < 18.5){
So you'll always hit the same if condition (which ever it is)
Why use a loop? Why not just do the math?
While not the complete code answer... you can fill in the blanks...
if( startTime >= startOfPremiumPeriod && endTime <= endOfPremiumPeriod )
totalMinutesPremimum = endTime - startTime;
else if( startTime < startOfPremiumPeriod && endTime < startOfPremimumPeriod )
totalMinutesDiscount = endTime - startTime;
.... etc. etc. etc.
You can take into account the case where the start time is before midnight and the end time after midnight by adding 24 hours to the end time...
if( endTime < startTime ) endTime += 1440;