13.8.4. Macro “reoptimizeHollowBarVizirMoead.C

13.8.4.1. Objective

The objective of the macro is to optimize the section and distortion of the hollow bar defined in Sizing of a hollow bar example problem using the evolutionary solvers, with a reduce number of points to compose the Pareto set/front. This example is comparing both the usual Vizir genetic algorithm and the MOEAD implementation that is meant to be a many-objective criteria algorithm. A short discussion on the many-objective aspect can be found in [Bla17].

13.8.4.2. Macro Uranie

    #define nbPoints 20
    #define total 4*nbPoints

    using namespace URANIE::DataServer;
    using namespace URANIE::Relauncher;
    using namespace URANIE::Reoptimizer;

    // variables
    TAttribute x("x", 0.0, 1.0),
      y("y", 0.0, 1.0),
      thick("thick"), // thickness
      sect("sect"), // section of the pipe
      dist("dist"); // distortion

     gROOT->LoadMacro("UserFunctions.C");

    // Creating the assessor using the analytical function
    TCIntEval code("barAllCost");
    code.addInput(&x);
    code.addInput(&y);
    code.addOutput(&thick);
    code.addOutput(&sect);
    code.addOutput(&dist);

    // Create a runner
    TSequentialRun runner(&code);
    runner.startSlave(); // Usual Relauncher construction

    int nMax=3000;
    if(runner.onMaster())
    {
        // ==================================================
        // ========= Classical Vizir implementation =========
        // ==================================================

        // Create the TDS
        TDataServer tds_viz("vizirDemo", "Vizir parameter dataser");
        tds_viz.addAttribute(&x);
        tds_viz.addAttribute(&y);

        // create the vizir genetic solver
        TVizirGenetic solv_viz;
        // Set the size of the population to 150, and a maximum number of evaluation at 15000
        solv_viz.setSize(nbPoints,nMax);

        // Create the multi-objective constrained optimizer
        TVizir2 opt_viz(&tds_viz, &runner, &solv_viz);

         // add the objective
        opt_viz.addObjective(&sect); // minimizing the section
        opt_viz.addObjective(&dist); // minimizing the distortion

        // and the constrains
        TGreaterFit positiv(0.4);
        opt_viz.addConstraint(&thick,&positiv);  //on thickness (thick > 0.4)

        opt_viz.solverLoop(); // running the optimization

        // ==================================================
        // ============== MOEAD implementation ==============
        // ==================================================

         // Create the TDS
        TDataServer tds_moead("vizirDemo", "Vizir parameter dataser");
        tds_moead.addAttribute(&x);
        tds_moead.addAttribute(&y);

        // create the vizir genetic solver
        TVizirGenetic solv_moead;
        solv_moead.setMoeadDiversity(nbPoints);
        solv_moead.setStoppingCriteria(1);
        solv_moead.setSize(0, nMax, 200);

        // Create the multi-objective constrained optimizer
        TVizir2 opt_moead(&tds_moead, &runner, &solv_moead);

        // add the objective
        opt_moead.addObjective(&sect); // minimizing the section
        opt_moead.addObjective(&dist); // minimizing the distortion

        opt_moead.addConstraint(&thick,&positiv);  //on thickness (thick > 0.4)

        opt_moead.solverLoop(); // running the optimization

        // Stop the slave processes
        runner.stopSlave();


        // Start the graphical part
        // Preaparing canvas
        TCanvas *fig1 = new TCanvas("fig1","Pareto Zone",5,64,1270,667);
        TPad *pad1 = new TPad("pad1","",0,0.03,1,1);
        pad1->Draw();
        pad1->Divide(2,1); pad1->cd(1);

        // extracting data to construct graphs
        double viz[total], moead[total+4]; // There is always one more point in moead
        tds_viz.getTuple()->extractData(viz, total, "x:y:sect:dist","","column");
        tds_moead.getTuple()->extractData(moead, total+4, "x:y:sect:dist","","column");

        TGraph *set_viz = new TGraph(nbPoints, &viz[0], &viz[nbPoints]);
        TGraph *front_viz = new TGraph(nbPoints, &viz[2*nbPoints], &viz[3*nbPoints]);
        set_viz->SetMarkerColor(4); set_viz->SetMarkerStyle(20); set_viz->SetMarkerSize(0.8);
        front_viz->SetMarkerColor(4); front_viz->SetMarkerStyle(20); front_viz->SetMarkerSize(0.8);

        TGraph *set_moead = new TGraph(nbPoints+1, &moead[0], &moead[nbPoints+1]);
        TGraph *front_moead = new TGraph(nbPoints, &moead[2*(nbPoints+1)], &moead[3*(nbPoints+1)]);
        set_moead->SetMarkerColor(2); set_moead->SetMarkerStyle(20); set_moead->SetMarkerSize(0.8);
        front_moead->SetMarkerColor(2); front_moead->SetMarkerStyle(20); front_moead->SetMarkerSize(0.8);

        // Legend
        TLegend *leg = new TLegend(0.25, 0.75, 0.55, 0.89);
        leg->AddEntry(set_viz,"Vizir algo","p");
        leg->AddEntry(set_moead,"MOEAD algo","p");

        // Pareto Set
        TMultiGraph *set_mg = new TMultiGraph();
        set_mg->Add(set_viz); set_mg->Add(set_moead);
        set_mg->Draw("aP");
        set_mg->SetTitle("Pareto Set"); set_mg->GetXaxis()->SetTitle("x"); set_mg->GetYaxis()->SetTitle("y");
        leg->Draw();
        gPad->Update();

        // Pareto Front
        pad1->cd(2);
        TMultiGraph *front_mg = new TMultiGraph();
        front_mg->Add(front_viz); front_mg->Add(front_moead);
        front_mg->Draw("aP");
        front_mg->SetTitle("Pareto front"); front_mg->GetXaxis()->SetTitle("Section"); front_mg->GetYaxis()->SetTitle("Distortion");
        leg->Draw();
        gPad->Update();
    }

