I'm trying to model this constraint in GMPL.
As far as I can understand, j:dij < Dk part means " all the 'j's which satisfies the property dij < Dk "
I'm pretty new to it so I couldn't manage to model it correctly. Any suggestions?
Ok, did it this way:
s.t. c3{i in N, k in K} : z[k] + sum{j in M : d[i,j] < b[k]} y[j] >= 1;
"b" is used in case of "D".
Related
I have a question ,what is the meaning of "range( i + 1 )" below ,if I want to show the output which has xyyzzz?
a = ("x", "y", "z")
for i in range(len(a)):
for j in range( i + 1):
print(a[i])
output: x
y
y
z
z
z
I tried to explain this to you with values
i = 0 ---> j = range(1) = 0 : a[0] = x
--------------------------------
i = 1 ----> j =range(2) = (0,1) : a[1] = y
: a[1] = y
-----------------------------------------
i = 2 ----> j = range(3) = (0,1,2) : a[2] = z
: a[2] = z
: a[2] = z
range(n) gives you values from 0 to n-1.
If you are unfamiliar with Python currently, this can be represented in different ways:
In mathematical interval notation, you can represent this as [0,n) . The left value is included, and the right one is excluded.
Taking len(a) to be 3, the above for loops would be written in C as:
for (int i = 0 ; i < 3 ; ++i){
for (int j = 0 ; j <= i ; ++j){ // note the <= . We can also do j < (i+1)
...
}
}
Your code first calculates len(a), which is 3, since this is a container with 3 elements (this specific container is called a tuple). The first for loop goes from 0 to 2, while the second for loop goes from 0 to wherever the counter of the outer for loop is at (less than or equal to). This causes the first value to be printed just once, next twice, and the last one thrice.
(If you want to test your understanding further, try to figure out what would be printed if we had print(a[j]) inside the loops rather than a[i].)
range() is a versatile and powerful thing in Python, it can do much more than just give you values from 0 to n-1. Do read about it if you intend to use Python.
I'm self-studying problem 32-1 in CLRS; part c), presents the following algorithm for string matching:
REPETITION-MATCHER(P, T)
m = P.length
n = T.length
k = 1 + ρ'(P)
q = 0
s = 0
while s <= n-m
if T[s+q+1] == P[q+1]
q = q+1
if q==m
print "Pattern occurs with shift" s
if q==m or T[s+q+1] != P[q+1]
s = s+max(1, ceil(q/k))
q = 0
Here, ρ'(P), which is a function of P only, is defined as the largest integer r such that some prefix P[1..i] = y^r, e.g. a substring y repeated r times.
This algorithm appears to be 95 percent similar to the naive brute-force string matcher. However, the one part which greatly confuses me, and which seems to be the centerpiece of the entire algorithm, is the second to last line. Here, q is the number of characters of P matched so far. What is the rationale behind ceil(q/k)? It is completely opaque to me. It would have made more sense if that line were something like s = s + max(1+q, 1+i), where i is the length of the prefix that gives rise to ρ'(P).
CLRS claims that this algorithm is due to Galil and Seiferas, but in the reference they provide, I cannot find anything that resembles the algorithm provided above. It appears that reference contains, if anything, a much more advanced version of what is here. Can someone explain this ceil(q/k) value, and/or point me toward a reference that describes this particular algorithm, instead of the more well-known main Galil Seiferas paper?
Example #1:
Match aaaa in aaaaab, here ρ' = 4. Consider state:
aaaa ab
^
We have a mismatch here, and we want to move forward by one symbol, no more, because we will match full pattern again (last line sets q to zero). q = 4 and k = 5, so ceil(q/k) = 1, that's all right.
Example #2: Match abcd.abcd.abcd.X in abcd.abcd.abcd.abcd.X. Consider state:
abcd.abcd.abcd. abcd.X
^
We have a mismatch here, and we would like to move forward by five symbols. q = 15 and k = 4, so ceil(q/k) = 4. That's ok, it is almost 5, we still can match our pattern. Had we bigger ρ', say 10, we would have ceil(50/(10+1)) = 5.
Yeh, algorithms skips forward less symbols than KMP does, in case ρ'=10 its running time is O(10n+m) while KMP has O(n+m).
I figured out the proof of correctness.
let k = ρ'(P) + 1, and ρ'(P) is the largest possible repetition factor out of all the prefixes of P.
Suppose T[s+1..s+q] = P[1..q], and either q=m or T[s+q+1] != P[q+1]
Then, for 1 <= j <= floor(q/k) (except for the case q=m and m mod k = 0, in which the upper limit must be ceil(m/k)), we have
T[s+1..s+j] = P[1..j]
T[s+j+1..s+2j] = P[j+1..2j]
T[s+2j+1..s+3j] = P[2j+1..3j]
...
T[s+(k-1)j+1..s+kj] = P[(k-1)j+1..kj]
where not every quantity on every line is equal, since k cannot be a repetition factor, since the largest possible repetition factor out of any prefix of P is k-1.
Suppose we now make a comparison at shift s' = s+j, so that we will make the following comparisons
T[s+j+1..s+2j] with P[1..j]
T[s+2j+1..s+3j] with P[j+1..2j]
T[s+3j+1..s+4j] with P[2j+1..3j]
...
T[s+kj+1..s+(k+1)j] with P[(k-1)j+1..kj]
We claim that not every comparison can match, e.g. at least one of the above "with"s must be replaced with !=. We prove by contradiction. Suppose every "with" above is replaced by =. Then, comparing to the first set of comparisons we did, we would immediately have the following:
P[1..j] = P[j+1..2j]
P[j+1..2j] = [2j+1..3j]
...
P[(k-2)j+1..(k-1)j] = P[(k-1)j+1..kj]
However, this cannot be true, because k is not a repetition factor, hence a contradiction.
Hence, for any 1 <= j <= floor(q/k), testing a new shift s'=s+j is guaranteed to mismatch.
Hence, the smallest shift that is possible to result in a match is s + floor(q/k) + 1 >= ceil(q/k).
Note the code uses ceil(q/k) for simplicity, solely to deal with the case that q = m and m mod k = 0, in which case k * (floor(q/k)+1) would be greater than m, so only ceil(q/k) would do. However, when q mod k = 0 and q < m, then ceil(q/k) = floor(q/k), so is slightly suboptimal, since that shift is guaranteed to fail, and floor(q/k)+1 is the first shift that has any chance of matching.
We have a number of N digits (it can start with 0). We must find the biggest number which can be obtained cutting K disjoint sequences of length L.
N can be very big so our number should be stored as a string.
Example 1)
nr = 12122212212212121222
K = 2, L = 3
answer: 22212212221222
We can cut "121" (from 0th digit) and "121" (from 12th digit).
Example 2)
nr = 0739276145
K = 3, L = 3
answer: 9
We can cut "073", "276" and "145".
I have tried something like this:
void cut(string str, int K, int L) {
if (K == 0)
return;
// here we cut a single sequence of length L
// in a way that the new number is the biggest
cut(str, K - 1, L);
}
But in this way, I can cut 2 sequences which in the initial number are not disjoint, so my method it's not correct. Please help me solve the problem!
You can define cutsrecursively:
cuts(s, 0, L) = s
cuts(s, K, L) = max(s[i:j] + cuts(s[j+L:], K-1, L) for j=i..len(s)-K*L)
As is normal in these problems, you can use dynamic programming to avoid an exponential runtime. You can probably avoid so much string slicing and appending, but this is an example solution in Python:
def cuts(s, K, L):
dp = [s[i:] for i in xrange(len(s)+1)]
for k in xrange(1, K+1):
dp = [max(s[i:j] + dp[j+L] for j in xrange(i, len(dp)-L))
for i in xrange(len(dp)-L)]
return dp[0]
print cuts('12122212212212121222', 2, 3)
print cuts('0739276145', 3, 3)
Output:
22212212221222
9
Unfortunately I don't know the name of following problem but I am sure that it is well known problem. I want to find effective algorithm to solve problem.
Let S - input string and K - some number (1 <= K <= 26).
Problem is to find longest substring of S, which has only K different characters. What is the best algorithm to solve this problem?
Some examples:
1) S = aaaaabcdef, K = 3, answer = aaaaabc
2) S = acaaba, K = 2, answer = acaa or aaba
3) S = abcde, K = 5, answer = abcde
I have sketch of solution of this problem. But it seems too difficult for me, also it has quadratic complexity. So, in single linear pass I can compute sequent of the same characters by one and appropriated count. Next step is to use set which will contain only K characters. Usage is similar:
std::string max_string;
for (int i = 0; i < s.size(); ++i)
{
std::set<int> my_set;
std::string possible_solution;
for (int j = i; j < s.size(); ++j)
{
// filling set and possible_solution
}
if (my_set.size() == K && possible_solution.size() > max_string.size())
max_string = possible_solution;
}
Notation:
s = input string, zero-based index
[start, end) = substring of input from start to end, including start but excluding end
k-substring = a substring that contains at most k different characters
Algorithm: linear complexity O(n)
start = 0
result = empty string
find max(end): [start, end) is a k-substring
LOOP:
// please note in every loop iteration, [start, end) is a k-substring
update result=[start, end) if (end-start) > length(result)
if end >= length(s) then DONE! EXIT
increase start until [start, end) is a (k-1)-substring
increase end while [start, end] is a k-substring
ENDLOOP
To check if increasing start or end respectively decrease or increase the character pool size (k property), we can use a count[] array, where count[c] = number of occurence of c in the current substring [start, end).
C++ Implementation: http://ideone.com/i2JPCq
The best solution I can come up with is with time complexity O(log(n) * n)) and additional memory complexity O(n). The idea is the following:
First for all 26 characters compute a prefix sum array. For the character C this array has the following property a0 = 0, ai = <number of occurrences of C up to position i>. It is very easy to compute this:
a[0] = 0;
for (int i = 1; i <= n; ++i) {
a[i] = a[i - 1] + (s[i - 1] == C)
}
Now let us assume you have these arrays. It is very easy to compute the number of occurrences of the character C in a closed interval [i, j]. This is precisely a[j + 1] - a[j]. Using this you can also check if C appears somewhere in the interval [i, j] - simply check if the count of the occurrences is greater than 0.
The last part of my solution is to use binary search. For each index i in the string use binary search to identify what is the longest length of substring starting at position i that has no more than K different characters. The complexity of this part of the algorithm is O(n * log(n)).
Since your alphabet consists of only 26 letters, a linear time algorithm can be as follows:
Scan the string from left to right, at each step maintain two separate arrays startIndex[26], endIndex[26].
startIndex[i] = index of first instance of ('a' + i)th letter in the current active substring.
endIndex[i] = index of last instance of ('a' + i)th letter in the current active substring.
You can initialize the arrays elements to be any strange value (like -1) to check their validity during the algorithm.
Also, maintain the maximum length of sub-string obtained so far and the number of current active unique characters.
Algorithm:
1. i = 0.
- Mark the startIndex and endIndex of S[0].
- Initialize maxLength = 1
- Initialize activeChars = 1.
2. for i = 1 to S.size()-1
- if (S[i] != any of the activeChars) // can be done in O(26)
if (activeChars == K)
update maxLength if maxLength < currLength.
remove an active char with least startIndex.
add this new char to startIndex and endIndex
currLength = i - min (remaining active startIndex) + 1
else
activeChars++;
add this S[i] to startIndex and endIndex
currLength++.
update maxLength if maxLength < currLength.
else
update endIndex for S[i].
currLength++.
update maxLength if maxLength < currLength.
3. again update maxLength if maxLength < currLength.
I'll try to modify Abhishek Bansal's algorithm to keep linear complexity and patch the errors that could arise with repeated characters in the active group.
Scan the string from left to right, at each step maintain two separate arrays startIndex[26], endIndex[26], and a map where you associate each char(key) to all its occurencies in the active substring(value).
startIndex[i] = index of first instance of ('a' + i)th letter in the current active substring
endIndex[i] = index of last instance of ('a' + i)th letter in the current active substring.
map.get(i) = list of occurencies in considered substring.
Algorithm:
1. i = 0.
- Mark the startIndex and endIndex of S[0], add the occurency of S[0] to the map.
- Initialize maxLength = 1
- Initialize activeChars = 1.
2. for i = 1 to S.size()-1
- if (S[i] != any of the activeChars) // can be done in O(26)
if (activeChars == K)
update maxLength if maxLength < currLength.
remove the active char with least endIndex.
add this new char to startIndex and endIndex, and to the map with this occurency
remove from the map all the occurencies of all the chars that are previous than removed char's endIndex
update all the startIndex referring to the edited map
currLength = i - min (remaining active startIndex) + 1
else
activeChars++;
add this S[i] to startIndex and endIndex and to the map
currLength++.
update maxLength if maxLength < currLength.
else
update endIndex for S[i], add the occurency to the map.
currLength++.
update maxLength if maxLength < currLength.
3. again update maxLength if maxLength < currLength.
I kept startIndex and endIndex arrays for clarity sake, but you could avoid the extra space and the extra work to update them using the first and the last element of the list of occurencies stored in the map for the key == char C.
#!/bin/python
for i in range(1000): #153
pre = i #pre=153
a =str (i) #a='153'
sum=0
for j in a:
k = int (j) #k=1
q = k*k*k
summ = summ+q
if (pre = summ):
print("Armstorng ",pre)
else
print("not Armstorng ",pre)
if (pre = summ):
That should be a double equals sign because it's a comparison between two values, not a variable assignment.
if (pre == summ):
Also, a couple of (potential) spelling errors: "Armstorng" and "summ". (Unless you intend "sum"/"summ" to be different variables.)