Is there a way to save the cutting planes from SCIP? - optimization

I am working on using SCIP to generate cutting planes for my project. I am doing so using a C++ code directly with default plugins included, modified from scip/examples/MIPsolver/src/cppmain. However the array of cutting planes is not saved. The program will be run using the command
./scipplanes [problem file]
The affected part of my program is shown below:
/*******************
* Problem Presolving *
*******************/
/* Presolve problem */
std::cout << "=============" << std::endl;
std::cout << "Presolve problem" << std::endl;
std::cout << "=============" << std::endl;
SCIP_CALL( SCIPpresolve(scip) ); //Presolve to simplify the problem
SCIP_CALL( SCIPsetRealParam(scip, "limits/time", 60) ); //Limit of solving time in seconds
/*************************
* Obtain cutting planes *
*************************/
std::cout << "=============" << std::endl;
std::cout << "Obtaining cutting planes" << std::endl;
std::cout << "=============" << std::endl;
SCIP_ROW** allcuts; //Because SCIPgetCuts outputs this kind of data (memory address/pointer)
int n_cuts; //For for loop iteration
SCIP_CALL( SCIPsolve(scip) );
allcuts = SCIPgetCuts(scip); /*Documentation says that this outputs the array of cuts currently stored in the separation storage,
in the form of a memory address of pointer of SCIP_ROW** */
std::cout << "allcuts is " << allcuts << std::endl;
n_cuts = SCIPgetNCuts(scip);
std::cout << "n_cuts is " << n_cuts << std::endl;
When I ran my code, I obtain n_cuts = 0, but the table of statistics shows :
time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl.
60.0s| 1 | 0 | 33295 | - | 333M | 0 |1164 | 39k| 39k| 120 | 10 | 19 | 0 | 0.000000e+00 | -- | Inf | unknown
There are 120 cuts. I have double checked by running the SCIP binary and using presolve and optimize with a time limit of 60s. The results are the same when display statistics is used.
I have also tried to iterate through allcuts by doing SCIPprintRow(scip, *allcuts, NULL); , but got a segmentation fault.
Thus, I have no idea why the cutting planes are not saved. Would it be possible to offer me some advice on how to solve this problem? Thank you.

I'm pretty sure that all cuts will be freed after the solve is finished (and in any case, SCIP will remove rows from time to time). If you want all the cuts that were used at any point during the solve, you should write an event handler (with event type SCIP_EVENTTYPE_ROWEVENT) that you can use to print the rows with SCIPprintRow)
There is an example of how to write your own event handler in the examples subdirectory.

Related

Cannot create more than 6 participants in FastDDS

I am working with FastDDS and have an application that will have 10-15 writers or readers. However if I try to create more than 6 total participants, the 7th one hangs on the create_participant() function call. It blocks there indefinitely. I'll put a minimal set of code below. My environment:
Windows 10
Visual Studio 2019
FastDDS 2.6.0 (also have the same issue in 2.5.1) Installed from binaries, not built from source
int count{7};
std::vector<eprosima::fastdds::dds::DomainParticipant*> participants;
for (int i = 0; i < count; ++i) {
std::cout << "Creating Participant " << i << "." << std::endl;
eprosima::fastdds::dds::DomainParticipantQos qos;
participants.push_back(eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->create_participant(0, qos));
std::cout << "Participant " << i << " created." << std::endl;
}
for (auto& p : participants) {
eprosima::fastdds::dds::DomainParticipantFactory::get_instance()->delete_participant(p);
}
And the output is:
Creating Participant 0.
Participant 0 created.
Creating Participant 1.
Participant 1 created.
Creating Participant 2.
Participant 2 created.
Creating Participant 3.
Participant 3 created.
Creating Participant 4.
Participant 4 created.
Creating Participant 5.
Participant 5 created.
Creating Participant 6.
It never completes that last create_participant call. If I switch the number to create to 6, it works.

CGAL example cannot read input files?

