How to optimize a problem using only linear constraints - optimization

I am new to AMPL. Currently I am trying to optimize a networking problem. I can only use CPLEX solver. Others like ILOG CP are forbidden.
Input:
Demands - set of demands that have to be fulfilled (basically QoS rules) which consist of multiple paths between a given pair of servers. Every path must be assigned some guaranteed bandwidth which is >= 0
demand_maxPath - number of paths for a demand d
hd - bandwidth requested for a demand d
Goal
The goal is to assign bandwidths to every path with regards to some cost function.
Here is an example. d denotes demand id, x(d,1) is a first path that belongs to demand d and so on, hd denotes bandwidth requested for a demand d.
Constraints
There are a couple of constraints:
sum of bandwidths of all paths for a demand d must equal hd
x(d,p) must be equal to hd, where p is a variable
Constraint 2 enforces that all other paths from a demand d, except for path (x,dp) must be equal to 0.
Approach
My approach: I declared a variable:
var demandPath_signalCount { d in Demands, 1..demand_maxPath[d]}, >= 0;
which holds values for each of the paths. The following constraint reflects contraint 1:
subject to demand_satisfaction_constraint { d in Demands }:
sum { dp in 1..demand_maxPath[d] } demandPath_signalCount[d,dp] = h[d];
However, I can't think of a way to write constraint 2. For example:
subject to path_value_satisfaction_constraint { d in Demands }:
max { dp in 1..demand_maxPath[d] } demandPath_signalCount[d,dp] = h[d];
doesn't work since max() function is nonlinear.
Other idea was to declare another variable:
var demand_chosenPath { d in demands }, >= 0;
and to use it like so:
subject to path_value_satisfaction_constraint { d in Demands }:
demandPath_signalCount[d,demand_chosenPath[d]] = h[d];
It obviously doesn't work either since variables cannot be used as indices.
Yet another way that I tried was to constraint the values that demandPath_signalCount may be equal to like so:
set possible_values {d in Demands } = 0..demand_volume[d] by demand_volume[d];
and
subject to possible_values_satisfaction_constraint { d in Demands, dp in 1..demand_maxPath[d] }:
demandPath_signalCount[d,dp] in possible_values[d];
But then again, the error is: continuous variable in tuple
How to formulate the second constraint?

Related

Constraint to require a certain number of matches

I am trying to write a hard constraint that requires that a certain value has been chosen a certain number of times. I have a constraint written below, which (I think) filters to a set of results that match this criteria, and I want it to penalize if there are no such results. I cannot figure out how to work .ifNotExists() into this. I think I am missing some understanding.
fun cpMustUseN(constraintFactory: ConstraintFactory): Constraint {
return constraintFactory.forEach(MealMenu::class.java)
.join(CpMustUse::class.java, equal({ mm -> mm.slottedCp!!.id }, CpMustUse::cpId))
.groupBy({ _, cpMustUse -> cpMustUse.numRequired }, countBi())
.filter { numRequired, count -> count >= numRequired }
.penalize(HardSoftScore.ONE_HARD)
.asConstraint("cpMustUseN")
}
MealMenu is an entity:
#PlanningEntity
class MealMenu {
#PlanningId
var id = 0
#PlanningVariable(valueRangeProviderRefs = ["cpRange"])
var slottedCp: Cp? = null
}
CpMustUse is a #ProblemFactCollectionProperty on my solution class, and the class looks like this:
class CpMustUse {
var cpId = 1
var numRequired = 4
}
I want to, in this case, constrain the result such that cpId 1 is chosen at least 4 times.
There are two conceptual issues here:
groupBy() will only match if the join returns a non-zero number of matches. Therefore you will never get a countBi() of zero - in that case, groupBy() will simply never match. Therefore you can not use grouping to check that something does not exist.
ifNotExists() always applies to a fact from the working memory. You can not use it to check if a result of a previous calculation exists.
Combined together, this makes your approach infeasible. This particular requirement will be a bit trickier to implement.
Start by inverting the logic of the constraint you pasted. Penalize every time count < numRequired; this handles all cases where count >= 1.
Then introduce a second constraint that will handle specifically the case where the count would be zero - in this case, you should be able to use forEach(MealMenu::class.java).ifNotExists(CpMustUse::class, ...).

