Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GSoC 2022: Manas Sivakumar Week 7 #241

Merged
merged 7 commits into from
Jul 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -331,8 +331,8 @@ endforeach()
# Google OR tools
#----------------------

set(CMAKE_PREFIX_PATH "/home/manas/Codes/GSOC-2022/MyFork/ortools/")
find_package(ortools CONFIG REQUIRED)
# set(CMAKE_PREFIX_PATH "/home/manas/Codes/GSOC-2022/MyFork/ortools/")
# find_package(ortools CONFIG REQUIRED)


#-----------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion configuration.conf
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ simulation | N | Y | N
optimizers | Y | N | N
initialsol | Y | N | N
vroom | Y | Y | Y
or_tools | Y | Y | N
or_tools | N | Y | N
3 changes: 1 addition & 2 deletions sql/or_tools/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
SET(LOCAL_FILES
_knapsack.sql
knapsack.sql
example.sql
)

foreach (f ${LOCAL_FILES})
Expand Down
46 changes: 0 additions & 46 deletions sql/or_tools/_knapsack.sql

This file was deleted.

67 changes: 67 additions & 0 deletions sql/or_tools/bin_packing.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
DROP FUNCTION IF EXISTS vrp_bin_packing CASCADE;
DROP TABLE IF EXISTS bin_packing_data CASCADE;

CREATE TABLE bin_packing_data(
weight INTEGER);

INSERT INTO bin_packing_data (weight)
VALUES
(48), (30), (19), (36), (36), (27), (42), (42), (36), (24), (30);


CREATE FUNCTION vrp_bin_packing(inner_query text, bin_capacity integer)
RETURNS integer
AS $$
from ortools.linear_solver import pywraplp
inner_query_result = plpy.execute(inner_query, 11)
data = {}
weights = []
for i in range(11):
weights.append(inner_query_result[i]["weight"])
data['weights'] = weights
data['items'] = list(range(len(weights)))
data['bins'] = data['items']
data['bin_capacity'] = bin_capacity

solver = pywraplp.Solver.CreateSolver('SCIP')
x = {}
for i in data['items']:
for j in data['bins']:
x[(i, j)] = solver.IntVar(0, 1, 'x_%i_%i' % (i, j))

y = {}
for j in data['bins']:
y[j] = solver.IntVar(0, 1, 'y[%i]' % j)

for i in data['items']:
solver.Add(sum(x[i, j] for j in data['bins']) == 1)

for j in data['bins']:
solver.Add(sum(x[(i, j)] * data['weights'][i] for i in data['items']) <= y[j] * data['bin_capacity'])

solver.Minimize(solver.Sum([y[j] for j in data['bins']]))

status = solver.Solve()

if status == pywraplp.Solver.OPTIMAL:
num_bins = 0.
for j in data['bins']:
if y[j].solution_value() == 1:
bin_items = []
bin_weight = 0
for i in data['items']:
if x[i, j].solution_value() > 0:
bin_items.append(i)
bin_weight += data['weights'][i]
if bin_weight > 0:
num_bins += 1
plpy.warning('Bin number', j)
plpy.warning(' Items packed', bin_items)
plpy.warning(' Total weight', bin_weight)
plpy.warning('Number of bins used', num_bins)
else:
plpy.error('The problem does not have an optimal solution')
return 1
$$ LANGUAGE plpython3u;

SELECT * from vrp_bin_packing('SELECT * from bin_packing_data', 100);
58 changes: 58 additions & 0 deletions sql/or_tools/composite_types.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
DROP FUNCTION IF EXISTS overpaid;
DROP FUNCTION IF EXISTS make_pair;
DROP FUNCTION IF EXISTS make_pair_dict;
DROP FUNCTION IF EXISTS multiout_simple;
DROP TABLE IF EXISTS employee;
DROP TYPE IF EXISTS named_value;
DROP PROCEDURE IF EXISTS python_triple;

CREATE TABLE employee (
name text,
salary integer,
age integer
);

CREATE TYPE named_value AS (
name text,
value integer
);

-- Input is a composite type
CREATE FUNCTION overpaid (e employee)
RETURNS boolean
AS $$
if e["salary"] > 200000:
return True
if (e["age"] < 30) and (e["salary"] > 100000):
return True
return False
$$ LANGUAGE plpython3u;

--output is a composite type
CREATE FUNCTION make_pair (name text, value integer)
RETURNS named_value[]
AS $$
return (( name, value ), (name, value))
# or alternatively, as list: return [ name, value ]
$$ LANGUAGE plpython3u;

CREATE FUNCTION make_pair_dict (name text, value integer)
RETURNS named_value
AS $$
return { "name": name, "value": value }
$$ LANGUAGE plpython3u;

