Make a random number more probable in python - python

I'm using numpy.random.rand(1) to generate a number between 0-1 and the values of a and b change depending on what the number is. How can I make the probability of x > .5 and x < .5 be proportional to a and b? So if a is 75 and b is 15 then the probability of x > .5 is 5 times more probable than x < .5. I'm unsure as to what codes to use to assign probabilities. This is what I have:
a = 100
b = 100
while True:
x = numpy.random.rand(1)
print x
if x < .5:
a = a + 10
b = b - 10
print a
print b
if x > .5:
b = b + 10
a = a - 10
print a
print b
if b1 == 0:
print a
break
if b2 == 0:
print b
break

I'd make two calls to random: One to calculate a random number between 0 and 0.5 and a second to determine if the number should be above 0.5.
For example;
a = 100
b = 100
x = numpy.random.rand(1)/2.0
proportion = a/(1.0*b+a)
if numpy.random.rand(1) > proportion:
x += 0.5

what a fitting name.
ratio = a/b
x = numpy.random.uniform(0.5 + ratio*0.5)
now you have a numbers distributed between 0 and the ratio multiplied by 0.5. With uniform distribution, the ratio between the population of numbers greater than 0.5 and the population lower than 0.5 is the desired ratio.
now we just need to broadcast those ranges to be between 0.5 and 1.0.
if x >= 0.5:
x = x - math.trunc(x)
if int(str(number-int(x))[1:]) < 5:
x += 0.5

In this case I would have numpy generate a number between 1 and 100 then assign based on that. I.e. (pusdocode)
if rand(100) => 50: a=0
else: a=1
then all you have to do is changed the 50 to whatever the % you want. I can elaborate further if that is confusing.
def get_rand_value(a, b):
if rand(100) => a:
return True
else:
return 1
a = 100
b = 100
while True:
x = get_rand_value(a, b)
print x
if x < .5:
a = a + 10
b = b - 10
print a
print b
if x > .5:
b = b + 10
a = a - 10
print a
print b
if b1 == 0:
print a
break
if b2 == 0:
print b
break

Related

Find the sum of all the multiples of 3 or 5 below 1000. (idk what is wrong with my code)

I'm a beginner and I tried this code to list the sum of all the multiples of 3 or 5 below 100, but it gives a wrong answer and I don't know why.
result = 0
result2 = 0
som = 0
sum2 = 0
below_1000 = True
while below_1000:
result = result+3
if result < 1000:
som += result
else:
below_1000 = False
below_1000 = True
while below_1000:
result2 = result2+5
if result2 < 1000:
sum2 += result2
else:
below_1000 = False
final_result = som+sum2
print(final_result)
Since you first loop over multiples of 3, then again over multiples of 5, you are double-counting a lot of values, specifically values that are multiples of both 3 and 5 (for example 15 or 60).
To write this manually, you can use a for loop over range
total = 0
for i in range(1000):
if i % 3 == 0 or i % 5 == 0:
total += i
>>> total
233168
A more concise way to do this same thing is using a generator expression within the sum function
>>> sum(i for i in range(1000) if i % 3 == 0 or i % 5 == 0)
233168

Variable takes negative value while it is restricted to be nonnegative

