Resource Constrained Project Scheduling such that tasks are scheduled based on highest priority - project-planning

This is regarding a Resource Constrained Project Scheduling Problem (RCPSP). This involves scheduling certain tasks in time windows on machines subject to availability of manpower. This is set up in the form of an Integer Program. I'm using a uniform discrete time representation.
The decision variables are x_it: x_it = 1 if activity i is scheduled to start at a discrete time point t.
Every task has a priority associated with it due to external reasons. To illustrate the goal, consider 3 tasks - p1,p2,p3 with priorities 3,3,4. (two priority levels - 3,4) The requirement is this - if sufficient manpower is available to schedule p1 & p2 or p3 alone, p3 must be chosen even though p1+p2 > p3. I'm looking for a way to implement this logic using decision variables x_it.
I've tried implementing my requirement in the following manner: Assign a new priority (P) to each task: P1 = 3, P2 = 3, P3 = 7; Essentially this involves scaling each priority level such that no combination of lower priority tasks can be higher than this priority level and setting the objective function to "maximize P_i*x_it"
The problem with this approach is that while scaling for a large set of tasks (~300 tasks) and multiple priority levels (20 levels), the new priority values quickly become huge numbers (~10^17).
Is there a more robust way to implement this requirement within the Integer Programming paradigm?

One way would be:
Solve for jobs with highest priority (say priority 1). Let number of jobs schedule be n1.
Add constraint: scheduled number of jobs with priority 1 = n1
Solve for jobs with priorities 1 and 2. Let number of scheduled jobs with priority 2 be n2.
Add constraint: scheduled number of jobs with priority 2 = n2
etc

Related

How can a Neural Network learn from testing outputs against external conditions which it can not directly control

