Maximize based on constraints - minizinc

3 Arrays f1,f2 and f3 have child elements (f1a,f1b) ; (f2a,f2b,f2c) ; (f3a,f3b,f3c,f3d) respectively.They are all bool variables
I have a combination of these child elements in a list with 2 columns . The first column gives an ID and second col has the combination of child elements as shown below
row1 : 2345 | f1a , f2b
row2 : 2345 | f1a,f2a,f3c
row3 : 2346 | f2c, f3a
row4 : 2347 | f1b, f2c
.... ....
I need to choose one element of each of the arrays and form a selected array
if all elements of row are represented in selected array, I set 1 for that Row , else 0
So if selected array is [ f1a,f2a,f3c] , then ( using the above list example)
row1 is 0 ( as f2b is not in selected array)
row2 is 1 as all elements of row are in selected list
row3 is 0 as f2c and f3a is not in selected array
row4 is 0 as f2c is not present in selected array
I need to choose the selected array so as to maximize the sum of Row count (0+1+0+0 ...) for all Unique ID
for example if list is as shown below and selected array is [f1a,f2b,f3c] , though both rows are set 1 ,
I would only take 1 from both the rows as ID is same in both rows
row1 : 2345 | f1a , f2b
row2 : 2345 | f1a,f2b,f3c
Any help is appreciated as I am new to Minizinc and struggling to formulate the constraint with Minizinc

If your row variables are themselves also located in an array, then
solve maximize sum(row);
should set the activation of the rows to be the objective.
If you don't have them in an array you can still manually add them together to form an objective:
solve maximize row1 + row2 + row3 + row4;
I'm unsure if you were also asking about how the row activation itself works, but if a row only activates when all its elements are selected, then this would be enforced using a simple forall constraint:
constraint row1 = forall([...]);

I could finally get it working with this code. Here row1 and row2 have same ID and similarly row 3 and row4 have another common ID
array[1..2] of var bool: f1 ;
array[1..2] of var bool: f1 ;
array[1..3] of var bool: f2 ;
array[1..4] of var bool: f3 ;
var bool: row1;
var bool: row2 ;
var bool: row3 ;
var bool: row4 ;
constraint sum(f1) == 1;
constraint sum(f2) == 1;
constraint sum(f3) == 1;
constraint row1 = forall ( [(f1[1]) ] ) ;
constraint row2 = forall ( [(f1[2]) , (f2[2]) , (f3[3]) ] );
constraint row3 = forall ( [(f1[1]) , (f2[2]) , (f3[3]) ] ) ;
constraint row4 = forall ( [(f1[2]) , (f2[1]) , (f3[4]) ] ) ;
var int: rown1 = bool2int(row1) ;
var int: rown2 = bool2int(row2) ;
var int: rown2a = max(rown1,rown2) ;
var int: rown3 = bool2int(row3) ;
var int: rown4 = bool2int(row4) ;
var int: rown4a = max( rown3,rown4) ;
var int: rown = rown2a + rown4a ;
solve maximize rown;

Related

MiniZinc: build a connectivity matrix