I am programming a vehicle routing problem in Python with PuLP. I got all my code in it, but for some reason I get a negative value for one of my decision variables, even though I restricted all of them to be nonnegative.
My code is as follows (Traveltimes is a two dimensional np array, with travel times between each pair of customers (i,j), where c(i,j) = c(j,i) and c(i,i) = 0.):
My code:
numVehicles = 2
numCustomers = 2
prob = LpProblem("DSP", LpMinimize)
var = [[[0 for k in range(numVehicles)] for j in range(numCustomers+1)] for i in range(numCustomers+1)]
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
var[i][j][k] = LpVariable("x"+str(i)+","+str(j)+","+str(k), 0,1, cat='Binary')
# ADD OBJECTIVE
obj = ""
for i in range(numCustomers+1):
for j in range(numCustomers+1):
for k in range(numVehicles):
obj += traveltimes[i][j]*var[i][j][k]
prob += obj
# ADD CONSTRAINTS
# All customers visited
for j in range(numCustomers+1):
for k in range(numVehicles):
nr = ""
for i in range(numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Enter each customer exactly once
for i in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for j in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Leave each customer exactly once
for j in range(numCustomers+1):
nr = ""
for k in range(numVehicles):
for i in range(1, numCustomers+1):
nr += var[i][j][k]
prob += nr == 1
# Per vehicle only one customer can be visited as first
nrFirst = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrFirst += var[0][j][k]
prob += nrFirst <= 1
# Max num vehicles
nrOut = ""
for k in range(numVehicles):
for j in range(numCustomers+1):
nrOut += var[0][j][k]
prob += nrOut <= numVehicles
# Restrict x(0,j,k) to be nonpositive
for j in range(numCustomers+1):
for k in range(numVehicles):
prob += var[0][j][k] >= 0
print(prob)
# Solve LP
prob.solve()
for v in prob.variables():
print(v.name, "=", v.varValue)
print("objective=", value(prob.objective))
The first output is the formulation printed
MINIMIZE
1.731*x0,1,0 + 1.731*x0,1,1 + 2.983*x0,2,0 + 2.983*x0,2,1 + 1.731*x1,0,0 + 1.731*x1,0,1 + 9.375*x1,2,0 + 9.375*x1,2,1 + 2.983*x2,0,0 + 2.983*x2,0,1 + 9.375*x2,1,0 + 9.375*x2,1,1 + 0.0
SUBJECT TO
_C1: x0,0,0 + x1,0,0 + x2,0,0 = 1
_C2: x0,0,1 + x1,0,1 + x2,0,1 = 1
_C3: x0,1,0 + x1,1,0 + x2,1,0 = 1
_C4: x0,1,1 + x1,1,1 + x2,1,1 = 1
_C5: x0,2,0 + x1,2,0 + x2,2,0 = 1
_C6: x0,2,1 + x1,2,1 + x2,2,1 = 1
_C7: x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
_C8: x1,1,0 + x1,1,1 + x1,2,0 + x1,2,1 <= 1
_C9: x2,1,0 + x2,1,1 + x2,2,0 + x2,2,1 <= 1
_C10: x0,0,0 + x0,1,0 + x0,2,0 <= 1
_C11: x0,0,0 + x0,0,1 + x0,1,0 + x0,1,1 + x0,2,0 + x0,2,1 <= 1
VARIABLES
0 <= x0,0,0 <= 1 Integer
0 <= x0,0,1 <= 1 Integer
0 <= x0,1,0 <= 1 Integer
0 <= x0,1,1 <= 1 Integer
0 <= x0,2,0 <= 1 Integer
0 <= x0,2,1 <= 1 Integer
0 <= x1,0,0 <= 1 Integer
0 <= x1,0,1 <= 1 Integer
0 <= x1,1,0 <= 1 Integer
0 <= x1,1,1 <= 1 Integer
0 <= x1,2,0 <= 1 Integer
0 <= x1,2,1 <= 1 Integer
0 <= x2,0,0 <= 1 Integer
0 <= x2,0,1 <= 1 Integer
0 <= x2,1,0 <= 1 Integer
0 <= x2,1,1 <= 1 Integer
0 <= x2,2,0 <= 1 Integer
0 <= x2,2,1 <= 1 Integer
It can clearly be observed that all variables are restricted to be an integer between 0 and 1 (thus binary). However, for some reason, I do get negative values for some variable(s), as can be seen below
x0,0,0 = 0.0
x0,0,1 = -1.0
x0,1,0 = 0.0
x0,1,1 = 1.0
x0,2,0 = 0.0
x0,2,1 = 1.0
x1,0,0 = 1.0
x1,0,1 = 1.0
x1,1,0 = 1.0
x1,1,1 = 0.0
x1,2,0 = 0.0
x1,2,1 = 0.0
x2,0,0 = 0.0
x2,0,1 = 1.0
x2,1,0 = 0.0
x2,1,1 = 0.0
x2,2,0 = 1.0
x2,2,1 = 0.0
objective= 11.159
Really looking forward to any suggestions on how to solve this problem, since I clearly do not want negative values!
As a few others have suggested you should write a Minimum Complete and Verifiable Example.
That said, if you are getting constraints violated, and you are sure you've implemented them correctly, I reckon you have an infeasible problem (i.e. if you looked at your constraints carefully you would find there is a combination which makes solving impossible).
To check this add:
print (("Status:"), LpStatus[prob.status])
Just after you do prob.solve(). I reckon you'll find it's infeasible.
prob += nr == 1
"+=" is for assignment
"==" is checking for equivalence, and belongs in an "if" statement or a "while".
For instance:
if prob + nr == 1: #execute what follows if prob + nr is equal to 1

Python times table using while

Why in python a times table program doesn't work like this?
n = int(input("Type a number: "))
count = 10
while count < 0:
print(f"{count} x {n} = {n * count}")
count = count - 1
But this works correctly:
n = int(input("Type a number: "))
for i in range(1, 11):
print(f"{i} x {n} = {n * i}")
The result is (or should be), for example:
1 x 5 = 5
2 x 5 = 10
3 x 5 = 15
4 x 5 = 20
5 x 5 = 25
6 x 5 = 30
7 x 5 = 35
8 x 5 = 40
9 x 5 = 45
10 x 5 = 50
As a beginner I need to understand... and is it possible to use while in that situation?
This is python 3.x
You want to start count from 1 so that your loop increments rather than decrements. Your while loop conditional check is also incorrect as count is never less than 0. Try this:
n = int(input("Type a number: "))
count = 1
while count <= 10:
print(f"{count} x {n} = {n * count}")
count = count + 1
You need to set the condition in the while to be true to go through the loop. Thus we will say do while count is greater than or equal to zero.
n = int(input("Type a number: "))
count = 10
while count >= 0:
print(f"{count} x {n} = {n * count}")
count = count - 1

whats wrong with this statement(count from 0-9)

I am trying to get this code to calculate 5 and print numbers by 5's with a while statement of 7, so I want it to loop through, generating a different number 7 times; however, when it gets to a number over 10, I want it to start back over at 0 and ignore the 10.
This is my code:
while z < 7:
firstpickplusfive = int(firstpickplusfive) + 1
counts = counts + 1
if counts == 1:
if firstpickplusfive > 9:
firstpickplusfive = 0
if counts == 5:
print firstpickplusfive
z = int(z) + 1
The code prints the first number, but freezes on printing any others. Why isn't this working?
Your code is not in the loop. Python's code blocks are created with indents:
while z < 7:
firstpickplusfive = int(firstpickplusfive) + 1
counts = counts + 1
if counts == 1:
if firstpickplusfive > 9:
firstpickplusfive = 0
if counts == 5:
print firstpickplusfive
z = int(z) + 1
Is this the result you were trying to achieve:
import random
x = random.randint(1,9)
for i in range(1,8):
print x
x += 5
if x >= 10:
x -= 9
This generates a random number, and adds 5 until it passes 10, then subtracts 9, and it does this seven times. If I understand your question correctly, this is what you were trying to do. Please correct me if I am wrong.
no this is not what I was trying to do here is what I am trying to do.
counts = 0
r = 0
firstpickplusfive = 7
p = firstpickplusfive + 5
while r < 3:
firstpickplusfive = p + counts
if firstpickplusfive > 6:
firstpickplusfive = firstpickplusfive + counts - 10
if p > 9:
p = firstpickplusfive + counts
print firstpickplusfive
counts = counts + 1
r = int(r) + 1
it works alone, but when I add it to the script I am trying to write it doesn't work...if there is a simpler way to do it I would appreciate knowing it.
ie.
number = number + 5 + 0
then
number = number + 5 + 1.....ect which
example 7 + 5 + 0 = 12,
7 + 5 + 1 = 13.........
if the number is equal to 10 then I want it to drop the tens place and keep the 1's place
example 7 + 5 + 0 = 2,
7 + 5 + 1 = 3
Here is an easier method:
for i in range(1,4):
num = 7
num += 5
num +=(i-1)
if num >=10:
num -= 10
print num
i+=1
Try this in your script, does it work?

Sum of 2 elements from 2 ranges that will be one given number

I need to make a quick algorithm(I already made a slow one) which will find the number of all possible values from two ranges of integer numbers (ranges can intersect or not) which sum will be the given number
I can represent it like an equation: z = x + y
where z is a known number and equals x plus y
z can be any number between 0 and 10^18
x belongs to a range of integer numbers [a..b], where 0 <= a <= b <= 10^18 and
the difference between the consecutive numbers is 1
y belongs to a range of integer numbers [c..d], where 0 <= c <= d <= 10^18 and
the difference between the consecutive numbers is 1
so I need to find the number(not their exact values) of all the possible variations of x and y from two sets of numbers which sum will be z
Example:
z = 5
first set: a = 1, b = 5(it means the set consists of 1,2,3,4,5)
second set: c = 1, b = 5
then the answer is 4, because all possible combinations are:
x = 4, y = 1
x = 3, y = 2
x = 2, y = 3
x = 1, y = 4
because theirs sums are 5's
The compulsory condition for an algrorithm is to work faster than 1 second
The following code works fine but only with numbers lesser than 1000000. It starts to work much slower with big numbers
with open(r"input.txt") as f:
n = int(f.readline()) # the given number
a = int(f.readline()) # the start position of the first set
b = int(f.readline()) # the end position of the first set
c = int(f.readline()) # the start position of the second set
d = int(f.readline()) # the end position of the second set
# print "n:",n,"a:",a,"b:",b,"c:",c,"d:",d
t = b - a + 1 # all posible variants of the first set
k = d - c + 1 # all posible variants of the second set
number_of_vars = 0
if t >= k:
while b >= a:
if (n - b <= d) \
and (n - b>= c):
number_of_vars += 1
b -= 1
else:
b -= 1
if t < k:
while d >= c:
if (n-d <= b) and (n-d >= a):
number_of_vars += 1
d -= 1
else:
d -= 1
print number_of_vars
No algorithm required -- just algebra:
It suffices to count the number of x in [a,b] for which z - x is in [c,d]
You need both a <= x <= b and c <= z - x <= d. The second inequality is equivalent to z - d <= x <= z - c hence you need
max(a, z - d) <= x <= min(b,z - c)
The number of such x is 0 if min(b,z - c) < max(a, z - d) otherwise it is
min(b,z - c) - max(a, z - d) + 1
In either case the number of solutions is
max(0, min(b,z - c) - max(a, z - d) + 1)
In your example a = c = 1 and b = d = z = 5 and
min(b, z - c) - max(a, z - d) + 1 = min(5,4) - max(1,0) + 1 = 4 - 1 + 1 = 4
One thing that you can use to reduce the checks in your algorithm is,
If the range for the 2 sets are overlapping, then you can cancel out some checks. Like in your example,
range for 1st set is 1 to 5
range for 2nd set is 1 to 5
So, if
x = 4, y = 1
is working, then
x = 1, y = 4
will also work. So you have to go only till half the number (i.e till 3 only in this case)
If only a part of the range is overlapping, then you can use the above method for that part, and the remaining part can be checked using normal method.

Categories