this is my first stackoverflow question, so I hope the following text meets the question requirements. If not, please tell me what needs to be changed so I can adapt the question.
I'm new to CGAL and C++ in general. I would like to use CGAL 5.0.2 on a Macbook Pro early 2015 with macOS Catalina Version 10.15.4.
So to begin with, I followed the instruction steps given by the CGAL documentation using the package manager Homebrew. Since CGAL is a header-only library I configured it using CMake, as is recommended by the documentation.
It all worked out fine, so I went on trying the recommended examples given in the file CGAL-5.0.2.tar.xz, which is provided here. I'm particularly interested in the example Voronoi_Diagram_2.
Using the Terminal I executed the command -DCGAL_DIR=$HOME/CGAL-5.0.2 -DCMAKE_BUILD_TYPE=Release . in the example folder called Voronoi_Diagram_2. Then I executed the command make. All went well, no error messages were prompted. But executing the resulting exec file didn't produce any results.
After some research I managed to modify the code in a way that it prints the values of some variables. Problem seems to be that the input file which contains the line segments for which the voronoi diagramm shall be calculated is not correctly read.
The while loop which I highlighted in the code below by inserting //// signs seems not to be entered. That's why I assume that the variable ifs is empty, even though the input file "data1.svd.cin", which can be found in the folder "data" of the example, wasn't.
Does anyone have an idea for the reasons of this behaviour? Any help is appreciated.
This is the vd_2_point_location_sdg_linf.cpp file included in the example, which I modified:
// standard includes
#include <iostream>
#include <fstream>
#include <cassert>
// includes for defining the Voronoi diagram adaptor
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Segment_Delaunay_graph_Linf_filtered_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_Linf_2.h>
#include <CGAL/Voronoi_diagram_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_traits_2.h>
#include <CGAL/Segment_Delaunay_graph_adaptation_policies_2.h>
// typedefs for defining the adaptor
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Segment_Delaunay_graph_Linf_filtered_traits_2<K> Gt;
typedef CGAL::Segment_Delaunay_graph_Linf_2<Gt> DT;
typedef CGAL::Segment_Delaunay_graph_adaptation_traits_2<DT> AT;
typedef CGAL::Segment_Delaunay_graph_degeneracy_removal_policy_2<DT> AP;
typedef CGAL::Voronoi_diagram_2<DT,AT,AP> VD;
// typedef for the result type of the point location
typedef AT::Site_2 Site_2;
typedef AT::Point_2 Point_2;
typedef VD::Locate_result Locate_result;
typedef VD::Vertex_handle Vertex_handle;
typedef VD::Face_handle Face_handle;
typedef VD::Halfedge_handle Halfedge_handle;
typedef VD::Ccb_halfedge_circulator Ccb_halfedge_circulator;
void print_endpoint(Halfedge_handle e, bool is_src) {
std::cout << "\t";
if ( is_src ) {
if ( e->has_source() ) std::cout << e->source()->point() << std::endl;
else std::cout << "point at infinity" << std::endl;
} else {
if ( e->has_target() ) std::cout << e->target()->point() << std::endl;
else std::cout << "point at infinity" << std::endl;
}
}
int main()
{
std::ifstream ifs("data/data1.svd.cin");
assert( ifs );
VD vd;
Site_2 t;
// /////////// Inserted Comment ////////////////////////////////
std::cout << "In the following the insertion from ifs should take place" << std::flush;
// ///////////////// while loop which doesn't seem to be active //////////////////
while ( ifs >> t ) {
// Existing Code to insert the points in the voronoi structure
vd.insert(t);
// Inserted Code to check if while loop is entered
std::cout << "Entered while loop" << std::flush;
}
// ///////////////////////////////////////////////////////////////////////////////
ifs.close();
assert( vd.is_valid() );
std::ifstream ifq("data/queries1.svd.cin");
assert( ifq );
Point_2 p;
while ( ifq >> p ) {
std::cout << "Query point (" << p.x() << "," << p.y()
<< ") lies on a Voronoi " << std::flush;
Locate_result lr = vd.locate(p);
if ( Vertex_handle* v = boost::get<Vertex_handle>(&lr) ) {
std::cout << "vertex." << std::endl;
std::cout << "The Voronoi vertex is:" << std::endl;
std::cout << "\t" << (*v)->point() << std::endl;
} else if ( Halfedge_handle* e = boost::get<Halfedge_handle>(&lr) ) {
std::cout << "edge." << std::endl;
std::cout << "The source and target vertices "
<< "of the Voronoi edge are:" << std::endl;
print_endpoint(*e, true);
print_endpoint(*e, false);
} else if ( Face_handle* f = boost::get<Face_handle>(&lr) ) {
std::cout << "face." << std::endl;
std::cout << "The vertices of the Voronoi face are"
<< " (in counterclockwise order):" << std::endl;
Ccb_halfedge_circulator ec_start = (*f)->ccb();
Ccb_halfedge_circulator ec = ec_start;
do {
print_endpoint(ec, false);
} while ( ++ec != ec_start );
}
std::cout << std::endl;
}
ifq.close();
return 0;
}

CGAL hole filling with color

