Skip to content

Commit

Permalink
Add graphset argument in degree_distribution_graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
junkawahara committed Sep 15, 2024
1 parent ea9fd8f commit 7025297
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 32 deletions.
23 changes: 11 additions & 12 deletions graphillion/graphset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2157,15 +2157,10 @@ def paths(terminal1=None, terminal2=None, is_hamilton=False, graphset=None):
else:
deg_dist = {0: GraphSet.DegreeDistribution_Any,
1: 2, 2: GraphSet.DegreeDistribution_Any}
gs = GraphSet.degree_distribution_graphs(deg_dist, True)
gs = GraphSet.degree_distribution_graphs(deg_dist, True, graphset=graphset)
if terminal1 == None:
if graphset == None:
return gs
else:
return gs & graphset
return gs
else:
if graphset != None:
gs &= graphset
dc = {}
for v in GraphSet._vertices:
if v == terminal1:
Expand Down Expand Up @@ -2425,7 +2420,9 @@ def regular_graphs(degree=None, is_connected=True, graphset=None):
ss = None if graphset is None else graphset._ss

ss = _graphillion._regular_graphs(graph=graph,
degree=degree, is_connected=is_connected,graphset=ss)
degree=degree,
is_connected=is_connected,
graphset=ss)
return GraphSet(ss)