-- Returns the result in one line

CREATE FUNCTION multiout_simple(OUT i integer, OUT j integer)
AS $$
return (1, 2)
$$ LANGUAGE plpython3u;


CREATE PROCEDURE python_triple(INOUT a integer, INOUT b integer)
AS $$
return (a * 3, b * 3)
$$ LANGUAGE plpython3u;

-- CALL python_triple(5, 10);
50 changes: 50 additions & 0 deletions sql/or_tools/example.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
DROP FUNCTION IF EXISTS pyadd;
DROP FUNCTION IF EXISTS pystrip;
DROP FUNCTION IF EXISTS return_arr;
DROP FUNCTION IF EXISTS md_array;
DROP FUNCTION IF EXISTS return_str_arr;
DROP FUNCTION IF EXISTS return_str;

-- function that adds two numbers
CREATE FUNCTION pyadd (a integer, b integer)
RETURNS integer
AS $$
if (a is None) or (b is None):
return None
x = a+b
return x
$$ LANGUAGE plpython3u;

-- The input parameters should be treated as read only
CREATE FUNCTION pystrip(x text)
RETURNS text
AS $$
global x
x = x.strip()
return x
$$ LANGUAGE plpython3u;

CREATE FUNCTION return_arr()
RETURNS int[]
AS $$
return [1, 2, 3, 4, 5]
$$ LANGUAGE plpython3u;

CREATE FUNCTION md_array(x int4[])
RETURNS int4[]
AS $$
plpy.info(x, type(x))
return x
$$ LANGUAGE plpython3u;

CREATE FUNCTION return_str()
RETURNS text
AS $$
return "hello"
$$ LANGUAGE plpython3u;

CREATE FUNCTION return_str_arr()
RETURNS varchar[]
AS $$
return "hello"
$$ LANGUAGE plpython3u;
109 changes: 60 additions & 49 deletions sql/or_tools/knapsack.sql
Original file line number Diff line number Diff line change
@@ -1,50 +1,61 @@
/*PGR-GNU*****************************************************************
File: knapsack_.sql

Copyright (c) 2021 pgRouting developers
Mail: project@pgrouting.org

Function's developer:
Copyright (c) 2022 Manas Sivakumar


------

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

********************************************************************PGR-GNU*/


CREATE OR REPLACE FUNCTION vrp_knapsack(
TEXT, -- weights_cost SQL
DROP FUNCTION IF EXISTS vrp_knapsack;
drop type if exists knapsack_items;
drop table if exists knapsack_data;

CREATE TABLE knapsack_data(
weight INTEGER,
cost INTEGER);

INSERT INTO knapsack_data (weight, cost)
VALUES
(12, 4),
(2, 2),
(1, 1),
(4, 10),
(1, 2);

create type knapsack_items as(
index integer,
weight integer,
cost integer
);

CREATE FUNCTION vrp_knapsack(inner_query text, capacity integer)
RETURNS SETOF knapsack_items
AS $$
from ortools.algorithms import pywrapknapsack_solver

INTEGER, -- capacity

OUT total_cost INTEGER,
OUT total_weight INTEGER,
OUT packed_cost INTEGER[],
OUT packed_weights INTEGER[]
)
RETURNS SETOF RECORD AS
$BODY$
SELECT *
FROM _vrp_knapsack(_pgr_get_statement($1), $2);
$BODY$
LANGUAGE SQL VOLATILE STRICT;

-- COMMENTS

COMMENT ON FUNCTION vrp_knapsack(TEXT, INTEGER)
IS 'vrp_knapsack';
solver = pywrapknapsack_solver.KnapsackSolver(
pywrapknapsack_solver.KnapsackSolver.
KNAPSACK_MULTIDIMENSION_BRANCH_AND_BOUND_SOLVER, 'KnapsackExample')

capacities = []
capacities.append(capacity)
inner_query_result = plpy.execute(inner_query, 5)
values = []
weight1 = []
weights =[]
for i in range(5):
values.append(inner_query_result[i]["cost"])
weight1.append(inner_query_result[i]["weight"])
weights.append(weight1)

solver.Init(values, weights, capacities)
computed_value = solver.Solve()

packed_items = []
packed_weights = []
packed_values = []
total_weight = 0
plpy.warning('Total value =', computed_value)
for i in range(len(values)):
if solver.BestSolutionContains(i):
packed_items.append(i)
packed_weights.append(weights[0][i])
packed_values.append(values[i])
total_weight += weights[0][i]
yield (i, weights[0][i], values[i])
plpy.warning('Total weight:', total_weight)
$$ LANGUAGE plpython3u;

SELECT * from vrp_knapsack('SELECT * from knapsack_data' , 15);
Loading