MainRegion.java 12.4 KB
import org.chocosolver.solver.Model;
import org.chocosolver.solver.Solution;
import org.chocosolver.solver.Solver;
import org.chocosolver.solver.constraints.Constraint;
import org.chocosolver.solver.objective.ParetoOptimizer;
import org.chocosolver.solver.variables.IntVar;

import java.io.*;
import java.util.List;
import java.util.Scanner;

public class MainRegion {
    public static void giveDomains (Model model, IntVar[] ugs, String dir, IntVar[] woodYield, IntVar[] soillossTotal,
                                    IntVar[] perc_r_Total, UG[] nodes, int R_option){
        int index = 0;
        try {
            File allUg = new File(dir + "/ugs_init.txt");
            Scanner readerUg = new Scanner(allUg);

            File myObjWood = new File(dir + "/wood_total_init.txt");
            Scanner myReaderWood = new Scanner(myObjWood);

            File myObjSoil = new File(dir + "/soilloss_total_init.txt");
            Scanner myReaderSoil = new Scanner(myObjSoil);

            String percR_dir;
            int R;
            switch(R_option) {
                case 1:
                    percR_dir = "/perc_r5_total_init.txt";
                    R = 5;
                    break;
                case 2:
                    percR_dir = "/perc_r10_total_init.txt";
                    R = 10;
                    break;
                default:
                    percR_dir = "/perc_r0_total_init.txt";
                    R = 0;
            }


            File myObjPerc_r = new File(dir + percR_dir);
            Scanner myReaderPerc_r = new Scanner(myObjPerc_r);

            while (readerUg.hasNextLine()) {
                String dataUg = readerUg.nextLine();
                String dataWood = myReaderWood.nextLine();
                String dataSoil = myReaderSoil.nextLine();

                String dataPerc_r = myReaderPerc_r.nextLine();



                if(nodes[index].valid) {
                    String[] str_split = dataUg.split(",", 0);

                    String[] str_split_wood = dataWood.split(",", 0);

                    String[] str_split_soil = dataSoil.split(",", 0);

                    String[] str_split_percr = dataPerc_r.split(",", 0);



                    int size = str_split.length;
                    int[] toInsert = new int[size];
                    int[] toInsertWood = new int[size];
                    int[] toInsertSoil = new int[size];

                    int[] toInsertPercR = new int[size];

                    for (int i = 0; i < size; i++) {
                        toInsert[i] = Integer.parseInt(str_split[i]);
                        toInsertWood[i] = (int) Float.parseFloat(str_split_wood[i]);
                        toInsertSoil[i] = (int) Float.parseFloat(str_split_soil[i]);

                        toInsertPercR[i] = (int) Float.parseFloat(str_split_percr[i]);

                    }

                    ugs[index] = model.intVar("UG_" + (index), toInsert);
                    woodYield[index] = model.intVar("Wood_Yield_" + (index), toInsertWood);
                    soillossTotal[index] = model.intVar("Soilloss_" + (index), toInsertSoil);

                    perc_r_Total[index] = model.intVar("RiskPercentileR"+R+":" + (index), toInsertPercR);


                }
                else {
                    ugs[index] = model.intVar("UG_"+(index), 0);
                    woodYield[index] = model.intVar("Wood_Yield_"+(index), 0);
                    soillossTotal[index] = model.intVar("Soilloss_" + (index), 0);

                    perc_r_Total[index] = model.intVar("RiskPercentileR"+R+":" + (index), 0);


                }

                index++;
            }

            readerUg.close();
            myReaderWood.close();
            myReaderSoil.close();

            myReaderPerc_r.close();

        } catch (FileNotFoundException e) {
            System.out.println("An error occurred.");
            e.printStackTrace();
        }
    }

