Working out 三维DP

本文详细解析了DP算法中的一道题目,通过转化问题视角,将复杂路径问题转化为求最大价值的问题。文章深入探讨了如何利用累积性和状态选择进行递推,并通过代码实现展示了具体的解决方案。

今天开始研究DP,今天是4.10 离省赛开始还有25天。
先来说一下这个题,一开始把题意看错了,没有看到必须在一个位置相遇。菜啊

这个题一开始想到了将问题转化成计算从相遇点到起点和终点的距离。
但是还是不知道怎么划分状态,看完题解后,想到了一个点就是”累积性”。联想到了概率上的分布函数,可能这就是“递推的本质”。

说一下这个题的思路。

这里写图片描述
先来说一下为什么将问题转化成相遇点到各个角的最大价值。

首先因为题目的要求必须有一个相遇点,这个很关键,一开始没翻译出来.然后假设有这样的一个点,然后可以画出几个简单的情景,或者想一下就会发现,如果只有一个相遇点的话,就会有两种情况,假设A是向左进入相遇点的话,必须从左边出相遇点,如果换方向的话,就会有另外的相遇点。
这样的话出现上面的情况,这样的话,就可以转化成各个角到相遇点的最大价值,现在就是打表算出从各个角出发到所有点的最大价值.
然后枚举所有可能的相遇点.
就可以了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    typedef long long LL;
    const int MAXN = 1e3 + 10;
    LL dp[MAXN][MAXN][4]; // 四个方向
    LL a[MAXN][MAXN];
    void f(int n,int m)
    {
        memset(dp,0,sizeof(dp));
        for(int i = 1;i <= n; ++i)
        {
            for(int j = 1;j <= m;++j)
            {
                dp[i][j][0] = max(dp[i - 1][j][0],dp[i][j - 1][0]) + a[i][j];
            }
        }
        for(int i = n;i >= 1;--i)
        {
            for(int j = 1; j <= m;++j)
            {
                dp[i][j][1] = max(dp[i + 1][j][1],dp[i][j - 1][1]) + a[i][j];
            }
        }
        for(int i = n;i >= 1;--i)
        {
            for(int j = m;j >= 1;--j)
            {
                dp[i][j][2] = max(dp[i + 1][j][2],dp[i][j + 1][2]) + a[i][j];
            }
        }
        for(int i = 1;i <= n;++i)
        {
            for(int j = m;j >= 1;--j)
            {
                dp[i][j][3] = max(dp[i - 1][j][3],dp[i][j + 1][3]) + a[i][j];
            }
        }
    }
    int main()
    {
        ios::sync_with_stdio(false);
        int n,m;
        while(cin >> n >> m)
        {

            for(int i = 1; i <= n;i++)
            {
                for(int j = 1;j <= m;++j)
                    cin >> a[i][j];
            }
            f(n,m);
            LL ans = 0;
            for(int i = 2; i <= n - 1; ++i)
            {
                for(int j = 2;j <= m - 1;++j)
                {
                    ans = max(ans,dp[i - 1][j][0] + dp[i + 1][j][2] + dp[i][j - 1][1] + dp[i][j + 1][3]);
                    ans = max(ans,dp[i - 1][j][3] + dp[i + 1][j][1] + dp[i][j - 1][0] + dp[i][j + 1][2]);
                }
            }
            cout << ans << endl;
        }
        return 0;
    }

总 结 一 下 : 就是递推的就是 "累积“和”状态的选择和转化“ 