The variables are defined as follow:

    // variables
    TAttribute x("x", 0.0, 1.0),
      y("y", 0.0, 1.0),
      thick("thick"), // thickness
      sect("sect"), // section of the pipe
      dist("dist"); // distortion

where the first two are the input ones while the last ones are computed using the provided code (as explained in Sizing of a hollow bar example problem). This code is configured through these lines

    // Creating the assessor using the analytical function
    TCIntEval code("barAllCost");
    code.addInput(&x);
    code.addInput(&y);
    code.addOutput(&thick);
    code.addOutput(&sect);
    code.addOutput(&dist);

The usual Relauncher construction is followed, using a TSequentialRun runner. The first solver is defined in these lines

        TVizirGenetic solv_viz;
        // Set the size of the population to 150, and a maximum number of evaluation at 15000
        solv_viz.setSize(nbPoints,nMax);

Combining the runner, solver and dataserver, the master object is created and the objective and constraint are defined. This is done in:

        // Create the multi-objective constrained optimizer
        TVizir2 opt_viz(&tds_viz, &runner, &solv_viz);

         // add the objective
        opt_viz.addObjective(&sect); // minimizing the section
        opt_viz.addObjective(&dist); // minimizing the distortion

        // and the constrains
        TGreaterFit positiv(0.4);
        opt_viz.addConstraint(&thick,&positiv);  //on thickness (thick > 0.4)

In a second block a new dataserver is created along with a new genetic solver in these lines:

        // create the vizir genetic solver
        TVizirGenetic solv_moead;
        solv_moead.setMoeadDiversity(nbPoints);
        solv_moead.setStoppingCriteria(1);
        solv_moead.setSize(0, nMax, 200);

The idea here is to use the Moead algorithm whose principle in few words is to split the space into a certain numbers of direction intervals (set by the argument in the function setMoeadDiversity). This should provide a Pareto front with a better homogeneity in the front member distribution (particularly visible here when the size of the requested ensemble is small). The second method, setStoppingCriteria(1) states that the only stopping criteria available is the total number of estimation, allowed in the setSize method. Finally, the last function to be called is the setSize one, with a peculiar first argument here: the size of the pareto can be chosen but if 0 is put (as done here) the number of elements will be the number of intervals defined previously plus one (the plus one comes from the fact that the elements are created at the edge of every interval, so for 20 intervals, there are 21 edges in total).

The rest of the code is creating the plot shown below in which both Pareto set and front are compared.

13.8.4.3. Graph

../../_images/reoptimizeHollowBarVizirMoead.png

Figure 13.57 Graph of the macro “reoptimizeHollowBarVizirMoead.C”