Git Product home page Git Product logo

ultimate-pit-limit---pseudoflow's Introduction

Solving the Ultimate Pit Limit Problem by Applying the Pseudoflow Algorithm

"Know how to solve every problem that has been solved." - R. Feynman (1988) ``Programming Language: Python``

Content

1. Some Introduction

Mining Engineers, and this is my kindly opinion, have learned about solving the Ultimate Pit Limit Problems by easy examples, i.e., Lerchs-Grossman 2D Algorithm. However, that is not what we actually see when running an open-pit mining operation. Most of the current problems, including this, have been solved by software programs, and some mining engineers become users rather than doers. That being said, I decided to code the solution of the ultimated pit limit problem by applying the Pseudoflow algorithm (Hochbaum, 2008).

2. The Problem

Given a 3D block model, how do we find the economic envelope/volume that contains the maximum value and fits in within our operational constraints? i.e. maximum slope angles?

bm up_


3. The Solution

The solution follows a paper from Geovia Whittle, published in 2017. They explain how the Pseudoflow algorithm works in detail (Geovia, 2017). To make life easier, this is a summary on how the algorithm works:

1- Estimate each block's value based on economic parameters:

Cutoff Grade = (MiningCost + ProcessingCost*(1 + Dilution))/(MetalPrice*Recovery)
for block in [1 ... Blocks]:
  block_value = (grade_of_block*Recovery*MetalPrice - (ProcessingCost+MiningCost))*Tons
  if grade_of_block < CutoffGrade:
    block_value = -MiningCost*Tons

2- Create a directed graph with our block model. For that:

  • Nodes: We will have 3 types of nodes:
    • Source: The graph starts here. Also, where the flow will start.
    • Sink: The graph ends here. Also, where the flow will end.
    • A block: Considered as a node
  • Edges:
    • Source -> a block: if the block's value is positive; the edge's weight will be the block value.
    • Block -> block: if allowed by the precedence, i.e, 1-5 precedence (45 degrees); the edge's weight will be the block value.
    • Block -> sink: if the block's value is negative; the edge's weight will be the block value (negative).

Hint: You can use 'Networkx' to build your graph or do it by your own using dictionaries in Python.

def create_graph(self, bmodel, precedence):
    # Create an empty directed graph.
    Graph = NetX.DiGraph()
    if precedence == 9:
        distance = (self.modex**2 + self.modey**2+ self.modez**2)**0.5
    elif precedence == 5:
        distance = (self.modex**2 + self.modez**2)**0.5
    for step in range(steps_z):
        upper_bench = np.array(bmodel[bmodel.iloc[:,3]== col_compare[step]])
        lower_bench = np.array(bmodel[bmodel.iloc[:,3] == col_compare[step]])
        self.create_edges(
          Graph=Graph, up=upper, low =lower, trigger=step, prec=precedence, dist=distance)
        # Shrink the block model when going down - it reduces the computational time.
        bmodel = bmodel[
          (bmodel.iloc[:,1]!= self.minx+i*self.modex)
          &(bmodel.iloc[:,1]!=self.maxx-i*self.modex)
          &(bmodel.iloc[:,2] != self.miny+i*self.modey)
          &(bmodel.iloc[:,2] != self.maxy-i*self.modey)]
    return Graph

def create_edges(self,Graph,up, low, trigger, prec, dist):
    # Create internal edges - Block to block.
    tree_upper = spatial.cKDTree(up[:,1:4])
    # Get the closest block for each block, yet complying the precedences.
    mask = tree_upper.query_ball_point(low[:,1:4], r = dist + 0.01)
    for _, g in enumerate(mask):
        if len(g) == prec:
            for reach in up[g][:,0]:
              # Add internal edge + adding a weight of 99e9 (infinite).
                Graph.add_edge(low[_][0], reach, const = 99e9, mult = 1)
    #Create external edges - Source to block to sink.
    player = up
    for node, capacity in zip(player[:,0], player[:,4]):
        cap_abs = np.absolute(np.around(capacity, decimals=2))
        # Create an edge from a node to the sink if bvalue less than 0
        if capacity < 0:
            Graph.add_edge(node, self.sink, const = cap_abs, mult = -1)
        # Otherwise the source is connected to the block.
        else:
            Graph.add_edge(0, node, const = cap_abs, mult = 1)

3- The algorithm will push the flow from the source to an ore node and it will try to saturate the capacity. Furthermore, it will push from the waste node to pay waste blocks. Therefore, as the maximum flow is found, the problem is solved and that will mean that waste blocks were paid. The following chart extracted from 'Whittle's paper' would help you better understand what is written above:

Screenshot 2021-02-27 114317


4. Building an Application

To solve this problem dynamically, and also to make people playing with it, a web application has been created by using Streamlit.

Features of the Application:

  • It can check outliers after you upload a block model in .csv format. If you do not have it, use a default one. We have everything for you!

    • What do we mean with outliers?
      • Block's coordinates that are out of the big block, meaning that an specific block does not belong to a 3D cubic beatiful form.
      • Block's coordinates that are not in the proper gravity center.
  • 3D Visualization: Select some lower and upper bounds for what you want to see and grades' ranges and we will color-code based on it.

visualize


* GradeTonnage Distribution

gtd


* Input the economic parameters to get the blocks' value

upl


* Run the Algorithm and visualize your **beatiful pit limit**

issue_output


5. Future Work Ideas

  • Add a variety of slope angles. At this point in time, we are just evaluating 2 precedences which are equivalent to 45 and 40 degrees approximately.
  • Evaluate a set of revenue factors and see where to mine first - which nested pit has the highest value. Also, visualize it.
  • Use some Operations Research techniques to draw automated inpit and expit ramps. Dr. Yarmuch developed an algorithm to solve this problem and his paper is worth reading.

6. References

  • Hochbaum, D. S. (2008). The pseudoflow algorithm: A new algorithm for the maximum-flow problem. Operations research, 56(4), 992-1009.
  • Souza, F. R., Melo, M., & Pinto, C. L. L. (2014). A proposal to find the ultimate pit using Ford Fulkerson algorithm. Rem: Revista Escola de Minas, 67, 389-395.
  • Yarmuch, J. L., Brazil, M., Rubinstein, H., & Thomas, D. A. (2020). Optimum ramp design in open pit mines. Computers & Operations Research, 115, 104739.

ultimate-pit-limit---pseudoflow's People

Contributors

luisflarota avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.