    public static void main(String[] args) throws IOException {
        int areaLimit = Integer.parseInt(args[0]);
        String fileDirectory = args[1];
        String region = (args[2]);
        int option = Integer.parseInt(args[3]);
        String criterion = args[5];

        int R_option = Integer.parseInt(args[4]);
        int R;
        switch(R_option) {
            case 1:
                R = 5;
                break;
            case 2:
                R = 10;
                break;
            default:
                R = 0;}

        Model m = new Model("Forest Management");

        BufferedReader reader = new BufferedReader(new FileReader(fileDirectory + "/ugs_init.txt"));

        int nUgs = 0;
        while (reader.readLine() != null) nUgs++;
        reader.close();

        UG[] nodes = new UG[nUgs];
        UG.fillArrayRegions(nodes, fileDirectory, region, option);

        IntVar[] ugs = new IntVar[nUgs]; // same for the constraint variable array

        IntVar[] woodYield = new IntVar[nUgs];

        IntVar[] soillossTotal = new IntVar[nUgs];

        IntVar[] perc_r_Total = new IntVar[nUgs];


        giveDomains(m, ugs, fileDirectory, woodYield, soillossTotal, perc_r_Total, nodes,  R_option); // reads the ugs_init file and initializes each variable with its possible prescription values as domain


        System.out.println("running");


        for(int ugIndex = 0; ugIndex < nodes.length; ugIndex++) { //loops through every UG
            //the propagator takes as parameters the index of the UG we are starting out from
            //the nodes with all the info, the constraint variable array and the area limit
            if(nodes[ugIndex].valid) {
                new Constraint("Area Limit Constraint", new CustomPropagator2(ugIndex, nodes, ugs, areaLimit, woodYield)).post();
            }
        }


        int valids = 0;
        for(int i = 0; i < nodes.length; i++){
            if(nodes[i].valid) {
                valids++;
                //System.out.println(nodes[i].internalId);
            }
        }

        for(int i = 0; i < nodes.length; i++){
            if(nodes[i].valid) {
                IntVar prescIndex = m.intVar(0, 255);

                m.element(ugs[i], nodes[i].presc, prescIndex).post();

                m.element(woodYield[i], nodes[i].wood_total, prescIndex).post();
                m.element(soillossTotal[i], nodes[i].soilloss_total, prescIndex).post();

                switch(R_option) {
                    case 1:
                        m.element(perc_r_Total[i], nodes[i].perc_r5_total, prescIndex).post();
                        break;
                    case 2:
                        m.element(perc_r_Total[i], nodes[i].perc_r10_total, prescIndex).post();
                        break;
                    default:
                        m.element(perc_r_Total[i], nodes[i].perc_r0_total, prescIndex).post();
                }

            }
            else{
                m.arithm(woodYield[i], "=", 0).post();
                m.arithm(soillossTotal[i], "=", 0).post();
                m.arithm(perc_r_Total[i], "=", 0).post();

            }
        }

        IntVar woodSum = m.intVar("WOOD_SUM", 0, 99999999);
        IntVar soilSum = m.intVar("SOIL_SUM", -99999999, 99999999);

        IntVar percRSum = m.intVar("RiskPercentile_R"+R, 0, 99999999);

        m.sum(woodYield,"=", woodSum).post();
        m.sum(soillossTotal,"=", soilSum).post();
        m.sum(perc_r_Total,"=", percRSum).post();

        // Single Criterion Optimization
        if(criterion.equalsIgnoreCase("single")) {
            //m.setObjective(Model.MAXIMIZE, woodSum);
            //m.setObjective(Model.MAXIMIZE, soilSum);
            //m.setObjective(Model.MAXIMIZE, percRSum);

            Solver s = m.getSolver();

            if (s.solve()) {

                FileWriter outputPairs = new FileWriter("outputPairs.csv");

                for (int i = 0; i < ugs.length; i++) {
                    if (nodes[i].valid) {
                        System.out.println(ugs[i] + ", wy:" + woodYield[i] + ", sl:" + soillossTotal[i] + ", R" + R + ":" + perc_r_Total[i]);
                        outputPairs.write(nodes[i].externalId + "," + ugs[i].getValue() + "\n");
                    }

                }
                outputPairs.close();
                System.out.println(woodSum);
                System.out.println(soilSum);
                System.out.println(percRSum);


            }
        }
        else {

            //Multi Criterion with Pareto

            //ParetoOptimizer po = new ParetoOptimizer(Model.MAXIMIZE, new IntVar[]{woodSum, soilToMaximize, percToMaximize});
            ParetoOptimizer po = new ParetoOptimizer(Model.MAXIMIZE, new IntVar[]{woodSum, soilSum, percRSum});

            Solver solver = m.getSolver();
            solver.plugMonitor(po);


            FileWriter nonParetoWS = new FileWriter("nonParetoWS.csv");
            FileWriter nonParetoWR = new FileWriter("nonParetoWR.csv");
            FileWriter nonParetoSR = new FileWriter("nonParetoSR.csv");
            FileWriter nonParetoWSR = new FileWriter("nonParetoWSR.csv");
            FileWriter allSolutionPairs = new FileWriter("allSolutionPairs.csv");

            // optimization
            int l = 1;
            long startTime = System.currentTimeMillis(); //fetch starting time
            try{
                while(solver.solve() & (System.currentTimeMillis()-startTime)<28800000)
                    {
                        //System.out.println(l);
                        nonParetoWS.write(woodSum.getValue()+","+soilSum.getValue()+"\n");
                        nonParetoWR.write(woodSum.getValue()+","+percRSum.getValue()+"\n");
                        nonParetoSR.write(soilSum.getValue()+","+percRSum.getValue()+"\n");
                        nonParetoWSR.write(woodSum.getValue()+","+soilSum.getValue()+","+percRSum.getValue()+"\n");
                        allSolutionPairs.write(l+", Wood: "+ woodSum.getValue()+", Soil:"+soilSum.getValue()+
                                ", Perc_R"+R+":"+percRSum.getValue()+"\n");
                        for(int i = 0; i < nodes.length; i++){
                            if(nodes[i].valid){
                                allSolutionPairs.write(nodes[i].externalId+"."+ugs[i].getValue()+"\n");
                            }
                        }
                        l++;
                    }
                }
            catch (OutOfMemoryError e){
                System.out.println("Reached Exception");
            }

            nonParetoWS.close();
            nonParetoWR.close();
            nonParetoSR.close();
            nonParetoWSR.close();

            List<Solution> paretoFront = po.getParetoFront();

            System.out.println("The pareto front has " + paretoFront.size() + " solutions : ");
            FileWriter outputPairs = new FileWriter("outputPairsMulti"+region+"WR0.csv");

            FileWriter paretoWS = new FileWriter("paretoWS.csv");
            FileWriter paretoWR = new FileWriter("paretoWR.csv");
            FileWriter paretoSR = new FileWriter("paretoSR.csv");
            FileWriter paretoWSR = new FileWriter("paretoWSR.csv");


            int l2 = 0;
            for (Solution so : paretoFront) {
                System.out.println("Wood = " + so.getIntVal(woodSum) + ", Soil = " + so.getIntVal(soilSum)+
                        ", Perc_R"+R+":"+so.getIntVal(percRSum));
                outputPairs.write("Pareto Solution: " + l2 + ", Wood: "+so.getIntVal(woodSum)+", Soil:"+so.getIntVal(soilSum)+
                        ", Perc_R"+R+":"+so.getIntVal(percRSum)+"\n");
                for (int i = 0; i < ugs.length; i++) {
                    if (nodes[i].valid) {
                        System.out.println(ugs[i] + ", wy:" + woodYield[i] + ", sl:" + soillossTotal[i] + ", R" + R + ":" + perc_r_Total[i]);
                        outputPairs.write(nodes[i].externalId + "," +so.getIntVal(ugs[i])  + "\n");
                    }

                }

                //PARETO POINTS
                paretoWS.write(so.getIntVal(woodSum)+","+so.getIntVal(soilSum)+"\n");
                paretoWR.write(so.getIntVal(woodSum)+","+so.getIntVal(percRSum)+"\n");
                paretoSR.write(so.getIntVal(soilSum)+","+so.getIntVal(percRSum)+"\n");
                paretoWSR.write(so.getIntVal(woodSum)+","+so.getIntVal(soilSum)+","+so.getIntVal(percRSum)+"\n");



                l2++;
            }
            outputPairs.close();
            paretoWS.close();
            paretoWR.close();
            paretoSR.close();
            paretoWSR.close();
            System.out.println(l + " solutions");
        }
    }
}