How to return a binary value by comparing two variables? - scheduling

I currently study operation research. I required to formulate the model as LP model.
The objective function is
y = ( ai * C1i + bi * C2i)
,where ai = max(0, xi - Ti) ; bi = max(0, Ti - xi)
This is a scheduling problem. xi is the decision variables of scheduled time for job i, and Ti is the best fit time for job i. Each unit of time of earlier or late will subject to a penalty cost. C1i and C2i are the penalty cost per unit.
if job i is start before the best time Ti for job i, the penalty cost will be
bi * C2i.
if job i is start after the best time Ti for job i, the penalty will be
ai * C1i.
During my formulation, i found that it is difficult to use max(,) function in Lingo or Cplex. Acutally, there is no max(,) function in the program. If the task start before Ti, ai = xi - Ti will be negative. bi = Ti - xi will be positive. I cannot think about a way to convert "if negative, then the value change into 0".
Is it possible to formula the objective with the below function?
y = ( ai * C1i*yi + bi * C2i*(1-yi))
if Ti - xi >= 0 ( Start before the best time for job i), then yi = 1
Otherwise, yi =0.
But, how can I formulate the above if-then-statement in LP model?
thanks!

The question is a little bit difficult to parse, but I think what you are after is something like:
Actually this was suggested in the duplicate question here. (Sorry: that question has been deleted).

Related

Solve ILP with Branch and Bound and CPLEX C++

I want to solve an ILP using a branch and bound algorithm for a graph labelling problem. My ILP has an objective function and constraints for every possible pair of nodes from the graph. So I have n^2 / 2 possible constraints, and the constraints have following shape:
for two vertices i, j \in V(G) add the constraints:
|X_i - X_j| >= k + 1 - d(i,j)
its obvious that this isn't linear. So i want to implement my algorithm that uses binary branch and bound:
start with empty LP only with the objective function
start with empty branch tree with start node
then at every node in the branch tree, create two child nodes.
in the first child node
add the constraints X_i - X_j >= k + 1 - d(i,j)
and constraint X_i >= X_j
for the second child node
add the constraint -(X_i - X_j) >= k + 1 - d(i,j)
and the constraint X_j >= X_i
repeat this step and possibly bound, until we find best solution
If I do this branch and bound algorithm, and search for the best solution, I would get the best occupancy of which variable should be greater than which.
Then I would get a LP, with constant constraints and I would get the optimal integer solution.
My question now is, what is the best way of doing that in c++ and cplex?
Should I always create a new IloModel in CPLEX? Or can I do it all in the same IloEnv?
I know that there are built in options, to specify the branch and bound in CPLEX, but I would like to do it "manually", so I can also implement functions that selects the "best" next constraint to add.
Thank you very much in advance!
Within CPLEX you also have Constraint Programmming and with OPL for example you can directly write
forall( ordered c1, c2 in Cells: distance[c1,c2] > 0) {
forall(t1 in 1..nbTrans[c1]) {
forall(t2 in 1..nbTrans[c2] )
abs(freq[<c1,t1>] - freq[<c2,t2>]) >= distance[c1,c2];
}
}
which is part of a frequency allocation model
The same can be done in C++

linear programming problem for minimum cost

A construction company has 6 projects, for each they need $d_i$ workers. The company has no workers at the beginning of project 1.
Each new worker must take a safety course that costs 300, and 50 more for each worker.
If there is no new worker there is no course.
Firing a worker does not cost any money, and a workers can't be rehired.
Given that the salary of a worker is 100 per project, formulate a linear programming problem that minimizes the workers costs.
What I tried:
Let $x_i$ be the number of new workers for project $i$.
Let $y_i$ be the number of old workers remaining from previous projects until project $i$ (all the workers hired - all the workers that were fired)
Let $z_i$ be an indicator such that $z_i =0 \iff x_i>0$
The function I'm trying to solve is:
$\min(\sum_{i=1}^6 150x_i + 300(1-z_i) + 100y_i)$
s.t:
\begin{align}
x_i,y_i,z_i &\ge 0 \\
z_i &\ge 1-x_i \\
y_i + x_i &\ge d_i \\
y_i &\ge y_{i-1} + x_i
\end{align}
Something feels not right to me. The main reason is that I tried to use matlab to solve this and it failed.
What did I do wrong? How can I solve this question?
When I see this correctly you have two small mistakes in your constraints.
The first appears when you use z_i >= 1-x_i. This allows z_i to take the value 1 all the time, which will never give you the extra cost of 300. You need to upper bound z_i such that z_i will not be 1 when you have x_i>0. For this constraint you need something called big M. For sufficiently large M you would then use z_i <= 1-x_i/M. This way when x_i=0 you can have z_i=1, otherwise the right hand side is smaller than 1 and due to integrality z_i has to be zero. Note that you usually want to choose M as tight as possible. So in your case d_i might be a good choice.
The second small mistake lays in y_i >= y_{i-1} + x_i. This way you can increase y_i over y_{i-1} without having to set any x_i. To force x_i to increase you need to flip the inequality. Additionally by the way you defined y_i this inequality should refer to x_{i-1}. Thus you should end up with y_i <= y_{i-1} + x_{i-1}. Additionally you need to take care of corner cases (i.e. y_1 = 0)
I think with these two changes it should work. Let me know whether it helped you. And if it still doesn't work I might have missed something.