In MiniZinc, I have an array of boolean representing an oriented connection between nodes of a graph:
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf;
VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
now I want to build
array[Variants,Variants] of bool VariantIsUpwardOf;
where VariantIsUpwardOf[v1,v2] = true if there is an oriented path "v1 -> ... -> v2" where "..." is a sequence of nodes defining an oriented path of any length going from v1 to v2.
My first try was to define a transitive kind of constraint
array[Variants,Variants] of var bool : VariantIsUpwardOf;
constraint forall (v1 in Variants, v2 in Variants)(VariantIsDirectlyUpwardOf[v1,v2]->VariantIsUpwardOf[v1,v2]);
constraint forall (v1 in Variants, v2 in Variants, v3 in Variants)( VariantIsUpwardOf[v1,v2] /\ VariantIsUpwardOf[v2,v3] -> VariantIsUpwardOf[v1,v3]);
but I think this is incorrect because if all values of VariantIsUpwardOf[v1,v2] were true, then my constraints would be satisfied and the result would be incorrect.
Following the comment (thanks Axel), I made a second unsuccessful test using predicate dpath, here is my very basic test calling dpath::
include "path.mzn";
enum MyNodes={N1,N2};
array [int] of MyNodes: EdgeFrom=[N1];
array [int] of MyNodes: EdgeTo= [N2];
array [MyNodes] of bool: NodesInSubGraph = [true, true];
array [int] of bool: EdgesInSubGraph = [true];
var bool : MyTest = dpath(EdgeFrom,EdgeTo,N1,N2,NodesInSubGraph,EdgesInSubGraph);
output [show(MyTest)];
it produces the following error:
Running MiniTest.mzn
221msec
fzn_dpath_enum_reif:3.3-52
in call 'abort'
MiniZinc: evaluation error: Abort: Reified dpath constraint is not supported
Process finished with non-zero exit code 1.
Finished in 221msec.
The following MiniZinc model demonstrates the usage of the dpath() predicate to find a directed path in a graph.
I took the directed graph from Wikipedia as example:
The model:
include "globals.mzn";
int: Nodes = 4;
bool: T = true; % abbreviate typing
bool: F = false;
set of int: Variants = 1..Nodes;
% VariantIsDirectlyUpwardOf[v1,v2] = true if there is an oriented arc "v1 -> v2".
% Example from https://en.wikipedia.org/wiki/Directed_graph
array[Variants,Variants] of bool : VariantIsDirectlyUpwardOf =
[| F, T, T, F,
| F, F, F, F,
| F, T, F, T,
| F, F, T, F |];
% count the number of Edges as 2D array sum
int: NoOfEdges = sum(VariantIsDirectlyUpwardOf);
set of int: Edges = 1..NoOfEdges;
% for dpath(), the graph has to be represented as two
% 'from' 'to' arrays of Nodes
% cf. https://www.minizinc.org/doc-2.6.4/en/lib-globals-graph.html
array[Edges] of Variants: fromNodes =
[row | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
array[Edges] of Variants: toNodes =
[col | row in Variants, col in Variants
where VariantIsDirectlyUpwardOf[row, col]];
% arbitrary choice of Nodes to be connected by a directed path
Variants: sourceNode = 4;
Variants: destNode = 2;
% decision variables as result of the path search
array[Variants] of var bool: nodesInPath;
array[Edges] of var bool: edgesInPath;
constraint dpath(fromNodes, toNodes, sourceNode, destNode, nodesInPath, edgesInPath);
% determine next node after nd in path
function int: successor(int: nd) =
min([s | s in Variants, e in Edges where
fix(nodesInPath[s]) /\ fix(edgesInPath[e]) /\
(fromNodes[e] = nd) /\ (toNodes[e] = s)]);
function string: showPath(int: nd) =
if nd = destNode then "\(nd)" else "\(nd)->" ++ showPath(successor(nd)) endif;
output [showPath(sourceNode)];
Resulting output:
4->3->2

Talend - split a string to n rows

I would like to split a string in a column to n rows in Talend.
For example :
column
2aabbccdd
The first number is the "n" which I use to define the row lenght, so the expected result should be :
row 1 = aa
row 2 = bb
row 3 = cc
row 4 = dd
The idea here is to iterate on the string and cut it every 2 characters.
Any idea please ?
I would use a tJavaFlex to split the string, with a trick to have n rows coming out of it.
tJavaFlex's main code:
int n = Integer.parseInt(row1.str.substring(0, 4)); //get n from the first 4 characters
String str2 = row1.str.substring(4); //get the string after n
int nbParts = (str2.length() + 1) / n;
System.out.println("number of parts = " + nbParts);
for (int i = 0; i < nbParts; i++)
{
String part = str2.substring(i * n);
if(part.length() > n)
{
part = part.substring(0, n);
}
row2.str = part;
And tJavaFlex's end code is just a closing brace:
}
The trick is to use a for loop in the main code, but only close it in the end code.
tFixedFlowInput contains just one column holding the input string.

PowerBI Cumulative Distinctcount by Date, Condition and through Dimension

I have the following Table:
It represents cases on which a certain Team is working on over the Time until the case is closed.
And there is also a Date Table over column Date.
I would like to cumulative count the open cases until the selected date.
So I used this measure:
CountOpen =
VAR CurrentDate = MAX('Date'[Date])
VAR Closed =
CALCULATE(
DISTINCTCOUNT(Tabelle1[case]),
ALL('Date'),'Date'[Date]<=CurrentDate,Tabelle1[Status_Open]="0")
VAR OpenAll =
CALCULATE(
DISTINCTCOUNT(Tabelle1[case]),
ALL('Date'),'Date'[Date]<=CurrentDate,Tabelle1[Status_Open]="1")
RETURN OpenAll-Closed
And it works for the overall view. But for the view within the Dimension CurrentTeam it's not correct:
It should be:
a = 0
b = 1
c = 0
So... this is actually quite tricky, you have to pick the latest status per case up to the selected date. In my solution I create a table, with a column R which ranks the cases per date, then in the result I filter for those depending on which team you have selected.
Measure is below:
VAR CurrentDate = MAX('Date'[Date])
VAR CurrentTeam = SELECTEDVALUE(Tabelle1[CurrentTeam])
VAR tbl =
SUMMARIZE(
FILTER(ALL('Tabelle1'), 'Tabelle1'[Date] <= CurrentDate),
Tabelle1[case],
Tabelle1[CurrentTeam],
Tabelle1[Status_Open],
Tabelle1[Date],
"R",
VAR c = MAX(Tabelle1[case])
VAR d = LASTDATE(Tabelle1[Date])
RETURN
CALCULATE(DISTINCTCOUNT(Tabelle1[Date]),
ALLSELECTED(Tabelle1),
Tabelle1[case] = c,
Tabelle1[Date] >= d)
)
RETURN SUMX(
FILTER(tbl,
[R] = 1 &&
(ISBLANK(CurrentTeam) || [CurrentTeam] = CurrentTeam) &&
[Status_Open])
, 1) + 0 //+0 is here to show 0 where it would be blank

remove duplicates in a table (rexx language)

I have a question about removing duplicates in a table (rexx language), I am on netphantom applications that are using the rexx language.
I need a sample on how to remove the duplicates in a table.
I do have a thoughts on how to do it though, like using two loops for these two tables which are A and B, but I am not familiar with this.
My situation is:
rc = PanlistInsertData('A',0,SAMPLE)
TABLE A (this table having duplicate data)
123
1
1234
12
123
1234
I need to filter out those duplicates data into TABLE B like this:
123
1234
1
12
You can use lookup stem variables to test if you have already found a value.
This should work (note I have not tested so there could be syntax errors)
no=0;
yes=1
lookup. = no /* initialize the stem to no, not strictly needed */
j=0
do i = 1 to in.0
v = in.i
if lookup.v <> yes then do
j = j + 1
out.j = v
lookup.v = yes
end
end
out.0 = j
You can eliminate the duplicates by :
If InStem first element, Move the element to OutStem Else check all the OutStem elements for the current InStem element
If element is found, Iterate to the next InStem element Else add InStem element to OutStem
Code Snippet :
/*Input Stem - InStem.
Output Stem - OutStem.
Array Counters - I, J, K */
J = 1
DO I = 1 TO InStem.0
IF I = 1 THEN
OutStem.I = InStem.I
ELSE
DO K = 1 TO J
IF (InStem.I ?= OutStem.K) & (K = J) THEN
DO
J = J + 1
OutStem.J = InStem.I
END
ELSE
DO
IF (InStem.I == OutStem.K) THEN
ITERATE I
END
END
END
OutStem.0 = J
Hope this helps.

Summary table using Coffeescript?

I've programmed a summary chart, and I'm trying to add a "Totals" line that will sum up three columns. The exercise is comprised of a number of questions, and the participant can increase, decrease or maintain a certain dollar amount. The column B total shows the initial values (where the slider starts off on). The column C shows the amount the participant either increased or decreased and the last column shows the resulting dollar amount. (B + C)
Here's an example of the summary chart
Column A --- B ------ C------ D
Question 1 | 100$ | +28$ | 128$ |
Question 2 | 150$ | (10$) | 140$ |
Totals ------| 250$ | +18$ | 268$ |
So far I've been able to program the totals for column B and D, but I can't figure out how to show a total for column C.
class window.CustomSimulator extends window.TaxSimulator
constructor: (#options = {}) ->
super
#updateTable()
update: ->
super
#updateTable()
updateTable: ->
self = this
$table = $('<table class="table table-condensed"><thead><tr><th>Category</th><th>Before</th><th>Your Choice</th><th>After</th></tr></table>')
$tbody = $('<tbody></tbody>')
before_total = 0
after_total = 0
#scope.find('.slider').each ->
$this = $(this)
$parents = $this.parents('tr')
category = $parents.find('.header').clone().children().remove().end().text().replace(/How would you adjust service levels and property tax funding for /, '').replace('?', '')
before = self.tipScaler($this, $this.data('initial'))
your_choice = $parents.find('.value').text()
after = $parents.find('.tip-content').text()
if $parents.find('.key').text() == 'Decrease:'
css_class = 'decrease'
your_choice = "(#{your_choice})"
else
css_class = 'increase'
$tr = $("""<tr><td>#{category}</td><td>#{before}</td><td class="table-#{css_class}">#{your_choice}</td><td>#{after}</td></tr>""")
$tbody.append($tr)
before_total += parseFloat(before.replace('$', ''))
after_total += parseFloat(after.replace('$', ''))
before_total = SimulatorHelper.number_to_currency(before_total, precision: 2, strip_insignificant_zeros: true)
after_total = SimulatorHelper.number_to_currency(after_total, precision: 2, strip_insignificant_zeros: true)
$("""<tfoot><tr><th>Totals</th><th>#{before_total}</th></th><th><th>#{after_total}</th></tr></tfoot>""").appendTo($table)
$table.append($tbody)
$('#summary-table').html($table)
I'm pretty new at this so I'm not sure if this is enough information.
Thanks!