model new model title "Longwall Mining Simulation" model domain extent 0 66.0 0 55.0 model config mechanical model mechanical timestep auto contact cmat default model linear method deformability emod 2e8 kratio 2.5 property fric 0.5 dp_nratio 0.5 dp_sratio 0.5 contact cmat apply ; ======================================== ; ======================================== [bottom_coal_height = 0.0] [top_coal_height = 15.8] [total_coal_height = 15.8] [gangue_layers = 0] [gangue_thickness = 0.0] [immediate_roof_thickness = 20.6] [main_roof_thickness = 0.0] [total_roof_thickness = 20.6] [height_floor = 2.32] [support_width = 1.5] [support_num = 34] [head_support_num = 6] [total_support_num = 40] [support_start = 3.0] [caving_support_num = 34] [caving_gates = 34] [caving_rounds = 1] [porosity = 0.105] [gangue_threshold = 0.05] [total_height = 36.4] [model_width = 66.0] [boundary_buffer = 3.0] [effective_mining_width = 60.0] ; [mining_start_x = 3.0] [mining_end_x = 63.0] [total_supports = support_num] [gangue_extension = 10.0] [support_top_height = 2.8] [PI = 3.1415926535] [y_bottom_coal_bottom = 0.0] [y_bottom_coal_top = 0.0] [y_top_coal_bottom = 0.0] [y_top_coal_top = top_coal_height] [y_immediate_roof_bottom = y_top_coal_top] [y_immediate_roof_top = y_immediate_roof_bottom + immediate_roof_thickness] [y_main_roof_bottom = 0.0] [y_main_roof_top = 0.0] [y_gangue_top = 0.0] ; ======================================== ; ======================================== ; ======================================== wall create vertices 0 0 0 35.0 id 100 wall create vertices 66.0 0 66.0 35.0 id 101 wall create vertices 0 0 66.0 0 id 102 wall create vertices 0 35.0 66.0 35.0 id 105 wall create vertices 3.0 0 3.0 35.0 id 103 wall create vertices 63.0 0 63.0 35.0 id 104 fish define finalize_walls loop foreach wp wall.list local wall_id = wall.id(wp) command wall attribute velocity-x 0.0 range id [wall_id] wall attribute velocity-y 0.0 range id [wall_id] end_command endloop io.out('All walls configured as rigid infinite mass surfaces.') end wall attribute velocity-x 0.0 range id 100 wall attribute velocity-y 0.0 range id 100 wall attribute velocity-x 0.0 range id 101 wall attribute velocity-y 0.0 range id 101 wall attribute velocity-x 0.0 range id 102 wall attribute velocity-y 0.0 range id 102 wall attribute velocity-x 0.0 range id 103 wall attribute velocity-y 0.0 range id 103 wall attribute velocity-x 0.0 range id 104 wall attribute velocity-y 0.0 range id 104 wall attribute velocity-x 0.0 range id 105 wall attribute velocity-y 0.0 range id 105 [finalize_walls] ; ======================================== ; ======================================== fish define calc_ball_numbers area_coal = model_width * total_coal_height * (1 - porosity) area_gangue = model_width * gangue_thickness * (1 - porosity) area_roof = model_width * total_roof_thickness * (1 - porosity) local coal_radius_avg = (0.04 + 0.06) / 2 local gangue_radius_avg = (0.06 + 0.08) / 2 local roof_radius_avg = (0.07 + 0.09) / 2 area_ball_coal = PI * (coal_radius_avg)^2 area_ball_roof = PI * (roof_radius_avg)^2 area_ball_gangue = PI * (gangue_radius_avg)^2 num_coal = math.floor(area_coal / area_ball_coal) num_roof = math.floor(area_roof / area_ball_roof) num_gangue = math.floor(area_gangue / area_ball_gangue) num_coal = math.max(50, math.min(500, num_coal)) num_gangue = math.max(25, math.min(250, num_gangue)) num_roof = math.max(30, math.min(300, num_roof)) global num_coal = num_coal global num_gangue = num_gangue global num_roof = num_roof io.out('Coal balls: ' + string(num_coal)) io.out(string(num_coal)) io.out('Gangue balls: ' + string(num_gangue)) io.out('Roof balls: ' + string(num_roof)) end fish define generate_bottom_coal io.out('===== Bottom Coal Generation Skipped =====') io.out('Bottom coal height is 0.0m - no bottom coal to generate') io.out('Skipping bottom coal generation') io.out('===============================================') end fish define generate_top_coal io.out('===== Generating Top Coal (Gaussian Distribution) =====') io.out('Top coal height: 15.8m') io.out('Position: Y=2.8m to Y=18.6m (natural coal layer)') io.out('X range: 3.0m to 63.0m (60m width)') io.out('Particle radius: 0.04-0.06m (Gaussian distribution, sigma=0.5)') local coal_y_bottom = 2.8 local coal_y_top = 18.6 local coal_thickness = coal_y_top - coal_y_bottom local coal_x_left = 3.0 local coal_x_right = 63.0 local coal_width = coal_x_right - coal_x_left local coal_area = coal_width * coal_thickness local coal_volume = coal_area * 1.0 local coal_density = 1360.0 local coal_mass = coal_volume * coal_density local radius_mean = 0.05 local radius_sigma = 0.5 ; Gaussian distribution for natural variation local radius_min = 0.04 local radius_max = 0.06 local avg_volume = (4.0/3.0) * PI * radius_mean^3 local avg_mass = avg_volume * coal_density local top_coal_needed = int(coal_mass / avg_mass) ; Calculate realistic number of balls based on area and radius local ball_area = PI * radius_mean^2 local max_possible_balls = int(coal_area / (ball_area * 3.0)) ; 3.0 is packing factor for complete generation top_coal_needed = math.min(top_coal_needed, max_possible_balls) top_coal_needed = math.max(200, math.min(500, top_coal_needed)) ; Increased range for complete generation io.out('Top coal balls needed: ' + string(top_coal_needed)) io.out('Max possible balls in area: ' + string(max_possible_balls)) io.out('Generating with Gaussian distribution pattern...') command ball generate id 1 [top_coal_needed] box [coal_x_left] [coal_x_right] [coal_y_bottom] [coal_y_top] group 'top_coal' tries 100000 radius [radius_min] [radius_max] end_command loop foreach bp ball.list if ball.group(bp) == 'top_coal' local u1 = random local u2 = random if u1 <= 0.0 u1 = 0.0001 endif local z0 = math.sqrt(-2.0 * math.log(u1)) * math.cos(2.0 * PI * u2) local radius = radius_mean + radius_sigma * z0 if radius < radius_min radius = radius_min endif if radius > radius_max radius = radius_max endif ball.radius(bp) = radius endif endloop command ball property density 1360 range group 'top_coal' ball property 'young_mod' 2e8 range group 'top_coal' ball property 'kratio' 2.5 range group 'top_coal' ball property 'fric' 0.5 range group 'top_coal' ball property 'dp_nratio' 0.5 range group 'top_coal' ball property 'dp_sratio' 0.5 range group 'top_coal' end_command local top_coal_count = 0 loop foreach bp ball.list if ball.group(bp) == 'top_coal' top_coal_count = top_coal_count + 1 endif endloop io.out('Top coal balls generated: ' + string(top_coal_count)) io.out('*** Top coal generation completed (Y: 2.8-18.6m, Gaussian distribution) ***') io.out('===============================================') end fish define generate_immediate_roof io.out('===== Generating Immediate Roof (Gaussian Distribution) =====') io.out('Immediate roof thickness: 15.6m') io.out('Position: Y=18.6m to Y=34.2m (natural roof layer)') io.out('X range: 3.0m to 63.0m (60m width)') io.out('Particle radius: 0.07-0.09m (Gaussian distribution, sigma=0.5)') local roof_y_bottom = 18.6 local roof_y_top = 34.2 local roof_thickness = roof_y_top - roof_y_bottom local roof_x_left = 3.0 local roof_x_right = 63.0 local roof_width = roof_x_right - roof_x_left local roof_area = roof_width * roof_thickness local roof_volume = roof_area * 1.0 local roof_density = 2560.0 local roof_mass = roof_volume * roof_density local radius_mean = 0.07 local radius_sigma = 0.6 ; Gaussian distribution for natural variation local radius_min = 0.05 local radius_max = 0.09 local avg_volume = (4.0/3.0) * PI * radius_mean^3 local avg_mass = avg_volume * roof_density local immediate_roof_needed = int(roof_mass / avg_mass) ; Calculate realistic number of balls based on area and radius local ball_area = PI * radius_mean^2 local max_possible_balls = int(roof_area / (ball_area * 3.0)) ; 3.0 is packing factor for complete generation immediate_roof_needed = math.min(immediate_roof_needed, max_possible_balls) immediate_roof_needed = math.max(200, math.min(500, immediate_roof_needed)) ; Increased range for complete generation io.out('Immediate roof balls needed: ' + string(immediate_roof_needed)) io.out('Max possible balls in area: ' + string(max_possible_balls)) io.out('Generating with Gaussian distribution pattern...') ; Find the next available ID local max_id = 0 loop foreach bp ball.list if ball.id(bp) > max_id max_id = ball.id(bp) endif endloop local start_id = max_id + 1 command ball generate id [start_id] [start_id + immediate_roof_needed - 1] box [roof_x_left] [roof_x_right] [roof_y_bottom] [roof_y_top] group 'immediate_roof' tries 100000 radius [radius_min] [radius_max] end_command loop foreach bp ball.list if ball.group(bp) == 'immediate_roof' local u1 = random local u2 = random if u1 <= 0.0 u1 = 0.0001 endif local z0 = math.sqrt(-2.0 * math.log(u1)) * math.cos(2.0 * PI * u2) local radius = radius_mean + radius_sigma * z0 if radius < radius_min radius = radius_min endif if radius > radius_max radius = radius_max endif ball.radius(bp) = radius endif endloop command ball property density 2560 range group 'immediate_roof' ball property 'young_mod' 2e8 range group 'immediate_roof' ball property 'kratio' 2.5 range group 'immediate_roof' ball property 'fric' 0.5 range group 'immediate_roof' ball property 'dp_nratio' 0.5 range group 'immediate_roof' ball property 'dp_sratio' 0.5 range group 'immediate_roof' end_command local immediate_roof_count = 0 loop foreach bp ball.list if ball.group(bp) == 'immediate_roof' immediate_roof_count = immediate_roof_count + 1 endif endloop io.out('Immediate roof balls generated: ' + string(immediate_roof_count)) io.out('*** Immediate roof generation completed (Y: 18.6-34.2m, Gaussian distribution) ***') io.out('===============================================') end ; ======================================== ; ======================================== fish define create_supports io.out('===== Creating Hydraulic Supports =====') io.out('Support offset: +3.0m (moved right)') io.out('Caving starts from support 6 (frame 6)') io.out('Middle supports: ' + string(support_num) + ' frames') io.out('Head supports: ' + string(head_support_num) + ' frames (3 at each end)') io.out('Total supports: ' + string(total_support_num) + ' frames') io.out('Caving supports: 34 frames (supports 6-39) with caving gates') io.out('Caving gate design: 1.2m width, separated from support, aligned with top') loop local i (1, 3) local xpos_head = 3.0 + (i-1) * support_width local wall_id_1_head = 2000 + i local wall_id_2_head = 3000 + i local wall_id_3_head = 4000 + i command wall create vertices [xpos_head] 0 [xpos_head] 2.8 id [wall_id_1_head] wall attribute velocity-x 0.0 range id [wall_id_1_head] wall create vertices [xpos_head+1.5] 0 [xpos_head+1.5] 2.8 id [wall_id_2_head] wall attribute velocity-x 0.0 range id [wall_id_2_head] wall create vertices [xpos_head] 2.8 [xpos_head+1.5] 2.8 id [wall_id_3_head] wall attribute velocity-x 0.0 range id [wall_id_3_head] end_command io.out('Created head support ' + string(i) + ' at x=' + string(xpos_head) + ' (no caving gate)') endloop loop local j (1, support_num) local xpos_middle = 3.0 + 3 * support_width + (j-1) * support_width local wall_id_1_middle = 2000 + 3 + j local wall_id_2_middle = 3000 + 3 + j local wall_id_3_middle = 4000 + 3 + j local wall_id_4_middle = 5000 + j local caving_gate_id = 6000 + j command wall create vertices [xpos_middle] 0 [xpos_middle] 2.8 id [wall_id_1_middle] wall attribute velocity-x 0.0 range id [wall_id_1_middle] wall create vertices [xpos_middle+1.5] 0 [xpos_middle+1.5] 2.8 id [wall_id_2_middle] wall attribute velocity-x 0.0 range id [wall_id_2_middle] wall create vertices [xpos_middle] 2.8 [xpos_middle+1.5] 2.8 id [wall_id_3_middle] wall attribute velocity-x 0.0 range id [wall_id_3_middle] end_command ; Only support 6 (j=6) has caving gate if j == 6 local gate_x_start = xpos_middle + 0.15 local gate_x_end = gate_x_start + 1.2 command wall create vertices [gate_x_start] 2.8 [gate_x_end] 2.8 id [wall_id_4_middle] group 'caving_gate' wall attribute velocity-x 0.0 range id [wall_id_4_middle] end_command io.out('Created middle support ' + string(j) + ' at x=' + string(xpos_middle) + ' (with 1.2m caving gate)') else io.out('Created middle support ' + string(j) + ' at x=' + string(xpos_middle) + ' (no caving gate)') endif endloop loop local k (1, 3) local xpos_tail = 3.0 + 3 * support_width + support_num * support_width + (k-1) * support_width local wall_id_1_tail = 2000 + 3 + support_num + k local wall_id_2_tail = 3000 + 3 + support_num + k local wall_id_3_tail = 4000 + 3 + support_num + k command wall create vertices [xpos_tail] 0 [xpos_tail] 2.8 id [wall_id_1_tail] wall attribute velocity-x 0.0 range id [wall_id_1_tail] wall create vertices [xpos_tail+1.5] 0 [xpos_tail+1.5] 2.8 id [wall_id_2_tail] wall attribute velocity-x 0.0 range id [wall_id_2_tail] wall create vertices [xpos_tail] 2.8 [xpos_tail+1.5] 2.8 id [wall_id_3_tail] wall attribute velocity-x 0.0 range id [wall_id_3_tail] end_command io.out('Created tail support ' + string(k) + ' at x=' + string(xpos_tail) + ' (no caving gate)') endloop io.out('All supports created successfully with 3m right offset') io.out('Caving gates: 1.2m width, separated from supports, aligned with top') io.out('===============================================') end ; ======================================== ; ======================================== fish define prevent_bouncing loop foreach bp ball.list local pos = ball.pos(bp) local px = pos->x local py = pos->y if py <= support_top_height + 0.05 ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endif if px <= 3.02 ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endif if px >= 62.98 ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endif if py <= 0.02 ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endif endloop end fish define execute_caving local xpos = global_xpos local gate_width = global_gate_width local coal_mass = 0.0 local gangue_mass = 0.0 local total_mass = 0.0 local gangue_ratio = 0.0 local stop_caving = false local res io.out('Executing single round caving at position: X=' + string(xpos) + ', width=' + string(gate_width)) local x1 = xpos local x2 = xpos + gate_width local y_min = 0.0 local y_max = support_top_height + top_coal_height + immediate_roof_thickness io.out('Caving zone: X=' + string(x1) + '-' + string(x2) + ', Y=' + string(y_min) + '-' + string(y_max)) io.out('Caving mechanism: Particles slide down along wall surfaces') res = 1 loop foreach bp ball.list ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endloop prevent_bouncing() command model cycle 2000 model solve time 2.0 end_command loop foreach bp ball.list ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endloop prevent_bouncing() prevent_bouncing() io.out('Caving completed. All particles frozen and system stabilized.') [return_value] = res end fish define sequential_caving global total_coal_mass = 0.0 global total_gangue_mass = 0.0 global caving_area = 0.0 io.out('===== Starting Single Support Caving =====') io.out('Only support 6 has caving gate') io.out('Support spacing: ' + string(support_width) + 'm') io.out('Gangue threshold: ' + string(gangue_threshold*100) + '% (5%)') io.out('Waiting for equilibrium before opening caving gate...') ; Force equilibrium - keep running until equilibrium is reached io.out('Checking equilibrium status...') local current_ratio = mech_ratio io.out('Current mechanical ratio: ' + string(current_ratio, 6)) local equilibrium_cycles = 0 local max_equilibrium_cycles = 500000 local equilibrium_threshold = 1e-3 ; Keep running until equilibrium is reached loop while current_ratio > equilibrium_threshold and equilibrium_cycles < max_equilibrium_cycles io.out('System not in equilibrium. Mechanical ratio: ' + string(current_ratio, 6) + ' (target: ' + string(equilibrium_threshold) + ')') io.out('Cycling until equilibrium... (cycle ' + string(equilibrium_cycles) + ')') command model cycle 1000 end_command equilibrium_cycles = equilibrium_cycles + 1000 current_ratio = mech_ratio if (equilibrium_cycles % 10000) == 0 io.out('Equilibrium check cycle ' + string(equilibrium_cycles) + ': ratio = ' + string(current_ratio, 6)) endif endloop if current_ratio <= equilibrium_threshold io.out('SUCCESS: System is in equilibrium!') io.out('Final mechanical ratio: ' + string(current_ratio, 6)) io.out('Equilibrium reached after ' + string(equilibrium_cycles) + ' cycles') else io.out('WARNING: Maximum equilibrium cycles reached') io.out('Final mechanical ratio: ' + string(current_ratio, 6)) io.out('Proceeding with caving despite potential instability...') endif ; Only proceed with caving after equilibrium is confirmed io.out('') io.out('===== EQUILIBRIUM REACHED - DELETING CAVING GATE HORIZONTAL LINE =====') local support_num = 6 local gate_id = 5000 + support_num local xpos = 3.0 + 3 * support_width + (support_num-1) * support_width io.out('===== Processing Support ' + string(support_num) + ' (Only Support with Caving Gate) =====') io.out('Support position: X=' + string(xpos) + 'm') io.out('Caving gate ID: ' + string(gate_id)) io.out('Caving gate width: 1.2m horizontal line') ; List all walls before deletion io.out('All walls before deletion:') loop foreach wp wall.list io.out(' Wall ID: ' + string(wall.id(wp)) + ' at ' + string(wall.pos(wp)) + ' group: ' + string(wall.group(wp))) endloop ; Check if caving gate exists io.out('Checking for caving gate horizontal line...') local gate = wall.find(gate_id) if gate == null io.out('ERROR: Caving gate ' + string(gate_id) + ' not found!') io.out('Trying to find caving gate by group...') loop foreach wp wall.list if wall.group(wp) == 'caving_gate' io.out(' Found caving gate: ID=' + string(wall.id(wp)) + ' at ' + string(wall.pos(wp))) gate_id = wall.id(wp) gate = wp endif endloop if gate == null io.out('No caving gate found, cannot proceed') return endif else io.out('Caving gate horizontal line found, proceeding with deletion...') io.out('Gate position: ' + string(wall.pos(gate))) io.out('Gate group: ' + string(wall.group(gate))) endif global global_xpos = xpos global global_gate_width = support_width io.out('EQUILIBRIUM CONFIRMED - Deleting caving gate horizontal line for support ' + string(support_num) + '...') io.out('Deleting 1.2m caving gate horizontal line (ID: ' + string(gate_id) + ')') io.out('Support structure remains intact') ; Delete only the caving gate horizontal line (1.2m), not the support structure command wall delete range id [gate_id] end_command ; Verify deletion local gate_after = wall.find(gate_id) if gate_after == null io.out('SUCCESS: 1.2m caving gate horizontal line deleted successfully') io.out('Support structure remains intact') else io.out('WARNING: Caving gate still exists after deletion attempt') io.out('Trying alternative deletion method...') command wall delete range group 'caving_gate' end_command io.out('Alternative deletion method applied') endif ; List all walls after deletion io.out('All walls after deletion:') loop foreach wp wall.list io.out(' Wall ID: ' + string(wall.id(wp)) + ' at ' + string(wall.pos(wp)) + ' group: ' + string(wall.group(wp))) endloop io.out('Caving gate horizontal line deleted for support ' + string(support_num)) io.out('1.2m horizontal opening created, particles can now flow through') ; Rest of the caving process... io.out('Waiting for particle flow and settlement...') local settlement_cycles = 0 local max_settlement_cycles = 10000 local stable_cycles = 0 local max_stable_cycles = 5 local last_coal_mass = 0.0 local last_gangue_mass = 0.0 loop while settlement_cycles < max_settlement_cycles command model cycle 200 end_command settlement_cycles = settlement_cycles + 200 if (settlement_cycles % 1000) == 0 io.out('Settlement cycle ' + string(settlement_cycles) + ' / ' + string(max_settlement_cycles)) endif local current_coal_mass = 0.0 local current_gangue_mass = 0.0 loop foreach bp ball.list local pos = ball.pos(bp) local px = pos->x local py = pos->y if px >= (xpos - support_width/2) and px <= (xpos + support_width/2) and py <= 2.8 if ball.group(bp) == 'coal' current_coal_mass = current_coal_mass + ball.mass(bp) else if ball.group(bp) == 'gangue' current_gangue_mass = current_gangue_mass + ball.mass(bp) endif endif endif endloop local total_mass = current_coal_mass + current_gangue_mass local gangue_ratio = 0.0 if total_mass > 0.0 gangue_ratio = current_gangue_mass / total_mass endif if abs(current_coal_mass - last_coal_mass) < 0.1 and abs(current_gangue_mass - last_gangue_mass) < 0.1 stable_cycles = stable_cycles + 1 else stable_cycles = 0 endif last_coal_mass = current_coal_mass last_gangue_mass = current_gangue_mass if stable_cycles >= max_stable_cycles io.out('Particle flow stabilized after ' + string(settlement_cycles) + ' cycles') io.out('Final coal mass: ' + string(current_coal_mass, 2) + ' kg') io.out('Final gangue mass: ' + string(current_gangue_mass, 2) + ' kg') io.out('Final gangue ratio: ' + string(gangue_ratio*100, 2) + '%') break endif endloop if settlement_cycles >= max_settlement_cycles io.out('Warning: Maximum settlement cycles reached, flow may not be fully stabilized') endif total_coal_mass = current_coal_mass total_gangue_mass = current_gangue_mass caving_area = 1.2 ; 1.2m caving gate width io.out('') io.out('===== Single Support Caving Completed =====') io.out('Support ' + string(support_num) + ' caving completed:') io.out(' Coal mined: ' + string(total_coal_mass, 2) + ' kg') io.out(' Gangue mined: ' + string(total_gangue_mass, 2) + ' kg') io.out(' Gangue ratio: ' + string(gangue_ratio*100, 2) + '%') io.out(' Caving area: ' + string(caving_area, 2) + ' m2 (1.2m gate width)') local total_mined_mass = total_coal_mass + total_gangue_mass local overall_gangue_ratio = 0.0 if total_mined_mass > 0.0 overall_gangue_ratio = total_gangue_mass / total_mined_mass endif io.out('Overall gangue ratio: ' + string(overall_gangue_ratio*100, 2) + '%') local coal_recovery_rate = 0.0 if caving_area > 0.0 coal_recovery_rate = total_coal_mass / caving_area endif io.out('Coal recovery rate: ' + string(coal_recovery_rate, 2) + ' kg/m2') io.out('===============================================') end ; ======================================== ; ======================================== fish define fix_all_balls loop foreach bp ball.list() if ball.radius(bp) <= 0 ball.radius(bp) = 0.05 endif if ball.density(bp) <= 0 if ball.group(bp) == "coal" or ball.group(bp) == "top_coal" or ball.group(bp) == "bottom_coal" ball.density(bp) = 1360 else ball.density(bp) = 2560 endif endif local pos = ball.pos(bp) local py = pos->y if py <= support_top_height + 0.1 ball.vel.y(bp) = 0.0 ball.vel.x(bp) = 0.0 ball.spin(bp) = 0.0 endif endloop end fish define execute_caving_coal local coal_mass = 0.0 loop foreach bp ball.list if ball.group(bp) == 'caved_coal' coal_mass = coal_mass + ball.mass(bp) endif endloop [return_value] = coal_mass end fish define execute_caving_gangue local gangue_mass = 0.0 loop foreach bp ball.list if ball.group(bp) == 'caved_gangue' gangue_mass = gangue_mass + ball.mass(bp) endif endloop [return_value] = gangue_mass end fish define balance_model io.out('===== Starting Model Balance =====') io.out('Target: Maximum unbalanced force ratio < 1e-3') io.out('Initial stress field establishment...') command model gravity 9.81 model cycle 10000 calm 100 end_command local max_ratio = 1.0 local cycle_count = 0 local max_cycles = 100000 io.out('Cycling until equilibrium...') loop while max_ratio > 1e-3 and cycle_count < max_cycles command model cycle 1000 end_command max_ratio = mech_ratio cycle_count = cycle_count + 1000 if (cycle_count % 10000) == 0 io.out('Cycle: ' + string(cycle_count) + ', Max ratio: ' + string(max_ratio, 6)) endif endloop command model save 'initial_state' end_command io.out('===== Model Equilibrium Reached =====') io.out('Final cycle count: ' + string(cycle_count)) io.out('Final max ratio: ' + string(max_ratio, 6)) io.out('Initial stress field established, kinetic energy 閳') io.out('===============================================') end fish define set_contact_parameters io.out('Setting contact parameters for different contact types...') io.out('Ball-ball: emod=2e8, kratio=2.5, fric=0.5, dp_nratio=0.5, dp_sratio=0.5') io.out('Ball-facet: emod=4e8, kratio=2.5, fric=0.5, dp_nratio=0.5, dp_sratio=0.5') command ; Set ball-ball contact parameters (default for all contacts first) contact cmat default model linear method deformability emod 2e8 kratio 2.5 property fric 0.5 dp_nratio 0.5 dp_sratio 0.5 contact cmat apply ; Then override ball-facet contacts with different emod contact cmat add model linear method deformability emod 4e8 kratio 2.5 property fric 0.5 dp_nratio 0.5 dp_sratio 0.5 range contact type 'ball-facet' contact cmat apply range contact type 'ball-facet' end_command io.out('Contact parameters set successfully (ball-ball: 2e8 Pa, ball-facet: 4e8 Pa).') end fish define reduce_damping_for_flow io.out('===== Setting Damping for Dense Flow =====') io.out('Setting damping to 0.15 for dense flow through 1.2m caving gates...') command ; Set ball-ball contact parameters (default for all contacts first) contact cmat default model linear method deformability emod 2e8 kratio 2.5 property fric 0.5 dp_nratio 0.15 dp_sratio 0.15 contact cmat apply ; Then override ball-facet contacts with different emod contact cmat add model linear method deformability emod 4e8 kratio 2.5 property fric 0.5 dp_nratio 0.15 dp_sratio 0.15 range contact type 'ball-facet' contact cmat apply range contact type 'ball-facet' ball property 'dp_nratio' 0.15 'dp_sratio' 0.15 end_command io.out('Damping set to 0.15 - dense flow mode enabled') io.out('Particles will flow in sliding-rolling mode through 1.2m gates') io.out('===============================================') end fish define visualize_layers io.out('===== Visualization Setup =====') io.out('Layers are ready for visualization') io.out('Use PFC interface to set colors manually if needed') io.out('===============================================') end fish define stepwise_coal_mining io.out('===== Starting Stepwise Coal Mining =====') io.out('*** WAITING FOR EQUILIBRIUM BEFORE STEPWISE MINING ***') io.out('Checking equilibrium status...') local current_ratio = mech_ratio io.out('Current mechanical ratio: ' + string(current_ratio, 6)) if current_ratio > 1e-3 io.out('System not in equilibrium yet. Cycling until equilibrium...') command model cycle 5000 model solve ratio-average 1e-3 end_command current_ratio = mech_ratio io.out('After cycling, mechanical ratio: ' + string(current_ratio, 6)) endif if current_ratio <= 1e-3 io.out('*** EQUILIBRIUM ACHIEVED - STARTING STEPWISE MINING ***') local step_distance = 0.6 local total_mining_length = 10.6 ; 娣囶喗娑.6缁 local gangue_threshold = 0.05 io.out('Stepwise mining parameters:') io.out(' Step distance: ' + string(step_distance) + 'm') io.out(' Total mining length: ' + string(total_mining_length) + 'm') io.out(' Total steps: ' + string(total_steps)) io.out(' Gangue threshold: ' + string(gangue_threshold*100) + '%') global total_coal_mined = 0.0 global total_gangue_mined = 0.0 global current_step = 0 loop local step (1, total_steps) current_step = step local current_position = 15.0 + (step - 1) * step_distance io.out('') io.out('===== Mining Step ' + string(step) + ' of ' + string(total_steps) + ' =====') io.out('Current position: ' + string(current_position, 1) + 'm') local gate_opened = open_caving_gate(current_position) if gate_opened io.out('*** CAVING GATE OPENED - WAITING FOR PARTICLE SETTLEMENT ***') local settlement_cycles = 0 local max_settlement_cycles = 30000 local stable_cycles = 0 local max_stable_cycles = 5 local last_total_discharged = 0.0 local last_mech_ratio = 1.0 loop while settlement_cycles < max_settlement_cycles command model cycle 1000 end_command settlement_cycles = settlement_cycles + 1000 if (settlement_cycles % 5000) == 0 local coal_discharged = calculate_discharged_coal_mass() local gangue_discharged = calculate_discharged_gangue_mass() local total_discharged = coal_discharged + gangue_discharged local gangue_ratio = 0.0 local current_mech_ratio = mech_ratio if total_discharged > 0.0 gangue_ratio = gangue_discharged / total_discharged endif io.out('Settlement cycle ' + string(settlement_cycles) + ':') io.out(' Coal discharged: ' + string(coal_discharged, 0) + ' kg') io.out(' Gangue discharged: ' + string(gangue_discharged, 0) + ' kg') io.out(' Gangue ratio: ' + string(gangue_ratio*100, 1) + '%') io.out(' Mechanical ratio: ' + string(current_mech_ratio, 6)) local mass_change = math.abs(total_discharged - last_total_discharged) local ratio_change = math.abs(current_mech_ratio - last_mech_ratio) if mass_change < 1.0 and ratio_change < 1e-4 stable_cycles = stable_cycles + 1 io.out(' System stable for ' + string(stable_cycles) + ' cycles') else stable_cycles = 0 io.out(' System still flowing... (mass change: ' + string(mass_change, 1) + ' kg)') endif last_total_discharged = total_discharged last_mech_ratio = current_mech_ratio if stable_cycles >= max_stable_cycles io.out('*** PARTICLE SETTLEMENT COMPLETED - SYSTEM STABLE ***') break endif endif endloop local step_coal_mass = calculate_discharged_coal_mass() local step_gangue_mass = calculate_discharged_gangue_mass() local step_total = step_coal_mass + step_gangue_mass gangue_ratio = 0.0 if step_total > 0.0 gangue_ratio = step_gangue_mass / step_total endif total_coal_mined = total_coal_mined + step_coal_mass total_gangue_mined = total_gangue_mined + step_gangue_mass io.out('Step ' + string(step) + ' results:') io.out(' Coal mined: ' + string(step_coal_mass, 1) + ' kg') io.out(' Gangue mined: ' + string(step_gangue_mass, 1) + ' kg') io.out(' Gangue ratio: ' + string(gangue_ratio*100, 1) + '%') io.out(' Cumulative coal: ' + string(total_coal_mined, 0) + ' kg') io.out(' Cumulative gangue: ' + string(total_gangue_mined, 0) + ' kg') if gangue_ratio >= gangue_threshold io.out('Gangue ratio ' + string(gangue_ratio*100, 1) + '% >= ' + string(gangue_threshold*100) + '% - closing gate') close_caving_gate(current_position) else io.out('Gangue ratio ' + string(gangue_ratio*100, 1) + '% < ' + string(gangue_threshold*100) + '% - gate remains open') endif else io.out('No caving gate found at position ' + string(current_position, 1) + 'm') endif command model cycle 1000 model solve ratio-average 1e-3 end_command endloop local total_mined = total_coal_mined + total_gangue_mined local overall_gangue_ratio = 0.0 local coal_recovery_rate = 0.0 if total_mined > 0.0 overall_gangue_ratio = total_gangue_mined / total_mined coal_recovery_rate = (total_coal_mined / total_mined) * 100 endif io.out('') io.out('===== Stepwise Mining Completed =====') io.out('Total mining length: ' + string(total_mining_length) + 'm') io.out('Total steps completed: ' + string(total_steps)) io.out('Total coal mined: ' + string(total_coal_mined, 0) + ' kg') io.out('Total gangue mined: ' + string(total_gangue_mined, 0) + ' kg') io.out('Overall gangue ratio: ' + string(overall_gangue_ratio*100, 1) + '%') io.out('Coal recovery rate: ' + string(coal_recovery_rate, 1) + '%') else io.out('*** EQUILIBRIUM NOT ACHIEVED - MINING CANNOT START ***') io.out('Current ratio: ' + string(current_ratio, 6) + ' > 1e-3') endif io.out('===============================================') end fish define debug_caving_gates io.out('===== Debug: Caving Gates Information =====') local gate_count = 0 loop foreach wp wall.list if wall.group(wp) == 'caving_gate' gate_count = gate_count + 1 local wall_pos = wall.pos(wp) local wall_x = wall_pos->x local wall_center_x = wall_x + 0.75 io.out('Gate ' + string(gate_count) + ': wall_x=' + string(wall_x, 1) + 'm, center=' + string(wall_center_x, 1) + 'm, ID=' + string(wall.id(wp))) endif endloop io.out('Total caving gates found: ' + string(gate_count)) io.out('===============================================') end fish define open_caving_gate(position) local gate_opened = false local gate_tolerance = 1.0 io.out('Looking for caving gate near position: ' + string(position, 1) + 'm') loop foreach wp wall.list if wall.group(wp) == 'caving_gate' local wall_pos = wall.pos(wp) local wall_x = wall_pos->x local wall_center_x = wall_x + 0.6 io.out('Found caving gate at wall_x=' + string(wall_x, 1) + 'm, center=' + string(wall_center_x, 1) + 'm') if math.abs(wall_center_x - position) <= gate_tolerance command wall delete range id [wall.id(wp)] end_command gate_opened = true io.out('*** CAVING GATE OPENED *** 1.2m opening created at position ' + string(position, 1) + 'm') io.out('Wall ID ' + string(wall.id(wp)) + ' deleted - gate is now open!') break endif endif endloop if not gate_opened io.out('No caving gate found near position ' + string(position, 1) + 'm') endif [return_value] = gate_opened end fish define close_caving_gate(position) local gate_closed = false local gate_tolerance = 0.3 ; Tolerance for gate position matching ; Note: In this implementation, gates are deleted when opened ; Closing would require recreating the gate wall ; For simplicity, we just mark as closed gate_closed = true io.out('Closed caving gate at position ' + string(position, 1) + 'm') [return_value] = gate_closed end fish define calculate_discharged_coal_mass local discharged_mass = 0.0 loop foreach bp ball.list local pos = ball.pos(bp) local py = pos->y ; Check if ball is below support level (discharged) if py < support_top_height local ball_group = ball.group(bp) if ball_group == 'top_coal' or ball_group == 'immediate_roof' if ball.density(bp) <= 1400 ; Coal density threshold local ball_mass = ball.mass(bp) if ball_mass > 0.0 discharged_mass = discharged_mass + ball_mass ball.group(bp) = 'discharged_coal' endif endif endif endif endloop [return_value] = discharged_mass end fish define calculate_discharged_gangue_mass local discharged_mass = 0.0 loop foreach bp ball.list local pos = ball.pos(bp) local py = pos->y ; Check if ball is below support level (discharged) if py < support_top_height local ball_group = ball.group(bp) if ball_group == 'top_coal' or ball_group == 'immediate_roof' if ball.density(bp) >= 2500 ; Gangue density threshold local ball_mass = ball.mass(bp) if ball_mass > 0.0 discharged_mass = discharged_mass + ball_mass ball.group(bp) = 'discharged_gangue' endif endif endif endif endloop [return_value] = discharged_mass end fish define calculate_mass_statistics io.out('===== Mass Statistics =====') local total_coal_mass = 0.0 local total_gangue_mass = 0.0 local caved_coal_mass = 0.0 local caved_gangue_mass = 0.0 loop foreach bp ball.list local ball_density = ball.density(bp) local ball_mass = ball.mass(bp) local ball_group = ball.group(bp) if ball_mass > 0.0 if ball_density <= 1400 total_coal_mass = total_coal_mass + ball_mass if ball_group == 'caved_coal' caved_coal_mass = caved_coal_mass + ball_mass endif else if ball_density >= 2500 total_gangue_mass = total_gangue_mass + ball_mass if ball_group == 'caved_gangue' caved_gangue_mass = caved_gangue_mass + ball_mass endif endif endif endif endloop local caving_area = caving_gates * support_width io.out('Original mass:') io.out(' Total coal: ' + string(total_coal_mass, 0) + ' kg') io.out(' Total gangue: ' + string(total_gangue_mass, 0) + ' kg') io.out('') io.out('Caved mass:') io.out(' Caved coal: ' + string(caved_coal_mass, 0) + ' kg') io.out(' Caved gangue: ' + string(caved_gangue_mass, 0) + ' kg') io.out('') io.out('Caving area: ' + string(caving_area, 1) + ' m2') if total_coal_mass > 0.0 io.out('Coal recovery rate: ' + string((caved_coal_mass/total_coal_mass)*100, 1) + '%') else io.out('Coal recovery rate: 0% (no coal mass)') endif if total_gangue_mass > 0.0 io.out('Gangue recovery rate: ' + string((caved_gangue_mass/total_gangue_mass)*100, 1) + '%') else io.out('Gangue recovery rate: 0% (no gangue mass)') endif io.out('') io.out('Mass per unit area:') if caving_area > 0.0 io.out(' Coal: ' + string(caved_coal_mass/caving_area, 1) + ' kg/m2') io.out(' Gangue: ' + string(caved_gangue_mass/caving_area, 1) + ' kg/m2') io.out(' Total: ' + string((caved_coal_mass+caved_gangue_mass)/caving_area, 1) + ' kg/m2') else io.out(' Mass per unit area: 0 kg/m2 (no caving area)') endif io.out('===============================================') end ; ======================================== ; ======================================== fish define print_simulation_info io.out('Longwall Mining Simulation Started') io.out('Model parameters:') io.out(' Bottom coal height: ' + string(bottom_coal_height) + 'm (Cutting)') io.out(' Top coal height: ' + string(top_coal_height) + 'm (Caving)') io.out(' Total coal height: ' + string(total_coal_height) + 'm') io.out(' Gangue layers: ' + string(gangue_layers) + ' layers') io.out(' Immediate roof: ' + string(immediate_roof_thickness) + 'm Siltstone') io.out(' Main roof: ' + string(main_roof_thickness) + 'm Fine Sandstone') io.out(' Support layout: ' + string(total_support_num) + ' frames total') io.out(' Head supports: ' + string(head_support_num) + ' frames (no caving)') io.out(' Middle supports: ' + string(support_num) + ' frames (with caving)') io.out(' Caving gates: ' + string(caving_gates) + ' (1 per middle support)') io.out(' Gangue threshold: ' + string(gangue_threshold*100) + ' percent') io.out('==============================================') local total_mined = total_coal_mass + total_gangue_mass if total_mined > 0.0 io.out('===== Simulation Completed =====') io.out('Final results:') io.out(' Total coal mined: ' + string(total_coal_mass, 0) + 'kg') io.out(' Total gangue mined: ' + string(total_gangue_mass, 0) + 'kg') io.out(' Recovery rate: ' + string((total_coal_mass/total_mined)*100, 1) + '%') else io.out('===== Simulation Completed =====') io.out('Final results:') io.out(' Total coal mined: ' + string(total_coal_mass, 0) + 'kg') io.out(' Total gangue mined: ' + string(total_gangue_mass, 0) + 'kg') io.out(' Recovery rate: 0% (no material mined)') endif io.out('================================') end [print_simulation_info] [create_supports] [generate_bottom_coal] [generate_top_coal] [generate_immediate_roof] [balance_model] [set_contact_parameters] [reduce_damping_for_flow] [visualize_layers] [debug_caving_gates] [stepwise_coal_mining] [calculate_mass_statistics] fish define calculate_coal_statistics io.out('===== Coal Mining Results =====') local total_top_coal_mass = 0.0 local total_gangue_mass = 0.0 local discharged_coal_mass = 0.0 local discharged_gangue_mass = 0.0 loop foreach bp ball.list local ball_density = ball.density(bp) local ball_mass = ball.mass(bp) local ball_group = ball.group(bp) if ball_mass > 0.0 if ball_group == 'top_coal' total_top_coal_mass = total_top_coal_mass + ball_mass else if ball_group == 'immediate_roof' total_gangue_mass = total_gangue_mass + ball_mass else if ball_group == 'discharged_coal' discharged_coal_mass = discharged_coal_mass + ball_mass else if ball_group == 'discharged_gangue' discharged_gangue_mass = discharged_gangue_mass + ball_mass endif endif endif endif endif endloop local total_coal_mass = total_top_coal_mass local total_discharged_mass = discharged_coal_mass + discharged_gangue_mass io.out('===== Original Coal Reserves =====') io.out('Top coal mass: ' + string(total_top_coal_mass, 0) + ' kg') io.out('Gangue mass: ' + string(total_gangue_mass, 0) + ' kg') io.out('Total coal reserves: ' + string(total_coal_mass, 0) + ' kg') io.out('') io.out('===== Mining Production =====') io.out('Coal mined: ' + string(discharged_coal_mass, 0) + ' kg') io.out('Gangue mined: ' + string(discharged_gangue_mass, 0) + ' kg') io.out('Total mined: ' + string(total_discharged_mass, 0) + ' kg') io.out('') local coal_recovery_rate = 0.0 local gangue_discharge_rate = 0.0 local gangue_ratio = 0.0 local mining_efficiency = 0.0 if total_coal_mass > 0.0 coal_recovery_rate = (discharged_coal_mass / total_coal_mass) * 100 endif if total_gangue_mass > 0.0 gangue_discharge_rate = (discharged_gangue_mass / total_gangue_mass) * 100 endif if total_discharged_mass > 0.0 gangue_ratio = (discharged_gangue_mass / total_discharged_mass) * 100 mining_efficiency = (discharged_coal_mass / total_discharged_mass) * 100 endif io.out('===== Key Performance Indicators =====') io.out('Coal recovery rate: ' + string(coal_recovery_rate, 1) + '%') io.out('Gangue discharge rate: ' + string(gangue_discharge_rate, 1) + '%') io.out('Gangue ratio in production: ' + string(gangue_ratio, 1) + '%') io.out('Mining efficiency: ' + string(mining_efficiency, 1) + '%') io.out('') io.out('===== Economic Indicators =====') local coal_volume = total_coal_mass / 1360.0 local mined_volume = total_discharged_mass / 1500.0 io.out('Coal volume: ' + string(coal_volume, 1) + ' m3') io.out('Mined volume: ' + string(mined_volume, 1) + ' m3') io.out('') io.out('===== Summary =====') if gangue_ratio <= 5.0 io.out('Mining successful: Gangue ratio ' + string(gangue_ratio, 1) + '% <= 5%') else io.out('Mining stopped: Gangue ratio ' + string(gangue_ratio, 1) + '% > 5%') endif if coal_recovery_rate >= 80.0 io.out('Good recovery: ' + string(coal_recovery_rate, 1) + '% >= 80%') else io.out('Low recovery: ' + string(coal_recovery_rate, 1) + '% < 80%') endif io.out('===============================================') end fish define control_particle_numbers io.out('===== Particle Number Control =====') io.out('Total particles will be limited to 2,000') io.out('Model dimensions:') io.out(' Total width: ' + string(model_width) + 'm') io.out(' Effective mining width: 60.0m (X: 3-63m)') io.out(' Boundary buffer: 6.0m (3m each side)') io.out(' Total height: 31.4m (Y: 0-31.4m)') io.out('Layer structure:') io.out(' Bottom layer: Top coal (15.8m height)') io.out(' Top layer: Immediate roof (15.6m height)') io.out('Distribution:') io.out(' Top coal: 1,000 particles (50%)') io.out(' Immediate roof: 1,000 particles (50%)') io.out(' Total: 2,000 particles') io.out('===============================================') end fish define visualize_modeling_process io.out('===== Modeling Process Visualization =====') io.out('Step 1: Generating top coal particles...') io.out('Step 2: Generating immediate roof particles (gangue)...') io.out('Step 3: Model balancing...') io.out('Step 4: Sequential caving simulation...') io.out('Step 5: Results calculation...') io.out('===============================================') end ; modeling_sequence function removed - using main execution sequence instead fish define detailed_mining_report io.out('===== Detailed Mining Report =====') local total_particles = 0 local top_coal_particles = 0 local gangue_particles = 0 local discharged_coal_particles = 0 local discharged_gangue_particles = 0 loop foreach bp ball.list total_particles = total_particles + 1 local ball_group = ball.group(bp) if ball_group == 'top_coal' top_coal_particles = top_coal_particles + 1 else if ball_group == 'immediate_roof' gangue_particles = gangue_particles + 1 else if ball_group == 'discharged_coal' discharged_coal_particles = discharged_coal_particles + 1 else if ball_group == 'discharged_gangue' discharged_gangue_particles = discharged_gangue_particles + 1 endif endif endif endif endloop io.out('Particle Statistics:') io.out(' Total particles: ' + string(total_particles)) io.out(' Top coal particles: ' + string(top_coal_particles)) io.out(' Gangue particles: ' + string(gangue_particles)) io.out(' Discharged coal particles: ' + string(discharged_coal_particles)) io.out(' Discharged gangue particles: ' + string(discharged_gangue_particles)) io.out('') local remaining_coal = top_coal_particles - discharged_coal_particles local remaining_gangue = gangue_particles - discharged_gangue_particles io.out('Remaining Particles:') io.out(' Remaining coal: ' + string(remaining_coal)) io.out(' Remaining gangue: ' + string(remaining_gangue)) io.out(' Total remaining: ' + string(remaining_coal + remaining_gangue)) io.out('===============================================') end fish define calculate_mining_area_statistics io.out('===== Mining Area Statistics =====') io.out('Total model width: ' + string(model_width) + 'm') io.out('Boundary buffer (each side): ' + string(boundary_buffer) + 'm') io.out('Effective mining width: ' + string(effective_mining_width) + 'm') io.out('Mining area: X = ' + string(mining_start_x) + ' to ' + string(mining_end_x) + 'm') io.out('Boundary areas (not included in mining statistics):') io.out(' Left boundary: X = 0 to ' + string(mining_start_x) + 'm') io.out(' Right boundary: X = ' + string(mining_end_x) + ' to ' + string(model_width) + 'm') io.out('===============================================') end fish define support_position_info io.out('===== Support Position Information =====') io.out('Support layout with 3m right offset:') io.out('') io.out('Head supports (3 frames):') io.out(' Support 1: X = 3.0m to 4.5m') io.out(' Support 2: X = 4.5m to 6.0m') io.out(' Support 3: X = 6.0m to 7.5m') io.out('') io.out('Middle supports (' + string(support_num) + ' frames):') io.out(' Start position: X = 7.5m') io.out(' End position: X = ' + string(7.5 + support_num * support_width) + 'm') io.out(' Spacing: ' + string(support_width) + 'm between frames') io.out('') io.out('Tail supports (3 frames):') local tail_start = 7.5 + support_num * support_width io.out(' Support 1: X = ' + string(tail_start) + 'm to ' + string(tail_start + 1.5) + 'm') io.out(' Support 2: X = ' + string(tail_start + 1.5) + 'm to ' + string(tail_start + 3.0) + 'm') io.out(' Support 3: X = ' + string(tail_start + 3.0) + 'm to ' + string(tail_start + 4.5) + 'm') io.out('') io.out('Total support coverage: X = 3.0m to ' + string(tail_start + 4.5) + 'm') io.out('===============================================') end fish define verify_immediate_roof_position io.out('===== Immediate Roof Position Verification =====') local particles_in_x_range = 0 local particles_in_y_range = 0 local particles_in_full_range = 0 local particles_out_of_range = 0 local min_x = 1000.0 local max_x = -1000.0 local min_y = 1000.0 local max_y = -1000.0 loop foreach bp ball.list if ball.group(bp) == 'immediate_roof' local pos = ball.pos(bp) local px = pos->x local py = pos->y if px >= 3.0 and px <= 63.0 particles_in_x_range = particles_in_x_range + 1 endif if py >= 0.0 and py <= 31.5 particles_in_y_range = particles_in_y_range + 1 endif if px >= 3.0 and px <= 63.0 and py >= 0.0 and py <= 31.5 particles_in_full_range = particles_in_full_range + 1 else particles_out_of_range = particles_out_of_range + 1 endif if px < min_x min_x = px endif if px > max_x max_x = px endif if py < min_y min_y = py endif if py > max_y max_y = py endif endif endloop io.out('Position verification results:') io.out(' Particles in X range (3-63m): ' + string(particles_in_x_range)) io.out(' Particles in Y range (0-31.5m): ' + string(particles_in_y_range)) io.out(' Particles in full range: ' + string(particles_in_full_range)) io.out(' Particles out of range: ' + string(particles_out_of_range)) io.out(' Actual X range: ' + string(min_x, 2) + ' to ' + string(max_x, 2) + 'm') io.out(' Actual Y range: ' + string(min_y, 2) + ' to ' + string(max_y, 2) + 'm') io.out(' Expected X range: 3.0 to 63.0m') io.out(' Expected Y range: 0.0 to 31.5m') if particles_out_of_range == 0 io.out('Bouncing prevention activated (particles_out_of_range = 0)') prevent_bouncing() command model cycle 50 model solve ratio-average 1e-3 end_command loop foreach bp ball.list ball.vel.x(bp) = 0.0 ball.vel.y(bp) = 0.0 ball.spin(bp) = 0.0 endloop endif local overall_gangue_ratio = 0.0 if (total_coal_mass + total_gangue_mass) > 0.0 overall_gangue_ratio = total_gangue_mass / (total_coal_mass + total_gangue_mass) endif io.out('===== Single Round Interval Caving Completed =====') io.out('Caving area: ' + string(caving_area, 1) + ' m2 (17 odd-numbered supports)') io.out('Total coal mined: ' + string(total_coal_mass, 0) + ' kg') io.out('Total gangue mined: ' + string(total_gangue_mass, 0) + ' kg') io.out('Overall gangue ratio: ' + string(overall_gangue_ratio*100, 1) + '%') io.out('Coal recovery rate: ' + string((total_coal_mass/(total_coal_mass + total_gangue_mass))*100, 1) + '%') io.out('Interval caving: Only odd-numbered gates (1,3,5,...,33) were processed') io.out('Boundary areas (6m each end): Particles remain constrained') io.out('===============================================') end ; ======================================== ; ======================================== fish define fix_boundary_walls io.out('===== Fixing Boundary Walls =====') command wall delete range id 103 wall delete range id 104 end_command command wall create vertices 3.0 0 3.0 31.4 id 103 wall attribute velocity-x 0.0 range id 103 end_command io.out('Left buffer wall (ID 103) created at X=3.0m') command wall create vertices 63.0 0 63.0 31.4 id 104 wall attribute velocity-x 0.0 range id 104 end_command io.out('Right buffer wall (ID 104) created at X=63.0m') io.out('Boundary walls fixed - particles should be constrained') io.out('===============================================') end fish define check_particle_boundaries io.out('===== Checking Particle Boundaries =====') local particles_in_left_buffer = 0 local particles_in_right_buffer = 0 local particles_in_mining_area = 0 local total_particles = 0 loop foreach bp ball.list total_particles = total_particles + 1 local pos = ball.pos(bp) local px = pos->x if px < 3.0 particles_in_left_buffer = particles_in_left_buffer + 1 else if px > 63.0 particles_in_right_buffer = particles_in_right_buffer + 1 else particles_in_mining_area = particles_in_mining_area + 1 endif endif endloop io.out('Particle boundary analysis:') io.out(' Total particles: ' + string(total_particles)) io.out(' Particles in left buffer (X<3.0m): ' + string(particles_in_left_buffer)) io.out(' Particles in mining area (3.0m to 63.0m): ' + string(particles_in_mining_area)) io.out(' Particles in right buffer (X>63.0m): ' + string(particles_in_right_buffer)) if particles_in_left_buffer > 0 or particles_in_right_buffer > 0 io.out('WARNING: Particles found in buffer zones!') io.out('Boundary walls may not be working properly') else io.out('SUCCESS: All particles are in mining area') endif io.out('===============================================') end fish define enhanced_equilibrium_check io.out('===== Enhanced Equilibrium Check =====') local mech_ratio = mech_ratio io.out('Mechanical ratio: ' + string(mech_ratio, 6)) local total_ke = 0.0 loop foreach bp ball.list local vel = ball.vel(bp) local mass = ball.mass(bp) total_ke = total_ke + 0.5 * mass * (vel->x^2 + vel->y^2) endloop io.out('Total kinetic energy: ' + string(total_ke, 6)) local is_equilibrium = false if mech_ratio <= 1e-3 and total_ke < 1e-6 is_equilibrium = true endif if is_equilibrium io.out('SUCCESS: System is in equilibrium!') else io.out('WARNING: System not in equilibrium') if mech_ratio > 1e-3 io.out(' - Mechanical ratio too high: ' + string(mech_ratio, 6)) endif if total_ke > 1e-6 io.out(' - Kinetic energy too high: ' + string(total_ke, 6)) endif endif io.out('===============================================') [return_value] = is_equilibrium end对代码进行分析
最新发布
09-26
### 3D Object Detection ROI Head Implementation and Usage In three-dimensional (3D) object detection frameworks, Region-of-Interest Heads (ROI Heads) play an essential role similar to their counterparts in two-dimensional (2D) detectors like Faster R-CNN[^2]. An ROI Head processes candidate regions generated by a region proposal network or other means, refining these proposals into final bounding boxes with associated class labels. For 3D object detection, the input data typically includes point clouds from LiDAR sensors or depth images. The process involves several stages: #### Feature Extraction A backbone network extracts features from raw sensor inputs such as voxelized point cloud grids or multi-view images. These extracted features serve as the basis for subsequent processing steps within the ROI Head. #### Proposal Generation Proposals are generated either through dedicated networks designed specifically for 3D space—such as PointPillars—or adapted versions of traditional 2D methods applied across multiple views or slices of volumetric representations. #### Refinement via ROI Pooling/Align Operations Once proposals have been identified, they undergo refinement using operations analogous to those found in standard 2D implementations but tailored towards handling spatial information inherent in 3D datasets. This often entails applying pooling techniques that aggregate local descriptors around each proposed box location before feeding them into fully connected layers responsible for classification and regression tasks. Here’s how this might look implemented in Python code targeting PyTorch-based architectures commonly employed in modern deep learning pipelines: ```python import torch.nn.functional as F from torchvision.ops import roi_align class ROIPooler(nn.Module): def __init__(self, output_size=(7, 7), sampling_ratio=2): super().__init__() self.output_size = output_size self.sampling_ratio = sampling_ratio def forward(self, feature_maps, rois): """ Args: feature_maps (Tensor): A tensor containing all feature maps. Shape should be [batch_size, channels, height, width]. rois (List[Tensor]): List of tensors where each element corresponds to one image, holding N RoIs given as [batch_index, x1, y1, z1, x2, y2, z2]. Returns: Tensor: Pooled features corresponding to provided RoIs. Shape will be [total_num_rois, channels * H_out * W_out], assuming `output_size` was specified appropriately during initialization. """ pooled_features = [] # Iterate over individual batches/images contained within 'rois' for img_idx, per_image_roi in enumerate(rois): # Select relevant slice(s) from full set of feature maps based on current batch index selected_feature_map = feature_maps[[img_idx]] # Perform alignment operation ensuring correct mapping between original coordinates & grid cells post-extraction aligned_boxes = convert_to_normalized_coordinates(per_image_roi[:, 1:], h=feature_maps.shape[-2], w=feature_maps.shape[-1]) # Apply ROI Align function directly available within torchvision library result = roi_align(selected_feature_map, boxes=[aligned_boxes], output_size=self.output_size, spatial_scale=1., sampling_ratio=self.sampling_ratio) pooled_features.append(result.flatten(start_dim=1)) return torch.cat(pooled_features) def convert_to_normalized_coordinates(boxes, h, w): """Convert absolute coordinate values into normalized form suitable for use with ROI align.""" new_boxes = boxes.clone() new_boxes[..., :2] /= w new_boxes[..., 2:] /= h return new_boxes ``` This example demonstrates basic functionality required when implementing custom ROI heads suited for working with 3D objects represented via structured grids derived from point clouds or stereo vision systems. Note that actual deployment scenarios may require additional considerations depending upon specific application requirements and hardware constraints present at runtime.
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值