I need to implement a 3D hole filling using CGAL library that support color.
is there any possibility to do it without CGAL library modification? I need to fill the hole with an average color of the hole's edge.
Regards, Ali
....
int main(int argc, char* argv[])
{
const char* filename = (argc > 1) ? argv[1] : "data/mech-holes-shark.off";
Mesh mesh;
OpenMesh::IO::read_mesh(mesh, filename);
// Incrementally fill the holes
unsigned int nb_holes = 0;
BOOST_FOREACH(halfedge_descriptor h, halfedges(mesh))
{
if(CGAL::is_border(h,mesh))
{
std::vector<face_descriptor> patch_facets;
std::vector<vertex_descriptor> patch_vertices;
bool success = CGAL::cpp11::get<0>(
CGAL::Polygon_mesh_processing::triangulate_refine_and_fair_hole(
mesh,
h,
std::back_inserter(patch_facets),
std::back_inserter(patch_vertices),
CGAL::Polygon_mesh_processing::parameters::vertex_point_map(get(CGAL::vertex_point, mesh)).
geom_traits(Kernel())) );
CGAL_assertion(CGAL::is_valid_polygon_mesh(mesh));
std::cout << "* FILL HOLE NUMBER " << ++nb_holes << std::endl;
std::cout << " Number of facets in constructed patch: " << patch_facets.size() << std::endl;
std::cout << " Number of vertices in constructed patch: " << patch_vertices.size() << std::endl;
std::cout << " Is fairing successful: " << success << std::endl;
}
}
CGAL_assertion(CGAL::is_valid_polygon_mesh(mesh));
OpenMesh::IO::write_mesh(mesh, "filled_OM.off");
return 0;
}
If you use CGAL::Surface_mesh as Mesh, you can use dynamic property maps to define attributes for your simplices, which allows for example to define colors per face. The "standard" syntax for this is
mesh.add_property_map<face_descriptor, CGAL::Color >("f:color")
I think. There are examples in the documentation of Surface_mesh.

How do I iterate through all the faces in a CGAL StraightSkeleton_2 / HalfedgeDS?

My goal is to take a polygon, find the straight skeleton, then turn each face into its own polygon.
I'm using the CGAL Create_straight_skeleton_2.cpp example as a starting point. I'm able to have it compute the skeleton and can iterate through the faces:
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly);
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
// How do I iterate through the vertexes?
}
But with a HalfedgeDSFace it looks like I can only call halfedge() for a HalfedgeDSHalfedge.
At that point I'm confused how to iterate through the vertexes in the face. Do I just treat it like a circular linked list and follow the next pointer until I get back to face->halfedge()?
Here's my first attempt at treating it like a circular linked list:
SsPtr iss = CGAL::create_interior_straight_skeleton_2(poly);
std::cout << "Faces:" << iss->size_of_faces() << std::endl;
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
std::cout << "Faces:" << iss->size_of_faces() << std::endl;
std::cout << "----" << std::endl;
do {
std::cout << edge->vertex()->point() << std::endl;
edge = edge->next();
} while (edge != face->halfedge());
}
But that seems to put an empty vertex in each face:
Faces:4
----
197.401 420.778
0 0
166.95 178.812
----
511.699 374.635
0 0
197.401 420.778
----
428.06 122.923
0 0
511.699 374.635
----
166.95 178.812
0 0
428.06 122.923
So the iteration is much as I'd expected:
// Each face
for( auto face = iss->faces_begin(); face != iss->faces_end(); ++face ) {
Ss::Halfedge_const_handle begin = face->halfedge();
Ss::Halfedge_const_handle edge = begin;
// Each vertex
do {
std::cout << edge->vertex()->point() << std::endl;
edge = edge->next();
} while (edge != begin);
}
The reason it wasn't working was the contour polygon I was using had a clockwise orientation. Once I reversed the order of the points I started getting valid data out of the faces.
For reference here's how you'd iterate over the vertexes in the contour:
// Pick a face and use the opposite edge to get on the contour.
Ss::Halfedge_const_handle begin = iss->faces_begin()->halfedge()->opposite();
Ss::Halfedge_const_handle edge = begin;
do {
std::cout << edge->vertex()->point() << std::endl;
// Iterate in the opposite direction.
edge = edge->prev();
} while (edge != begin);

Letters stored as integers

#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "Please enter an integer between 1 and 5" << endl;
int x; //Selection of menu prompt
cin >> x;
while (x < 1 || x > 5) //Tossing out garbage input
{
cout << "Invalid selection, please make another." << endl;
cin >> x;
}
return 0;
}
When this is run, entering "a" for example, enters the while loop, but does not wait for user input at "cin >> x;" and instead loops infinitely through. Can someone explain to me why this happens and how I might fix the issue? I can only imagine it is something to do with the keyboard buffer.
In this code, it's possible for cin to enter an error state. If the user does not enter an integer, it will fail.
That is, if the user enters a, then cin >> x does not set x, and future calls to cin >> x do not block. You see an endless loop.
You can check for this failure status and clear it. before continuing using code similar to:
if (cin.fail())
{
cin.clear();
cin.ignore();
cerr << "Invalid selection, please make another." << endl;
}
You really should use cin.clear() and cin.ignore() after accepting the input.
cin.clear() clears the error flag on cin, and then cin.ignore(5000, '\n') skips to the next newline. It will skip up to 5000 characters, so the code is assuming the user will not put in a very long.