In order to simplify the question and hopefully the answer I will provide a somewhat simplified version of what I am trying to do.
Setting up fixed conditions:
Max Oxygen volume permitted in room = 100,000 units
Target Oxygen volume to maintain in room = 100,000 units
Maximum Air processing cycles per sec == 3.0 cycles per second (min is 0.3)
Energy (watts) used per second is this formula : (100w * cycles_per_second)SQUARED
Maximum Oxygen Added to Air per "cycle" = 100 units (minimum 0 units)
1 person consumes 10 units of O2 per second
Max occupancy of room is 100 person (1 person is min)
inputs are processed every cycle and outputs can be changed each cycle - however if an output is fed back in as an input it could only affect the next cycle.
Lets say I have these inputs:
A. current oxygen in room (range: 0 to 1000 units for simplicity - could be normalized)
B. current occupancy in room (0 to 100 people at max capacity) OR/AND could be changed to total O2 used by all people in room per second (0 to 1000 units per second)
C. current cycles per second of air processing (0.3 to 3.0 cycles per second)
D. Current energy used (which is the above current cycles per second * 100 and then squared)
E. Current Oxygen added to air per cycle (0 to 100 units)
(possible outputs fed back in as inputs?):
F. previous change to cycles per second (+ or - 0.0 to 0.1 cycles per second)
G. previous cycles O2 units added per cycle (from 0 to 100 units per cycle)
H. previous change to current occupancy maximum (0 to 100 persons)
Here are the actions (outputs) my program can take:
Change cycles per second by increment/decrement of (0.0 to 0.1 cycles per second)
Change O2 units added per cycle (from 0 to 100 units per cycle)
Change current occupancy maximum (0 to 100 persons) - (basically allowing for forced occupancy reduction and then allowing it to normalize back to maximum)
The GOALS of the program are to maintain a homeostasis of :
as close to 100,000 units of O2 in room
do not allow room to drop to 0 units of O2 ever.
allows for current occupancy of up to 100 people per room for as long as possible without forcibly removing people (as O2 in room is depleted over time and nears 0 units people should be removed from room down to minimum and then allow maximum to recover back up to 100 as more and more 02 is added back to room)
and ideally use the minimum energy (watts) needed to maintain above two conditions. For instance if the room was down to 90,000 units of O2 and there are currently 10 people in the room (using 100 units per second of 02), then instead of running at 3.0 cycles per second (90 kw) and 100 units per second to replenish 300 units per second total (a surplus of 200 units over the 100 being consumed) over 50 seconds to replenish the deficit of 10,000 units for a total of 4500 kw used. - it would be more ideal to run at say 2.0 cycle per second (40 kw) which would produce 200 units per second (a surplus of 100 units over consumed units) for 100 seconds to replenish the deficit of 10,000 units and use a total of 4000 kw used.
NOTE: occupancy may fluctuate from second to second based on external factors that can not be controlled (lets say people are coming and going into the room at liberty). The only control the system has is to forcibly remove people from the room and/or prevent new people from coming into the room by changing the max capacity permitted at that next cycle in time (lets just say the system could do this). We don't want the system to impose a permanent reduction in capacity just because it can only support outputting enough O2 per second for 30 people running at full power. We have a large volume of available O2 and it would take a while before that was depleted to dangerous levels and would require the system to forcibly reduce capacity.
My question:
Can someone explain to me how I might configure this neural network so it can learn from each action (Cycle) it takes by monitoring for the desired results. My challenge here is that most articles I find on the topic assume that you know the correct output answer (ie: I know A, B, C, D, E inputs all are a specific value then Output 1 should be to increase by 0.1 cycles per second).
But what I want is to meet the conditions I laid out in the GOALS above. So each time the program does a cycle and lets say it decides to try increasing the cycles per second and the result is that available O2 is either declining by a lower amount than it was the previous cycle or it is now increasing back towards 100,000, then that output could be considered more correct than reducing cycles per second or maintaining current cycles per second. I am simplifying here since there are multiple variables that would create the "ideal" outcome - but I think I made the point of what I am after.
Code:
For this test exercise I am using a Swift library called Swift-AI (specifically the NeuralNet module of it : https://github.com/Swift-AI/NeuralNet
So if you want to tailor you response in relation to that library it would be helpful but not required. I am more just looking for the logic of how to setup the network and then configure it to do initial and iterative re-training of itself based on those conditions I listed above. I would assume at some point after enough cycles and different conditions it would have the appropriate weightings setup to handle any future condition and re-training would become less and less impactful.
This is a control problem, not a prediction problem, so you cannot just use a supervised learning algorithm. (As you noticed, you have no target values for learning directly via backpropagation.) You can still use a neural network (if you really insist). Have a look at reinforcement learning. But if you already know what happens to the oxygen level when you take an action like forcing people out, why would you learn such a simple facts by millions of evaluations with trial and error, instead of encoding it into a model?
I suggest to look at model predictive control. If nothing else, you should study how the problem is framed there. Or maybe even just plain old PID control. It seems really easy to make a good dynamical model of this process with few state variables.
You may have a few unknown parameters in that model that you need to learn "online". But a simple PID controller can already tolerate and compensate some amount of uncertainty. And it is much easier to fine-tune a few parameters than to learn the general cause-effect structure from scratch. It can be done, but it involves trying all possible actions. For all your algorithm knows, the best action might be to reduce the number of oxygen consumers to zero permanently by killing them, and then get a huge reward for maintaining the oxygen level with little energy. When the algorithm knows nothing about the problem, it will have to try everything out to discover the effect.

Is it possible that you have the same arrival time in CPU Scheduling?

I have searched the internet for examples for the algorithms in cpu scheduling and I have never seen any examples with the same arrival time.
Is it possible to make the processes have the same arrival time?
For example:
Algorithm: Round Robin
Process ---- Arrival Time ----- Burst Time
P1 ----------------- 3 ------------------ 4 -----
P2 ----------------- 1 ------------------ 5 -----
P3 ----------------- 1 ------------------ 3 -----
Quantum = 1
What would be the gantt chart look like?
Is it possible to make the processes have the same arrival time?
Yes, for normal definitions of "same time" (e.g. excluding "in the same Planck time quantum") it's possible for processes to have the same arrival time.
For an example, imagine if 100 tasks sleep until midnight. When midnight occurs a timer IRQ handler processes a list of tasks waiting to wake up and wakes up 100 tasks at the "same" time.
Now, for this example you could say that "same time" is stricter; and that the timer IRQ handler processes the list of tasks sequentially and adds them to scheduler's queues sequentially, and that it's only "almost at the same time". In this case it's still possible to have N CPUs running in parallel (with a different timer for each CPU) that happen to wake (up to) N tasks at the same time.
Of Course, multiple processes can have the same arrival time i.e the time they came for looking the CPU to execute them. And its the responsibility of the Processor to handle and schedule them accordingly as per the appropriate Scheduling Algorithms.
When the Arrival time for two or more processes are same, then the RR-Scheduling follows FCFS {First come first serve} approach. Here in Round robin scheduling with quantum = 1, we have
Gantt Chart
At time 0, no process
At time 1 , we have P2 and P3 with P2 first then after a quantum RR executes P3,
At time 3 we have all three processes with order P2,P3,P1 hence the RR-Algorithm will keep switching between them until they complete their execution (burst) time.
And we will get all executed at time 13.

Assumptions taken in Rate Monotonic Scheduling Algorithm?

I'm doing a Real Time Systems course, and we in the class are stuck in some assumptions in the section 4 of the paper of Liu and Layland about Rate-Monotonic Scheduling that we can not fully understand:
If floor(T2/T1) is the number of Times that Task1 interferes in Task2 why the function applied to T2/T1 is floor and not ceil?
Also, there are these equations:
According to the paper, and as we clearly see in the image, equation (1) is a necessary condition but not sufficient, while equation (2) is a sufficient condition. This gives sense to me, but why do the authors state as a conclusion this:
In other words, whenever the T1 < T2 and C1,C2 are such that the task scheduling is feasible with Task2 at higher priority than Task1, it is also feasible with Task1 at higher priority than Task2 (but opposite is not true)[...] Specifically, tasks with higher request rates will have higher priorities.
If the second equation, where Task2 have the highest priority, is a sufficient condition, why could we assume that the task scheduling would be feasible if Task1 have the highest priority instead of Task2?
I hope i explained myself well, please feel free to tell me also if i've understood wrong the article statements.
EDIT:
As requested, here is a little explanation to the terms in the article and presented in this question.
In the article, T1 refers to the Period (and Deadline) of Task1,
and T2 to the Period (and Deadline) of Task2.
C1 and C2 refer to the runtime of Task1 and Task2 each one.
First of all, too bad you didn't include what T's and C's mean. I had to read the article, but it was an interesting read so thanks.
It's pretty straightforward. The first equation (1) defines what is the highest possible T2 period value - it cannot be longer than C2 (time needed to execute task 2) plus C1 multiplied by the number of times task 1 is requested during period T2 (hence, floor(T1/T2)) AND CAN FULLY EXECUTE. If T1 is requested, it's executed no matter what, as in this case it's the highest priority task. Task 2 is not able to execute if task 1 is currently executing.
Consider the equation (1) with certain values. Let's use the values suggested in the article. T2 = 5, T1 = 2, C1 = C2 = 1. The floor(T2/T1) gives us the number of requests of task 1 that occur during task 2 period. It's 2 (floor(5/2)). If it would be ceiling(T2/T1) than the result would be 3, which is obviously wrong, as the third request was indeed executed (as depicted in Figure 2), but the period didn't end. To understand it better, consider the same case, but extend the task 1 execution time C1 to 1.5. Below is the timeline for such a system, which is feasible. It fulfills the equaiton (1). If we would use ceiling(T2/T1) then the equation would not be fulfilled, and you clearly see below that the system is fine. I think this will help you see and understand the difference - we need to take into account not the number of times the task is requested, but the number of times the full period of a higher priority task can fit in the period of the lower priority task).
Tasks timeline. Image made using Excel. One "column" is 0.5 unit of time
That's the first part of my answer, need to take some more time to answer the other part of your question. I'll post an update soon.
Anyway, thanks for linking to an interesting article.

Assign people to tasks that require a team while minimising total time

The classical assignment problem deals with assigning N agents to M jobs while minimising the time spent on each job. The problem has a solution in polynomial time, called the Hungarian algorithm, which has a cost matrix C as an input and returns the optimal list of assignments.
In my case, I got the same problem, but with one difference. Each job requires a pair of two works to be assigned to it. The number of agents are chosen such that N is an even number in order for this to be possible.
I am fairly new to assignment problem related questions, so I am not sure how to tackle this problem.
How would one solve this problem?
Edit: Note that a agent can be assigned to at most one task, it can not be assigned to multiple tasks. One can assume M(jobs) = 2N(agents) and otherwise introduce dummy agent or tasks.
Since there are twice as many tasks as workers, you need to double the number of tasks. Since each task requires two workers, you can double the number of tasks by duplicating each of them (ex. Task 1 becomes Task 1a and Task 1b). You would then have an equal number of workers and tasks, and after running the Hungarian Algorithm you can find your pairs of workers by looking at who was assigned to each split of each task.

Is it possible to have priority inversion with two processes?

The usual example gives three processes, but shouldn't it be possible with only two processes?
Let us assume we have two processes, p3 and p1. p3's priority is less than p1. p3 is currently in the critical section using a resource which p1 will need. p1 comes along, and p3 gets preempted by p1. But, p3 was holding a resource which p1 needed to run.
Isn't this an example of priority inversion with 2 processes?
No, it's not. p1 will just block when it tries to acquire the resource, which will allow p3 to run again, finish using the resource, and relinquish it, thereby unblocking p1.
Wikipedia's example of a priority inversion is a good reference that describes why three tasks are required.