Search code examples
pythonlistrandommontecarlo

Adding variable list elements into a new list


Background: I'm trying to do a monte carlo simulation. The idea is if there is a process of n different random sub-processes and each has a cost distribution, what will be the histogram of probable cost distribution of the process?

So I first take the number of sub processes from user. Take the parameters for triangular random distribution and generate a random number and store price in the list. This will be my price for that sub-process. Now this is done for all activities so if there are 2 activities I have 2 prices here. I run a simulation say 10 times, and get this 2 prices 10 times, all in order. So I have 20 elements. [PriceA, PriceB, PriceA, PriceB ... 10 times here] and so on in the list.

Now to calculate total price of the process, I need to sum up individual sub-processes. Here for example PriceA and PriceB should be added and I would get 10 simulated total prices of my process.

The issue I am facing is I cannot do this addition for n activities where n is left to user. If it were just 2 then I would write a code using i and i+1 and get it done or any determined value. How do I do it for any n? I though of splitting the lists and adding by indexes but that seems inefficient way to do it.

Code:

import matplotlib
import numpy
import random
lower, likely, upper, cost, sim = [],[],[],[],[]
n = int(input("Enter the number of monte carlo simulations to be performed \t"))
val = int(input("Enter the number of work packages in project: "))
print(val)
for i in range(val):
    print("For the work package \t", i+1)
    lower.append(int(input("enter the optimistic cost for work package \t")))
    likely.append(int(input("enter the most probable cost for work package \t")))
    upper.append(int(input("enter the optimistic cost for work package \t")))
print('The lower, most likely and upper costs for projects are \n',lower,'\n',likely,'\n',upper,'\n')
for j in range(n):
    for i in range(val):
        cost.append(random.triangular(lower[i], upper[i], likely[i]))
print(cost)

Output:

Enter the number of monte carlo simulations to be performed     10
Enter the number of work packages in project: 2
2
For the work package     1
enter the optimistic cost for work package  3
enter the most probable cost for work package   6
enter the optimistic cost for work package  9
For the work package     2
enter the optimistic cost for work package  1
enter the most probable cost for work package   4
enter the optimistic cost for work package  7
The lower, most likely and upper costs for projects are 
 [3, 1] 
 [6, 4] 
 [9, 7] 

[6.098694228674759, 2.974477452062627, 6.006427763481563, 6.8545773736244735, 4.638673767474145, 4.833207090016218, 4.359294435445397, 5.563718626442213, 7.017102295368932, 3.6445583270543027, 5.802321952031663, 4.240692991425738, 4.3449796431896575, 5.760021915286421, 4.472665149713935, 4.023976581268439, 4.9939827601969595, 5.651542603447864, 5.382829752293766, 3.02272111116958]

Process finished with exit code 0

I'll later on add a graph and all to make it visual. Kindly let me know of any function or method which can add these elements efficiently. Or if there is a way to split it into lists and then add them individually or maybe store the data in different lists from the start. Any help would be appreciated.


Solution

  • This answer is based on the simplified question provided by the OP in the comment:

    "How to add number of elements in list such that the number is input by user? So if user says 2 then i add 0 and 1 index and 2 and 3 and so on. If user says 4 then i add 0 1 2 3 indexes and the next would be 4 5 6 7 and so on. All additions will be stored in a new list."


    You can use range with slicing:

    def sum_chunk(lst, n):
        return [lst[i:i+n] for i in range(0, len(lst), n)]
    
    lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    
    print(sum_chunk(lst, 2)) # [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]]
    print(sum_chunk(lst, 4)) # [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]