@staticmethod
Expand Down Expand Up @@ -2488,7 +2485,7 @@ def weighted_induced_graphs(weight_list=None, lower=0, upper=4294967295//2):
return GraphSet(ss)

@staticmethod
def forbidden_induced_subgraphs(graphset):
def forbidden_induced_subgraphs(graphset=None):
"""Returns a GraphSet characterized by forbidden induced subgraphs.
Examples:
Expand All @@ -2503,7 +2500,9 @@ def forbidden_induced_subgraphs(graphset):
graph.append(
(pickle.dumps(e[0], protocol=0), pickle.dumps(e[1], protocol=0)))

ss = _graphillion._forbidden_induced_subgraphs(graph=graph, graphset=graphset._ss)
ss = None if graphset is None else graphset._ss

ss = _graphillion._forbidden_induced_subgraphs(graph=graph, graphset=ss)
return GraphSet(ss)

@staticmethod
Expand Down Expand Up @@ -2783,7 +2782,7 @@ def balanced_partitions(weight_list=None, ratio=0.0, lower=0, upper=4294967295 /
DegreeDistribution_Any = -1

@staticmethod
def degree_distribution_graphs(deg_dist, connected):
def degree_distribution_graphs(deg_dist, is_connected, graphset=None):
"""Returns a GraphSet having specified degree distribution.
Examples:
Expand Down Expand Up @@ -2815,7 +2814,7 @@ def degree_distribution_graphs(deg_dist, connected):
graph.append(
(pickle.dumps(e[0], protocol=0), pickle.dumps(e[1], protocol=0)))

ss = _graphillion._degree_distribution_graphs(graph, deg_dist, connected)
ss = _graphillion._degree_distribution_graphs(graph, deg_dist, is_connected, graphset)
return GraphSet(ss)

@staticmethod
Expand Down
36 changes: 26 additions & 10 deletions src/graphillion/degree_distribution/DegreeDistributionGraphs.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,28 @@
#include "graphillion/graphset.h"
#include "subsetting/util/IntSubset.hpp"
#include "subsetting/eval/ToZBDD.hpp"
#include "subsetting/spec/SapporoZdd.hpp"

tdzdd::DdStructure<2>
constructDegreeDistributionGraphs(const tdzdd::Graph &g,
const std::vector<int>& degRanges,
const bool is_connected) {
const bool is_connected,
const graphillion::zdd_t* search_space,
const int offset) {

#ifdef _OPENMP
bool use_mp = (omp_get_num_procs() >= 2);
#else
bool use_mp = false;
#endif

tdzdd::DdStructure<2> dd;
if (search_space != NULL) {
SapporoZdd f(*search_space, offset);
dd = tdzdd::DdStructure<2>(f, use_mp);
} else {
dd = tdzdd::DdStructure<2>(g.edgeSize(), use_mp);
}

std::vector<tdzdd::IntSubset*> dr;

Expand All @@ -22,13 +39,7 @@ constructDegreeDistributionGraphs(const tdzdd::Graph &g,

DegreeDistributionSpec ddspec(g, dr, is_connected);

#ifdef _OPENMP
bool use_mp = (omp_get_num_procs() >= 2);
#else
bool use_mp = false;
#endif

auto dd = tdzdd::DdStructure<2>(ddspec, use_mp);
dd.zddSubset(ddspec);
dd.zddReduce();

for (size_t i = 0; i < dr.size(); ++i) {
Expand All @@ -42,14 +53,19 @@ namespace graphillion {
setset
SearchDegreeDistributionGraphs(const std::vector<edge_t> &edges,
const std::vector<int>& degRanges,
const bool is_connected) {
const bool is_connected,
const setset* search_space) {
tdzdd::Graph g;
for (const auto &e : edges) {
g.addEdge(e.first, e.second);
}
g.update();

auto dd = constructDegreeDistributionGraphs(g, degRanges, is_connected);
const zdd_t* search_space_z =
((search_space == NULL) ? NULL : &search_space->zdd_);

auto dd = constructDegreeDistributionGraphs(g, degRanges, is_connected,
search_space_z, setset::max_elem() - setset::num_elems());
dd.useMultiProcessors(false);
zdd_t f = dd.evaluate(ToZBDD(setset::max_elem() - setset::num_elems()));
return setset(f);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define GRAPHILLION_DEGREE_DISTRIBUTION_GRAPHS_H_

#include "graphillion/type.h"
#include "graphillion/setset.h"

namespace graphillion {
/**
Expand All @@ -10,7 +11,8 @@ namespace graphillion {
setset
SearchDegreeDistributionGraphs(const std::vector<edge_t> &edges,
const std::vector<int>& degRanges,
const bool is_connected);
const bool is_connected,
const setset* search_space);
} // namespace graphillion

#endif
3 changes: 2 additions & 1 deletion src/graphillion/setset.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,8 @@ class setset {
friend setset SearchOddEdgeSubgraphs(const std::vector<edge_t>& edges);
friend setset SearchDegreeDistributionGraphs(const std::vector<edge_t> &edges,
const std::vector<int>& degRanges,
const bool is_connected);
const bool is_connected,
const setset* search_space);
};

} // namespace graphillion
Expand Down
23 changes: 15 additions & 8 deletions src/pygraphillion.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1850,15 +1850,16 @@ static PyObject* degree_distribution_graphs(PyObject*, PyObject* args, PyObject*

static char s1[] = "graph";
static char s2[] = "deg_dist";
static char s3[] = "connected";
static char* kwlist[7] = {s1, s2, s3, NULL};
static char s3[] = "is_connected";
static char s4[] = "graphset";
static char* kwlist[5] = {s1, s2, s3, s4, NULL};

PyObject* graph_obj = NULL;
PyObject* deg_dist = NULL;
PyObject* connected = NULL;

if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO", kwlist, &graph_obj,
&deg_dist, &connected)) {
PyObject* is_connected = NULL;
PyObject* graphset_obj = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OOO|O", kwlist, &graph_obj,
&deg_dist, &is_connected, &graphset_obj)) {
return NULL;
}

Expand Down Expand Up @@ -1889,12 +1890,18 @@ static PyObject* degree_distribution_graphs(PyObject*, PyObject* args, PyObject*
}
}

if (!PyBool_Check(connected)) {
if (!PyBool_Check(is_connected)) {
PyErr_SetString(PyExc_TypeError, "not bool");
return NULL;
}

auto ss = graphillion::SearchDegreeDistributionGraphs(graph, deg_ranges, connected != Py_False);
setset* search_space = NULL;
if (graphset_obj != NULL && graphset_obj != Py_None) {
search_space = reinterpret_cast<PySetsetObject*>(graphset_obj)->ss;
}

auto ss = graphillion::SearchDegreeDistributionGraphs(graph, deg_ranges,
is_connected != Py_False, search_space);
PySetsetObject* ret = reinterpret_cast<PySetsetObject*>
(PySetset_Type.tp_alloc(&PySetset_Type, 0));
ret->ss = new setset(ss);
Expand Down

0 comments on commit 7025297

Please sign in to comment.