The Integrality theorem in maximum flow - bipartite

The integraloty theorem tells us that if all capacities in a flow network are integers, then there is a maximum flow where every value is an integer
But the most remarkable part is the existence, not every maximum flow!
Which means this statement doesn't claim every maximum flow is integer-valued
I cannot figure out why if all capacities are integer, but there exists a maximum flow is not integer-valued!!
Or did I just get wrong idea of this theorem that tries to tell me?

Let
e = edge in the graph.
c(e) = capacity of the given edge e
f(e) = amount of flow going through given edge e
The theorem states:
If c(e) for all edges, e, in graph are integers, then there exists a max flow
f for which every flow value f(e) is an integer.
Notice the theorem does not place constraint on f(e).
Only c(e) must be integer.
Since "c(e) must be integer" does not imply "f(e) must be integer" as well.
Therefore it is perfectly valid to have non-integer flow with integer capacity.
Here is an example where all capacities are integer with a maximum flow that has some edges that has non-integer flow..
G is the flow Graph I am working with..
N is a maximum integral flow..
N` is a maximum flow where it has some edges has non-integer flow..
pair number on edges are of format: "flow/capacity"
Remember the theorem only says the upper bound of f(u,v) are integers.. it does not say anything about its lower bound.. therefore flow can be any number between 0 and c(u,v)..

If using Ford-Fulkerson method to get a maximum flow, then the resulted flow must be integer-valued
But, we still can have a maximum flow that use real number as the flow value on the edges
Check this example:
B
/ \
/ \
/ \
s------A      t
\ /
\ /
\ /
C
the directions of edges all go from left to right , and the (s,a) has 1 flow and 1 capacity,
and rest of all all go with 0.5 flow and 1 capacity.
This is flow network having a maximum flow but not integer-valued.

Related

Difference of quasiconcave functions has unknown curvature (CVXPY)

I am attempting to model an allocation problem via (quasi)convex optimization: given a matrix of unknowns X containing the amount of a certain product in a certain moment and its value C, i want to maximize the resulting income cp.sum(cp.multiply(X, C)).
Among close/equivalent solutions, i want to have the least amount of different products types in inventary, - cp.sum(cp.maximum(0, cp.sign(X)), which counts the number of non-null entries in X as a penalty.
According to cvxpy, both functions are quasiconcave (the first is affine, and the second quasilinear), but when i compose them linearly, cp.sum(cp.multiply(X, C)) - cp.sum(cp.maximum(0, cp.sign(X)), the resulting problem has an UNKNOWN curvature, and refuses to solve since not 'DQCP'.
The problem is simplified, as there are additional parameters and weights, and in the constrains X is bound to be non-negative and to satisfy space availability, but this simple version reproduces this unexpected behavior.
Is the bug in cvxpy or in my math?
The difference of two quasiconcave functions is not necessarily quasiconcave, so this operation is not permitted in CVXPY.

How to scale % change based features so that they are viewed "similarly" by the model

I have some features that are zero-centered values and supposed to represent change between a current value and previous value. Generally speaking i believe there should be some symmetry between these values. Ie. there should be roughly the same amount of positive values as negative values and roughly these values should operate on the same scale.
When i try to scale my samples using MaxAbsScaler, i notice that my negative values for this feature get almost completely drowned out by the positive values. And i don't really have any reason to believe my positive values should be that much larger than my negative values.
So what i've noticed is that fundamentally, the magnitude of percentage change values are not symmetrical in scale. For example if i have a value that goes from 50 to 200, that would result in a 300.0% change. If i have a value that goes from 200 to 50 that would result in a -75.0% change. I get there is a reason for this, but in terms of my feature, i don't see a reason why a change of 50 to 100 should be 3x+ more "important" than the same change in value but the opposite direction.
Given this information, i do not believe there would be any reason to want my model to treat a change of 200-50 as a "lesser" change than a change of 50-200. Since i am trying to represent the change of a value over time, i want to abstract this pattern so that my model can "visualize" the change of a value over time that same way a person would.
Right now i am solving this by using this formula
if curr > prev:
return curr / prev - 1
else:
return (prev / curr - 1) * -1
And this does seem to treat changes in value, similarly regardless of the direction. Ie from the example of above 50>200 = 300, 200>50 = -300. Is there a reason why i shouldn't be doing this? Does this accomplish my goal? Has anyone ran into similar dilemmas?
This is a discussion question and it's difficult to know the right answer to it without knowing the physical relevance of your feature. You are calculating a percentage change, and a percent change is dependent on the original value. I am not a big fan of a custom formula only to make percent change symmetric since it adds a layer of complexity when it is unnecessary in my opinion.
If you want change to be symmetric, you can try direct difference or factor change. There's nothing to suggest that difference or factor change are less correct than percent change. So, depending on the physical relevance of your feature, each of the following symmetric measures would be correct ways to measure change -
Difference change -> 50 to 200 yields 150, 200 to 50 yields -150
Factor change with logarithm -> 50 to 200 yields log(4), 200 to 50 yields log(1/4) = -log(4)
You're having trouble because you haven't brought the abstract questions into your paradigm.
"... my model can "visualize" ... same way a person would."
In this paradigm, you need a metric for "same way". There is no such empirical standard. You've dropped both of the simple standards -- relative error and absolute error -- and you posit some inherently "normal" standard that doesn't exist.
Yes, we run into these dilemmas: choosing a success metric. You've chosen a classic example from "How To Lie With Statistics"; depending on the choice of starting and finishing proportions and the error metric, you can "prove" all sorts of things.
This brings us to your central question:
Does this accomplish my goal?
We don't know. First of all, you haven't given us your actual goal. Rather, you've given us an indefinite description and a single example of two data points. Second, you're asking the wrong entity. Make your changes, run the model on your data set, and examine the properties of the resulting predictions. Do those properties satisfy your desired end result?
For instance, given your posted data points, (200, 50) and (50, 200), how would other examples fit in, such as (1, 4), (1000, 10), etc.? If you're simply training on the proportion of change over the full range of values involved in that transaction, your proposal is just what you need: use the higher value as the basis. Since you didn't post any representative data, we have no idea what sort of distribution you have.

how to set a pattern in a variable using Z3Py

I'm pretty new in Z3, but a thing that my problem could be resolved with it.
I have two variables A and B and two pattern like this:
pattern_1: 1010x11x
pattern_2: x0x01111
where 1 and 0 are the bits zero and one, and x (dont care) cold be the bit 0 or 1.
I would like to use Z3Py for check if A with the pattern_1 and B with the pattern_2 can be true at the same time.
In this case if A = 10101111 and B = 10101111 than A and B cold be true ate the same time.
Can anyone help me with this?? It is possible resolve this with Z3Py
revised answer after clarification
Here's one way you could represent those constraints. There is an operation called Extract that can be applied to bit-vector terms. It is defined as follows:
def Extract(high, low, a):
"""Create a Z3 bit-vector extraction expression."""
where high is the high bit to be extracted, low is the low bit to be extracted, and a is the bitvector. This function represents the bits of a between high and low, inclusive.
Using the Extract function you can constrain each bit of whatever term you want to check so that it matches the pattern. For example, if the seventh bit of D must be a 1, then you can write s.add(Extract(7, 7, D) == 1). Repeat this for each bit in a pattern that isn't an x.

How to effectively use the Levenshtein algorithm for text auto-completion

I'm using the Levenshtein distance algorithm to filter through some text in order to determine the best matching result for the purpose of text field auto-completion (and top 5 best results).
Currently, I have an array of strings, and apply the algorithm to each one in an attempt to determine how close of a match it is to the text which was typed by the user. The problem is that I'm not too sure how to interpret the values outputted by the algorithm to effectively rank the results as expected.
For example: (Text typed = "nvmb")
Result: "game" ; levenshtein distance = 3 (best match)
Result: "number the stars" ; levenshtein distance = 13 (second best match)
This technically makes sense; the second result needs many more 'edits', because of it's length. The problem is that the second result is logically and visually a much closer match than the first one. It's almost as if I should ignore any characters longer than the length of the typed text.
Any ideas on how I could achieve this?
Levenshtein distance itself is good for correcting query, not for auto-completion.
I can propose alternative solution:
First, store your strings in prefix tree instead of array, so you will have no need to analyze all of them.
Second, given user input enumerate strings with fixed distance from it and suggest completions for any.
Your example: Text typed = "nvmb"
Distance is 0, no completions
Enumerate strings with distance 1
Only "numb" will have some completions
Another example:Text typed="gamb"
For distance 0 you have only one completion, "gambling", make it first suggestion, and continue to get 4 more
For distance 1 you will get "game" and some completions for it
Of course, this approach sometimes gives more than 5 results, but you can order them by another criterion, not depending on current query.
I think it is more efficient because typically you can limit distance with at maximum two, i.e. check order of 1000*n prefixes, where n is length of input, most times less than number of stored strings.
The Levenshtein distance corresponds to the number of single-character insertions, deletions and substitutions in an optimal global pairwise alignment of two sequences if the gap and mismatch costs are all 1.
The Needleman-Wunsch DP algorithm will find such an alignment, in addition to its score (it's essentially the same DP algorithm as the one used to calculate the Levenshtein distance, but with the option to weight gaps, and mismatches between any given pair of characters, arbitrarily). But there are more general models of alignment that allow reduced penalties for gaps at the start or the end (and reduced penalties for contiguous blocks of gaps, which may also be useful here, although it doesn't directly answer the question). At one extreme, you have local alignment, which is where you pay no penalty at all for gaps at the ends -- this is computed by the Smith-Waterman DP algorithm. I think what you want here is in-between: You want to penalise gaps at the start of both the query and test strings, and gaps in the test string at the end, but not gaps in the query string at the end. That way, trailing mismatches cost nothing, and the costs will look like:
Query: nvmb
Costs: 0100000000000000 = 1 in total
Against: number the stars
Query: nvmb
Costs: 1101 = 3 in total
Against: game
Query: number the stars
Costs: 0100111111111111 = 13 in total
Against: nvmb
Query: ber star
Costs: 1110001111100000 = 8 in total
Against: number the stars
Query: some numbor
Costs: 111110000100000000000 = 6 in total
Against: number the stars
(In fact you might want to give trailing mismatches a small nonzero penalty, so that an exact match is always preferred to a prefix-only match.)
The Algorithm
Suppose the query string A has length n, and the string B that you are testing against has length m. Let d[i][j] be the DP table value at (i, j) -- that is, the cost of an optimal alignment of the length-i prefix of A with the length-j prefix of B. If you go with a zero penalty for trailing mismatches, you only need to modify the NW algorithm in a very simple way: instead of calculating and returning the DP table value d[n][m], you just need to calculate the table as before, and find the minimum of any d[n][j], for 0 <= j <= m. This corresponds to the best match of the query string against any prefix of the test string.

Does a Given Network has a Unique Min-Cut?

Let G = (V, E) be a network with s and t being the source and the sink. Let f be a maximum flow in G. Find an algorithm that determines whether there exists a unique min-cut in G.
I have managed to find a similar question on this site:
Determining the uniqueness of a min-cut
A summary of the answer given there:
Find all the vertices reachable from s in the residual graph and we've found a min-cut (S,T) in G.
Look at the same residual graph, starting at t. Look at the group of vertices reachable from t in the reverse direction of the arrows (meaning all the vertices which can reach t).
This group is also a min-cut.
If that cut is identical to your original cut, then there is only one. Otherwise, you just found 2 cuts, so the original one can't possibly be unique.
I don't understand why if the cut is identical to the original cut then the cut is unique.
Who can promise us that there is no other min-cut ?
Thanks in advance
Actually, I don't quite understand that solution. But in the original question, the second answer provided by davin is absolutely correct.
I just copy and paste it here
Given a minimum S-T cut, (U,V) with cut-edges E', we make one simple observation:
If this minimum cut is not unique, then there exists some other minimum cut with
a set of cut-edges E'', such that E'' != E'.
If so, we can iterate over each edge in E', add to its capacity, recalculate the
max flow, and check if it increased.
As a result of the observation above, there exists an edge in E' that when
increased, the max flow doesn't increase iff the original cut is not unique.
some explanation of my own:
What you need to prove actually is
there exists an edge in E' that when increased, the max flow doesn't increase
<=>
the original cut is not unique
=>:
You increase the capacity of edge e by 1, calculate the new max flow and it remains the same, which means that e is not in the new min-cut. (if e is in, according to the property of min-cut, f(e)=capacity of e, which leads to an increase). Since e is not in the new min-cut, it is also a min-cut of the original graph which has the same volume with the cut we know.Thus, the original cut is not unique.
<=:
The original cut is not unique(Let's call them E and E'), which means you can find an edge e that is in E but not in E'. Then you just increase the capacity of e by 1. When calculating the min-cut of the new graph, E' is already there. Since E' doesn't contain edge e, max flow remains the same with no doubt.
Hope you understand :)
another option to prove by contradiction the first way:
->:
let's say there's a single minimal (S,T) cut with cut edges E'.
After increasing the capacity of edge e which belongs to E' by 1 and finding that the max flow remains the same, leads that e is not in the new min-cut. (if e is in E', according to the property of min-cut the max flow would be increased).
However at the beginning we said the e is in E' - contradiction
The algorithm that you talked about is more efficient than the suggested ones.
The algorithm:
For graph G=(V,E)
Find maximum flow in the graph, and let R be the last residual graph.
Run BFS from s (find nodes reachable from s), lets call them X
Run BFS from t with reversed edges (find nodes that there is a path to t), lets call them Y.
if X + Y = V ('+' as in union) return TRUE, else FALSE
A short explanation:
in step 2 we find the nodes that determine the minimum cut (X, V/X).X is the set of all nodes reachable from s in our last residual graph. In step 3 we find the set of nodes from which t is reachable in the last residual graph. This set defines the cut (V-Y,Y) which is the minimum-cut closest to t. In step 4, is go the same cut from both ends (X + Y = V), then the graph has a unique minimum cut.
The complexity is mainly finding the maximum flow. With Edmonds Karp O(|E|^2|V|), and BFS O(|E| + |V|).
The complexity of the suggested answer will be O(|V||E|^3).
So far, all discussion of the algorithm presented in the original post (both here an d in the post from which it is copied) seem to stop short of actually proving that if the two minimum cuts are the same, then it is the unique minimum cut. But this isn't hard!
OK, so what are these two minimum cuts? We run a maximum flow algorithm and look at the residual graph. The first cut is (S,T=V-S) where S is the set of all nodes that can be reached from the source using only edges with residual capacity. The second cut is (V-T,T) where T is the set of all nodes that can reach the sink using only edges with residual capacity.
If these two cuts are different, then clearly there is more than one minimal cut. But if they are the same, then we can use the technique described by laike9m to show that this is the only minimum cut. Why? Well, by the definitions of S and T in the previous paragraph, each edge e=(v0->v1) in the cut comes with a path s->v0 and a path v1->t that have residual capacity. Thus, if we increase the capacity of e, we know that we will increase the maximum flow. Since this is true for every edge e in the cut, this means that this minimum cut is unique.

Resources