MS Access - multiple count from same table

First time poster...
I am using access to build a report for alarms from a control system. The list is an export from the alarm utility which needs needs 3 important bits of data:
Module - Name of instrument associated with alarm
Description - description of the instrument
Alarm type - High, High High etc.
I would like to do a top ten of all the alarms but the issue I'm having is that the instrument module contains multiple different types of alarms and I need to filter for each one. I used the group by then count, but it takes all instances of module and does not break it down.
I am not very good at SQL and access and I'm sure its a simple fix.
Any help would be appreciated
I you want multiple count from same table you can write the query like below
record = session.createSQLQuery("select count(village_id),count(date_of_action), from TABLE_NAME where CONDITION ORDER BY date_of_action DESC" ).list();
if (record != null && record.size() > 0) {
for(Object[] obj:(List<Object[]>)record ){
int i = 0;
BigInteger villageCounts = (BigInteger)obj[i];
BigInteger memberCounts = (BigInteger)obj[++i];

How to model domain index with subset of set in minizinc

I am working on a nurse scheduling problem with the constraint stating that there should not be a day shift assigned to nurse after a night shift in previous day.
The constraint looks like this:
The shift set is "set of int: shift=1..7",
set of int: dayshift ={1,3,4};
set of int: dayshift={2,5,6,7};
How to model this constraint in minizinc?
I've tried:
constraint
forall(e in Employee, d in Day where d != Day[card(Day)])(
Assign[e, d, sh in NightShfit] + Assign[e, d+1, sh in DayShift] < 1
);
error: MiniZinc: type error: undefined identifier `sh'
The solution to your problem is to compute the sum of the "Assign" variables for both of the shift:
constraint forall(e in Employee, d in Day where d != Day[card(Day)])(
sum(sh in NightShift)(Assign[e, d, sh]) + sum(sh in DayShift)(Assign[e, d+1, sh]) < 1
);
As a side note I would like to remark that using 0/1 variables for these kinds of problems is only a good way of modelling for mathematical optimisation solvers (MIP). Constraint Programming (CP) solvers and Lazy Clause Generation (LCG) solvers will not work efficiently even though they are great for these kinds of problems.
My recommendation would be to have the different kinds of shift (for every day) as an enum and then assign one version of it for every employee for every day. Constraints like the ones your expressing here then often fit well into a regular constraint which performs great of both MIP and CP/LCG solvers. (In case of MIP it gets automatically transformed into a flow model).

What is the use case that makes EAVT index preferable to EATV?

From what I understand, EATV (which Datomic does not have) would be great fit for as-of queries. On the other hand, I see no use-case for EAVT.
This is analogous to row/primary key access. From the docs: "The EAVT index provides efficient access to everything about a given entity. Conceptually this is very similar to row access style in a SQL database, except that entities can possess arbitrary attributes rather then being limited to a predefined set of columns."
The immutable time/history side of Datomic is a motivating use case for it, but in general, it's still optimized around typical database operations, e.g. looking up an entity's attributes and their values.
Update:
Datomic stores datoms (in segments) in the index tree. So you navigate to a particular E's segment using the tree and then retrieve the datoms about that E in the segment, which are EAVT datoms. From your comment, I believe you're thinking of this as the navigation of more b-tree like structures at each step, which is incorrect. Once you've navigated to the E, you are accessing a leaf segment of (sorted) datoms.
You are not looking for a single value at a specific point in time. You are looking for a set of values up to a specific point in time T. History is on a per value basis (not attribute basis).
For example, assert X, retract X then assert X again. These are 3 distinct facts over 3 distinct transactions. You need to compute that X was added, then removed and then possibly added again at some point.
You can do this with SQL:
create table Datoms (
E bigint not null,
A bigint not null,
V varbinary(1536) not null,
T bigint not null,
Op bit not null --assert/retract
)
select E, A, V
from Datoms
where E = 1 and T <= 42
group by E, A, V
having 0 < sum(case Op when 1 then +1 else -1 end)
The fifth component Op of the datom tells you whether the value is asserted (1) or retracted (0). By summing over this value (as +1/-1) we arrive at either 1 or 0.
Asserting the same value twice does nothing, and you always retract the old value before you assert a new value. The last part is a prerequisite for the algorithm to work out this nicely.
With an EAVT index, this is a very efficient query and it's quite elegant. You can build a basic Datomic-like system in just 150 lines of SQL like this. It is the same pattern repeated for any permutation of EAVT index that you want.

Fox-Goat-Cabbage Transportation

My question is about an old transportation problem -- carrying three items across a river with a boat only capable of tranferring one item at a time. A constraint is certain items cannot be left together, such as the cabbage with the goat, wolf with the goat etc. This problem should be solveable using Integer programming, or another optimization approach. The cost function is all items being on the other side of the river, and the trips required to get there could be the output from Simplex (?) that tries out different feasible solutions. I was wondering if anyone has the Integer Programming (or Linear Programming) formulation of this problem, and / or Matlab, Octave, Python based code that can offer the solution programmatically, including a trace of Simplex trying out all paths -- our boat rides.
There was some interesting stuff here
http://www.zib.de/Publications/Reports/SC-95-27.pdf
Thanks,
I recommend using binary variables x_i,t to model the positions of your items, i.e. they are zero if the item is located on the left shore after trip t and one otherwise. At most one of these variables can change during a trip. This can be modeled by
x_wolf,1 + x_cabbage,1 + x_goat,1 <= 1 + x_wolf,0 + x_cabbage,0 + x_goat,0 and
x_wolf,1 >= x_wolf,0
x_cabbage,1 >= x_cabbage,0
x_goat,1 >= x_goat,0
Similar constraints are required for trips in the other direction.
Furthermore, after an odd number of trips you nedd constraints to check the items on the left shore, and similarily you have to check the right shore. For instance:
x_wolf,1 + x_goat,1 >= 0 and
x_wolf,2 + x_goat,2 <= 1 ...
Use an upper bound for t, such that a solution is surely possible.
Finally, introduce the binary variable z_t and let
z_t <= 1/3 (x_wolf,t + x_cabbage,t + x_goat,t)
and maximize sum_t (z_t).
(Most probably sum_t (x_wolf,t + x_cabbage,t + x_goat,t) shold work too.)
You are right that this formulation will require integer variables. The traditional way of solving a problem like this would be to formulate a binary variable model and pass the formulation onto a solver. MATLAB in this case would not work unless you have access to the Optimization Toolbox.
http://www.mathworks.com/products/optimization/index.html
In your formulation you would need to address the following:
Decision Variables
In your case this would look something like:
x_it (choose [yes=1 no=0] to transport item i during boat trip number t)
Objective Function
I'm not quite sure what this is from your description but there should be a cost, c_t, associated with each boat trip. If you want to minimize total time, each trip would have a constant cost of 1. So your objective should look something like:
minimize SUM((i,t),c_t*x_it) (so you are minimizing the total cost over all trips)
Constraints
This is the tricky part for your problem. The complicating constraint is the exclusivity that you identified. Remember, x_it is binary.
For each pair of items (i1,i2) that conflict with each other you have a constraint that looks like this
x_(i1 t) + x_(i2 t) <= 1
For example:
x_("cabbage" "1") + x_("goat" "1") <= 1
x_("wolf" "1") + x_("goat" "1") <= 1
x_("cabbage" "2") + x_("goat" "2") <= 1
x_("wolf" "2") + x_("goat" "2") <= 1
ect.
You see how this prevents conflict. A boat schedule that assigns "cabbage" and "goat" to the same trip will violate this binary exclusivity constraint since "1+1 > 1"
Tools like GAMS,AMPL and GLPK will allow you to express this group of constraints very concisely.
Hope that helps.