time window constraint are defined by
time_dimension.CumulVar(node).SetRange(time_window[0], time_window[1])
and the time dimension by
routing.AddDimension(evaluator, slack_max, capacity, fix_start_cumul_to_zero, name)
What is the relationship between the allowed values of CumulVar(node) and slack_max? For example, say that the time window is (50,60) and slack is 5. Does that mean that a value of the cumul var of 45 is also admissible, or does the slack relate to values inside the range? Does max_slack=0 mean that the value of the cumul var must be either 50 or 60, in the example above?
Is there a paper or detailed page about the mathematical model that is used my the routing model of or-tools?
For time window constraint, you can see the slack value as waiting time.
From the source code.
// if j == next(i),
// cumuls(j) = cumuls(i) + transits(i) + slacks(i)
src: https://github.com/google/or-tools/blob/d44fb1b423f9d6658c142c041143a4f54b5106d3/ortools/constraint_solver/routing.h#L1356-L1357
e.g. Supposing your are at node A at time 0 aka A(0) and you have B([40,60]) and transit time is T(50). Thus you have:
B(40) < A(0) + T(50) -> means too late to reach the lower bound even with no waiting time.
B(60) = A(0) + T(50) + 10 -> means vehicle can wait at node A up to 10min and still be in time at node B.
Second example: A(0), B([40,60]), T(30):
B(40) = A(0) + T(30) + 10 -> have to wait 10min
B(60) = A(0) + T(30) + 30 -> have to wait 30min
if slack max is 5 this route is forbidden because otherwise vehicle will be at most at node B at 35 = A(0) + T(30) + 5 which is too early
i.e. not in the range [40,60] so for the solver the time windows constraint can't be respected...
note: we can also deduce:
B(40) = A(5) + T(30) + 5
B(60) = A(30) + T(30)
So vehicle must be at node A in range [5,30] to be on time at node B with slack_max = 5.
i.e. With slack max you can limit the maximum waiting time (extra capacity) allowed along the route.
Routing use a "two steps" algorithms.
1) Try to find a first solution an can use various algorithm
cf. https://developers.google.com/optimization/routing/routing_options#first-solution-strategy-options for paper reference
2) Can use a local search to optimize this first solution
again several methods are implemented cf https://developers.google.com/optimization/routing/routing_options#local-search-options
Related
I would like to constrain locations to be served by the same vehicle.
I used capacity-constraints for achieving this. Say we have l = [[1,2], [3,4]] which means that location 1, 2 must be served by the same vehicle and 3, 4 as well. So 1, 2 ends up on route_1 and 3, 4 on route_2
My code for achieving this is:
for idx, route_constraint in enumerate(l):
vehicle_capacities = [0] * NUM_VEHICLES
vehicle_capacities[idx] = len(route_constraint)
route_dimension_name = 'Same_Route_' + str(idx)
def callback(from_index):
from_node = manager.IndexToNode(from_index)
return 1 if from_node in route_constraint else 0
same_routes_callback_index = routing.RegisterUnaryTransitCallback(callback)
routing.AddDimensionWithVehicleCapacity(
same_routes_callback_index,
0, # null capacity slack
vehicle_capacities, # vehicle maximum capacities
True, # start cumul to zero
route_dimension_name)
The idea is that 1,2 have a capacity demand of each 1 unit (all others have zero). As only vehicle 1 has a capacity of 2 it is the only one able to serve 1,2.
This seems to work fine if len(l) == 1. If greater the solver is not able to find a solution if though I put into l pairs of locations which were on the same route without the above code (hence without the above capacity constraints.
Is there a more elegant way to model my requirement?
Why does the solver fail to find a solution?
I have also considered the possibility of dropping visits (at a high cost) to give the solver the possibility to start from a solution which drops visits such that it will find his way fro this point to a solution without any drops. I had no luck.
Thanks in advance.
Each stop has a vehicle var whose values determine what vehicle is allowed to visit the stop. If you want to have stops 1 and 2 serviced by vehicle 0 use a member constraint on the vehicle var of each stop and set it to [0]. Since you might have other constraints that make stops optional add the value -1 to the list. It is a special value that indicates that the stop is not serviced by a vehicle.
In Python:
n2x = index_manager.NodeToIndex
cpsolver = routing_model.solver()
for stop in [1,2]:
vehicle_var = routing_model.VehicleVar(n2x(stop))
values = [-1, 0]
cpsolver.Add(cpsolver.MemberCt(vehicle_var, values))
Now initially it seemed that it should be O(Nlog(N)) , where N is the number of elements in the heap but, assuming worst case, it will take log(N) time to sift each elements until N/2 nodes have been popped (Since that would mean that the height of heap has been reduced by one) , and then it will take log(N)-1 time to sift each element until N/4 nodes have been popped
Therefore it becomes a series like
N/2*(log(N)) + N/4*(log(N)-1) + N/8*(log(N)-1) + ... N/(2^(log(N))*(log(N) - Height of Heap)
Where the last term is basically N/N * 0 - 0
I cant figure out the sum of this series, I tried integrating it in its standard form integral of N*(log(N) - x)/2^(x+1)dx , limits 0 to log(N) but wolfram gave me a complicated answer
If you have n items in a heap, then popping the root item has a worst case complexity of log(n). You then have n-1 items on the heap, and complexity of popping the root item is log(n-1). So the series you want to sum is:
log(n) + log(n-1) + log(n-2) + log(n-3) + ... + log(n-n+1)
Or, easier to understand:
log(1) + log(2) + log(3) + ... + log(n)
https://stackoverflow.com/a/21152768/56778 explains how that is O(n log n), as well as Θ(n log n).
Alternately, log(a) + log(b) is equal to log(a*b). So the summation of logs from 1 to n is equal to log(n!). See https://math.stackexchange.com/questions/589027/whats-the-formula-to-solve-summation-of-logarithms
See also Is log(n!) = Θ(n·log(n))?
I need to construct a loop (simulation) that will iterate a certain number of times and display a value of warrant once the new firm value is close to the guess firm value. Specifically, the idea is to start out with a guess for the firm value (for example the stock price multiplied by the number of shares). Then you value the warrant as a call option (the code below) on this value multiplied by dilution factor, using the same volatility as the vol of the share price. You recompute then the value of the firm (number of shares times share price plus number of warrants times warrant price). This value will be different from the value of the firm you started with. Then you redo the procedure and after a few iterations you will see that the difference in values of the firm tends to zero. For this, I have a following code, but what I get is the following:
TypeError: 'int' object is not subscriptable
Please, help me to figure out the error given the code below:
def bsm_call_value(S0, K, T, r, sigma):
from math import log, sqrt, exp
from scipy import stats
S0 = float(S0)
d1 = (log(S0 / K) + (r + 0.5 * sigma ** 2) * T) / (sigma * sqrt(T))
d2 = (log(S0 / K) + (r - 0.5 * sigma ** 2) * T) / (sigma * sqrt(T))
value = (S0 * stats.norm.cdf(d1, 0.0, 1.0) - K * exp(-r * T) *stats.norm.cdf(d2, 0.0, 1.0))
return value
def warrant_1unobservable(S0, K, T, r, sigma, k, N, M, Iteration):
for i in range(1, Iteration):
Guess_FirmValue = S0*N
dilution = N/(N +k*M)
warrant[i] = bsm_call_value(Guess_FirmValue[i]/N,100,1,0.1,0.2)*dilution
New_FirmValue[i] = Guess_FirmValue[i]+ warrant[i]
Guess_FirmValue[i] - New_FirmValue[i] == 0
return warrant
print(warrant_1unobservable(100,100,1,0.1,0.2,1,100,10, 1000))
I'm not really a python expert and I'm not familiar with the algorithm you're using, but I'll point out a few things that could be causing the issue.
1) In warrant_1observable, you first assign Guess_FirmValue a scalar value (since both S0 and N are scalars the way you call the function), and then you try to access it with an index as Guess_FirmValue[i]. My guess would be that this is causing the error you displayed, since you're trying to index/subscript a variable that, based on your function input values, would be an integer.
2) Both warrant[i] and New_FirmValue[i] are attempts to assign values to an indexed position in a list, but nowhere do you initialize these variables as lists. Lists in python are initialized as warrant = []. Also, it's likely that you would have to either a) pre-allocate the lists to the correct size based on the Iteration or b) use append to push new values onto the back of the list.
3) Guess_FirmValue[i] - New_FirmValue[i] == 0 is a vacuous line of code. All this does is evaluate to either true or false, while performing no other operation. I imagine you're trying to check if the values are equal and then return, but that won't happen even if you stick this in an if statement. It is extremely unlikely that the floating-point representation of the values will ever be identical. This kind of break is accomplished by checking if the difference of the values is below some tolerance, which is set to be a very small number. Ex.:
if (abs(Guess_FirmValue[i] - New_FirmValue[i]) <= 1e-9):
return ...
Lets say i have a counter, and wish it to increment as many times as their are 100s in 500; so 5
i have
saleAmount = 200
points = 0
amount = 100
SaleTotal = saleAmount
for amount in str(SaleTotal):
points = points + 1
print(points)
but it seems to give the wrong answer all the time of 3 points rather than 2, any advice would be appreciated, i also need it to only count 2 lots of 100 if i enter say 240.
If I understand correctly your problem you need the operator / . This way you can obtain the integer of a division
saleAmount = 200
points = 0
amount = 100
SaleTotal = saleAmount
number_lots = SaleTotal / amount
for lots in range(number_lots)
points += 1
This will work for your cases
Consider the following piece of C++ code:
string s = "a";
for (int i = 0; i < n; i++) {
s = s + s; // Concatenate s with itself.
}
Usually, when analyzing the time complexity of a piece of code, we would determine how much work the inner loop does, then multiply it by the number of times the outer loop runs. However, in this case, the amount of work done by the inner loop varies from iteration to iteration, since the string being built up gets longer and longer.
How would you analyze this code to get the big-O time complexity?
The time complexity of this function is Θ(2n). To see why this is, let's look at what the function does, then see how to analyze it.
For starters, let's trace through the loop for n = 3. Before iteration 0, the string s is the string "a". Iteration 0 doubles the length of s to make s = "aa". Iteration 1 doubles the length of s to make s = "aaaa". Iteration 2 then doubles the length of s to make s = "aaaaaaaa".
If you'll notice, after k iterations of the loop, the length of the string s is 2k. This means that each iteration of the loop will take longer and longer to complete, because it will take more and more work to concatenate the string s with itself. Specifically, the kth iteration of the loop will take time Θ(2k) to complete, because the loop iteration constructs a string of size 2k+1.
One way that we could analyze this function would be to multiply the worst-case time complexity of the inner loop by the number of loop iterations. Since each loop iteration takes time O(2n) to finish and there are n loop iterations, we would get that this code takes time O(n · 2n) to finish.
However, it turns out that this analysis is not very good, and in fact will overestimate the time complexity of this code. It is indeed true that this code runs in time O(n · 2n), but remember that big-O notation gives an upper bound on the runtime of a piece of code. This means that the growth rate of this code's runtime is no greater than the growth rate of n · 2n, but it doesn't mean that this is a precise bound. In fact, if we look at the code more precisely, we can get a better bound.
Let's begin by trying to do some better accounting for the work done. The work in this loop can be split apart into two smaller pieces:
The work done in the header of the loop, which increments i and tests whether the loop is done.
The work done in the body of the loop, which concatenates the string with itself.
Here, when accounting for the work in these two spots, we will account for the total amount of work done across all iterations, not just in one iteration.
Let's look at the first of these - the work done by the loop header. This will run exactly n times. Each time, this part of the code will do only O(1) work incrementing i, testing it against n, and deciding whether to continue with the loop. Therefore, the total work done here is Θ(n).
Now let's look at the loop body. As we saw before, iteration k creates a string of length 2k+1 on iteration k, which takes time roughly 2k+1. If we sum this up across all iterations, we get that the work done is (roughly speaking)
21 + 22 + 23 + ... + 2n+1.
So what is this sum? Previously, we got a bound of O(n · 2n) by noting that
21 + 22 + 23 + ... + 2n+1.
< 2n+1 + 2n+1 + 2n+1 + ... + 2n+1
= n · 2n+1 = 2(n · 2n) = Θ(n · 2n)
However, this is a very weak upper bound. If we're more observant, we can recognize the original sum as the sum of a geometric series, where a = 2 and r = 2. Given this, the sum of these terms can be worked out to be exactly
2n+2 - 2 = 4(2n) - 2 = Θ(2n)
In other words, the total work done by the body of the loop, across all iterations, is Θ(2n).
The total work done by the loop is given by the work done in the loop maintenance plus the work done in the body of the loop. This works out to Θ(2n) + Θ(n) = Θ(2n). Therefore, the total work done by the loop is Θ(2n). This grows very quickly, but nowhere near as rapidly as O(n · 2n), which is what our original analysis gave us.
In short, when analyzing a loop, you can always get a conservative upper bound by multiplying the number of iterations of the loop by the maximum work done on any one iteration of that loop. However, doing a more precisely analysis can often give you a much better bound.
Hope this helps!