Linear programming of taxation cost on fossil fuel and green energy

I am currently working on a project where I am modelling a set of combined heat and power production units (CHP).
I am using linear programming to do this for now.
The main idea is to minimize the overall production cost. In order to that one must consider the taxation on the fuel type used. The general idea is that heat produced with fossil fuels will have a tax on it and power produced with green energy will have a subsidy on it.
In order to calculate this I could do the following:
FossilShare = FossilFuel / TotalFuel
FossilHeat = FossilShare * Q
GreenPower = (1-FossilShare) * P
Where P and Q are the heat and power produced. Then my taxation cost function would be as following:
Cost = FossilHeat * Tax - GreenPower * subsidy
The problem, however, is that this is not linear. I cannot think of a way to linearise this and I cannot think of another way of doing it, because I need to calculate the portion of heat produced with fossil fuel and the portion of power produced with green energy.
Any help or suggestions would be much appreciated.
Thanks in advance
M. Frank

What is the practical use of the Kadane's algorithm?

This algorithm is interesting, I know that it's being used in image processing ( and probably other scenarios ), but what I find strange is that this algorithm also operates on negative values, and negative values are virtually non existent in the imaging world where there are a lot of unsigned int to represent the values .
Could you offer a practical example that takes advantage of the Kadane algorithm ?
One of the obvious application is business analysis where you need to find out the duration of time where the company experienced the maximum growth or also duration of time with minimum growth which helps company to find what they did good or bad during those periods to repeat or prevent them in future for benefit of company.
It can handle problems like:
Station Travel in Order
Given a list of n gas station of form P(D,X) where D is the distance from this station to next station and X is the amount of petrol available at this station, identify the starting station from where you can complete journey to each station in order from 1.....N. You can only go in one direction i.e from P(i) to P(i+1). Suppose you need to find the max sum.
Kadane's algorithm (solution)
Initialize:
max_so_far = 0
max_ending_here = 0
Loop for each element of the array
(a) max_ending_here = max_ending_here + a[i]
(b) if(max_ending_here < 0)
max_ending_here = 0
(c) if(max_so_far < max_ending_here)
max_so_far = max_ending_here
return max_so_far
Hotels Along the Croatian Coast.
I am quoting directly from wikipedia,
The problem was first posed by Ulf Grenander of Brown University in
1977, as a simplified model for maximum likelihood estimation of
patterns in digitized images. A linear time algorithm was found soon
afterwards by Jay Kadane of Carnegie-Mellon University (Bentley 1984).
if you don't already know what is maximum likelihood estimation, then here it goes for you.

Better alternative to divide and conquer algorithm

First let me explain the problem I'm trying to solve. I'm integrating my code with 3rd party library which does quite complicated financial predictions. For the purposes of this question let's just say I have a blackbox which returns y when I pass in x.
Now, what I need to do is find input (x) for a given output (y). Since I know lowest and highest possible input values I wrote the following algorithm:
define starting input range (minimum input value to maximum input value)
divide the range into two equal parts and find output for a middle value
find which half output falls into
repeat steps 2 and 3 until range is too small to divide any further
This algorithm does the job nicely, I don't see any problems with it. However, is there a faster way to solve this problem?
It sounds like x and y are strongly correlated (i.e. as x increases, so does y), as otherwise your divide and conquer algorithm wouldn't work.
Assumuing this is the case, and you could work out a correlation factor, then you might be able to multiply the midpoint by the correlation factor to potentially hone in the expected value quicker.
Please note that I've not tested this idea at all, but it's something to think about. Possible improvements would be to make the correlationFactor a moving average, or precompute it based on, say, the deciles between xLow and xHigh.
Also, this assumes that calling f(x) is relatively inexpensive. If it is expensive, then the increased number of calls to f(x) would dwarf any savings. In fact - I'm starting to think this is a stupid idea...
Hopefully the following pseudo-code illustrates what I mean:
DivideAndConquer(xLow, xHigh, correlationFactor, expectedValue)
xMid = (xHigh - xLow) * correlationFactor
// Add some range checks to make sure that xMid is within xLow and xHigh!!
y = f(xMid)
if (y == expectedValue)
return expectedValue
elseif (y < expectedValue)
correlationFactor = (xMid - xLow) / (f(xMid) - f(xLow))
return DivideAndConquer(xLow, xMid, correlationFactor, expectedValue)
else
correlationFactor = (xHigh - xMid) / (f(xHigh) - f(xMid))
return DivideAndConquer(xMid, xHigh, correlationFactor, expectedValue)