Giter VIP home page Giter VIP logo

numberjack's People

Contributors

9thbit avatar alexander-schiendorfer avatar bertrandservin avatar degivry avatar ehebrard avatar eomahony avatar jelchison avatar lokdlok avatar ppershing avatar rchikhi avatar rdeits avatar siala avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

numberjack's Issues

Installation issue

I am trying to pip install Numberjack but I am getting a dependency problem:

Could not find xml2-config

I assume this is related to libxml2, which I installed from here.

What am I missing?

Python 3 Compatibility

Any plans on support Python 3.x? If not I will be glad to help you to port the project to Python 3.x

ImportError: No module named '_Mistral'

When trying to use Numberjack as a dependency for a python package on mac os, I get the following below. I also get the same error in a python console when trying:
import Numberjack.solvers.Mistral

Traceback (most recent call last):
  File "/opt/anaconda3/envs/env_test3/lib/python3.7/site-packages/Numberjack/solvers/Mistral.py", line 18, in swig_import_helper
    fp, pathname, description = imp.find_module('_Mistral', [dirname(__file__)])
  File "/opt/anaconda3/envs/env_test3/lib/python3.7/imp.py", line 296, in find_module
    raise ImportError(_ERR_MSG.format(name), name=name)
ImportError: No module named '_Mistral'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/opt/anaconda3/envs/env_test3/lib/python3.7/site-packages/Numberjack/__init__.py", line 910, in load
    lib = __import__(solverstring, fromlist=[solverspkg])
  File "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
  File "/opt/anaconda3/envs/env_test3/lib/python3.7/site-packages/Numberjack/solvers/Mistral.py", line 28, in <module>
    _Mistral = swig_import_helper()
  File "/opt/anaconda3/envs/env_test3/lib/python3.7/site-packages/Numberjack/solvers/Mistral.py", line 20, in swig_import_helper
    import _Mistral
  File "/Applications/PyCharm CE.app/Contents/plugins/python-ce/helpers/pydev/_pydev_bundle/pydev_import_hook.py", line 21, in do_import
    module = self._system_import(name, *args, **kwargs)
ModuleNotFoundError: No module named '_Mistral'

New puzzle examples ready.

I'm ready to submit a pull request for 10 new puzzle varieties for the examples/ directory, but I don't have collaborator access, so I can't push the branch. Can someone add me, or alternately, email me (at jbum at jbum dot com) and I can send the files...

New puzzles are:

Akari, Battleships, ComparisonSudoku, Futoshiki Hidato, JigsawSudoku, Kakuro, KenKen, KryptoKakuro and Suguru

Also note that I'm providing multiple examples of each puzzle type. If it's helpful, I can also pad the existing puzzle examples with additional (and in some cases, harder / pathological) examples, let me know...

Toulbar2 cannot be loaded

I tried to install and run Numberjack on a freshly installed Ubuntu 15.10.

I get the following error message

/home/alexander/anaconda2/lib/python2.7/site-packages/_Toulbar2.so: undefined symbol: 
_ZN16BinaryConstraint10projectionI15Functor_getCostEEvT_P18EnumeratedVariableS4_iRSt6vectorI10StoreBasicIxESaIS7_EE

from printing the exception in init.py

except ImportError as e:            
            print e
            raise ImportError(
                "ERROR: Failed during import, wrong module name? (%s)" %
                solvername)

Toulbar2 is also installed on my system but it can't be loaded with Numberjack, other solvers (Mistral2) are fine.

Cheers,
Alex

Installing with SCIP on OSX

I've been trying for the past few hours to install Numberjack with SCIP on OSX for the past few hours. I'm trying very hard to follow the directions exactly, but I am invoking sudo make and sudo make install rather than make and make install

cd ./solvers/sat; make install_python
cd ./python; python /Users/scott/Applications/Numberjack/solvers/sat/../../tools/setup.py install
running install
running build
running build_py
running install_lib
running install_egg_info
Removing /Library/Python/2.7/site-packages/NumberjackSatWrapper-1.0-py2.7.egg-info
Writing /Library/Python/2.7/site-packages/NumberjackSatWrapper-1.0-py2.7.egg-info
cd ./solvers/mip; make install_python
cd ./python; python /Users/scott/Applications/Numberjack/solvers/mip/../../tools/setup.py install   
running install
running build
running build_py
running install_lib
running install_egg_info
Removing /Library/Python/2.7/site-packages/NumberjackMipWrapper-1.0-py2.7.egg-info
Writing /Library/Python/2.7/site-packages/NumberjackMipWrapper-1.0-py2.7.egg-info
cd ./solvers/minisat; make install_python
cd ./python; python /Users/scott/Applications/Numberjack/solvers/minisat/../../tools/setup.py install   
running install
running build
running build_py
running install_lib
running install_egg_info
Removing /Library/Python/2.7/site-packages/NumberjackMiniSat-1.0-py2.7.egg-info
Writing /Library/Python/2.7/site-packages/NumberjackMiniSat-1.0-py2.7.egg-info
cd ./solvers/mistral; make install_python
cd ./python; python /Users/scott/Applications/Numberjack/solvers/mistral/../../tools/setup.py install   
running install
running build
running build_py
running install_lib
running install_egg_info
Removing /Library/Python/2.7/site-packages/NumberjackMistral-1.0-py2.7.egg-info
Writing /Library/Python/2.7/site-packages/NumberjackMistral-1.0-py2.7.egg-info
cd ./solvers/mistral2; make install_python
cd ./python; python /Users/scott/Applications/Numberjack/solvers/mistral2/../../tools/setup.py install
running install
running build
running build_py
running install_lib
running install_egg_info
Removing /Library/Python/2.7/site-packages/NumberjackMistral2-1.0-py2.7.egg-info
Writing /Library/Python/2.7/site-packages/NumberjackMistral2-1.0-py2.7.egg-info
cd ./solvers/scip; make install_python
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
Makefile:47: /make/make.project: No such file or directory
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
make[1]: *** No rule to make target `/make/make.project'.  Stop.
make: *** [scip_install] Error 2

Then I try to test the installation with:

#!/usr/bin/python
# -*- coding: utf-8 -*-


from Numberjack import *

def model_warehouse_planning(data):
    WareHouseOpen = VarArray(data.NumberOfWarehouses)

    ShopSupplied = Matrix(data.NumberOfWarehouses,
                          data.NumberOfShops)

    # Cost of running warehouses
    warehouseCost = Sum(WareHouseOpen, data.WareHouseCosts)

    # Cost of shops using warehouses
    transpCost = Sum([ Sum(varRow, costRow) 
                       for (varRow, costRow) in zip(ShopSupplied, data.SupplyCost)])

    obj = warehouseCost + transpCost

    model = Model(
        # Objective function
        Minimise(obj), 
        # Channel from store opening to store supply matrix
        [[var <= store for var in col] 
         for (col, store) in zip(ShopSupplied.col, WareHouseOpen)],
        # Make sure every shop if supplied by one store
        [Sum(row) == 1 for row in ShopSupplied.row],
        # Make sure that each store does not exceed it's supply capacity
        [Sum(col) <= cap 
         for (col, cap) in zip(ShopSupplied.col, data.Capacity)]
    )

    return (obj, WareHouseOpen, ShopSupplied, model)

def solve_warehouse_planning(data, param):
    (obj, WareHouseOpen, ShopSupplied, model) = model_warehouse_planning(data)
    solver = model.load(param['solver'])
    solver.setVerbosity(1)
    solver.solve()    
    print obj.get_value()
    print "",WareHouseOpen
    print ShopSupplied

class WareHouseData:
    def __init__(self):        
        self.NumberOfWarehouses = 5
        self.NumberOfShops = 10
        self.FixedCost = 30
        self.WareHouseCosts = [30, 30, 30, 30, 30]
        self.Capacity = [1,4,2,1,3]
        self.SupplyCost = supplyCost = [
            [ 20, 24, 11, 25, 30 ],
            [ 28, 27, 82, 83, 74 ],
            [ 74, 97, 71, 96, 70 ],
            [ 2, 55, 73, 69, 61 ],
            [ 46, 96, 59, 83, 4 ],
            [ 42, 22, 29, 67, 59 ],
            [ 1, 5, 73, 59, 56 ],
            [ 10, 73, 13, 43, 96 ],
            [ 93, 35, 63, 85, 46 ],
            [ 47, 65, 55, 71, 95 ]
        ]


if __name__ == '__main__':
    solve_warehouse_planning(WareHouseData(), input({'solver':'SCIP'}))

which results in the following error:

new-host:Desktop scott$ python nj_scip_test.py
Traceback (most recent call last):
  File "nj_scip_test.py", line 68, in <module>
    solve_warehouse_planning(WareHouseData(), input({'solver':'SCIP'}))
  File "nj_scip_test.py", line 39, in solve_warehouse_planning
    solver = model.load(param['solver'])
  File "/Library/Python/2.7/site-packages/Numberjack.py", line 861, in load
    raise ImportError("ERROR: Failed during import, wrong module name? (%s)" % library)
ImportError: ERROR: Failed during import, wrong module name? (SCIP)

What am I doing wrong here?

discussion group

I am new to Numberjack and constraint programming in general.I was wondering if there are any channels dedicated to Numberjack beginner questions or anything of the sort.

Segfault using Table constraint

I'm currently using Numberjack for puzzle solving / generation. I'm working on a Hidato puzzle generator, and sometimes accidentally generate candidate puzzles which segfault.

Here is sample code for a Hidato solver. The first puzzle in the list generates a segfault. If I remove the Table constraints, the segfault doesn't happen. The other puzzles seem to be fine.

https://gist.github.com/jbum/f40c15f6f8d2689f4fe5575b28250ee4

Here's the error log / stacktrace:

segfault_errordump.txt

setup.py is always searching for CPLEX

Running python setup.py build yields:

>> python setup.py build
Traceback (most recent call last):
  File "setup.py", line 417, in <module>
    library_dirs=get_cplex_lib_dirs(),
  File "setup.py", line 399, in get_cplex_lib_dirs
    return [getlibdirs(cplexlibfolder), getlibdirs(concertlibfolder)]
  File "setup.py", line 395, in getlibdirs
    "Error could not find the lib folder in %s" % cplexhome)
RuntimeError: Error could not find the lib folder in /nfs/optimi

The same happens with python setup.py build -solver SCIP

related to https://stackoverflow.com/questions/40009141/install-scip-solver-on-python3-5-numberjack-osx/40013421#40013421

AttributeError: 'float' object has no attribute 'lb'_

Hi All,

I am using Numberjack with python3.9.1.

I have a code that with some models works and with some other it crashes. For example if the model looks like the output below WITHOUT the lines marked with "" then it works. If I modify it adding the lines marked with "" then it has a deep crash that I report below. Any suggestion about the possible source of the problem and how to fix it? I am working on a code developed by a colleague and I was told it worked with python2.
Thanks
L

model assign:
  x0 in {0..2}
  **x0 in {0..2}**
  x1 in {0..2}
  x0 in {0..3}
  x1 in {0..3}
  **x in {0..5}**

subject to:
 **((Element(0, 1150.0, 1200.0, x0) <= Element(0, 1100.0, 1400.0, x0)) or (Element(0, 1150.0, 1450.0, x0) <= Element(0, 1100.0, 1150.0, x0)))**
  AllDiff(x0, x1)
  (card of 0 in [x0 x1] == 0)
  AllDiff(x0, x1)
  **(x0 != 0)**
  (card of 0 in [x0 x1] == 0)

Traceback (most recent call last):
File "DataParser_2021.py", line 325, in
(facultyschedules,studentsforfaculty,solver)=MySolver.solve_schedule(FacultyPrefs,StudentPrefs,FacultyTimeSlots,mandatorymeetings,ProfAllowsOverlap2,ProfAllowsOverlap3,ProfAllowsOverlap4,ProfAllowsOverlap8)
File "/media/sf_SharedOSX/2021/CurrentOptimizer2.py", line 134, in solve_schedule
solver = model.load('MiniSat') #param['solver'])
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 911, in load
solver = lib.Solver(self, X, encoding=encoding)
File "/usr/local/lib/python3.8/dist-packages/Numberjack/solvers/MiniSat.py", line 213, in init
Numberjack.NBJ_STD_Solver.init(self, "MiniSat", "SatWrapper", model, X, FD, clause_limit, encoding)
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3175, in init
self.solver.add(self.load_expr(expr))
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3286, in load_expr
arguments = [self.load_expr(child) for child in expr.get_children()]
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3286, in
arguments = [self.load_expr(child) for child in expr.get_children()]
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3286, in load_expr
arguments = [self.load_expr(child) for child in expr.get_children()]
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3286, in
arguments = [self.load_expr(child) for child in expr.get_children()]
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3329, in load_expr
return self.decompose_expression(expr)
File "/usr/local/lib/python3.8/dist-packages/Numberjack/init.py", line 3333, in decompose_expression
expr_list = expr.decompose()
File "/usr/local/lib/python3.8/dist-packages/Numberjack/Decomp.py", line 446, in decompose_Element
u = u | set([e] if type(e) is int else list(range(e.lb, e.ub + 1)))
AttributeError: 'float' object has no attribute 'lb'

RFE, include example for supply chain mgmt

It would be great to include an example of a process that varies with time. i.e. the solution is not a single state, but rather a time varying state. One such example is a supply chain management problem, where every day some raw-material is bought, stored into warehouse, and some raw material goes into the factory for production, resulting products are sold. How to optimize overall cost, while maintaining certain thresholds (min raw material in warehouse, min cash in bank) ..etc as a time variant process

Support for logical clauses

a, b, c = VarArray(3)
m = Model()
m += ( (a==True) | (b==False) )
m += ( (b==True) | (a==False) )
m += (c==True)

would be nice to just write something like:

a, b, c = VarArray(3)
m = Model()
m += (a | not b)
m += (b | not a)
m += (c)

if dealing with Boolean variables.

Support Gurobi Compute Server running in the cloud

Gurobi now has a compute server option in which a gurobi server can be provisioned on a cloud platform such as AWS and connected to using a client, which could be a laptop or any other server. It doesn't look like Numberjack supports such a configuration since it expects Gurobi to be installed on the same server as numberjack.
http://www.gurobi.com/documentation/6.5/cloud-guide/aws/configurations.html

Is there a chance that this can be addressed?

KeyError ('f') when running the examples from the website

Hi there,

I am using the newest pip version of NumberJack (1.1.4). When I run examples from the website, for instance this one:

from Numberjack import *

def model_costas_array(N):
    sequence = VarArray(N,1,N)
    model = Model(
        AllDiff(sequence),
        [AllDiff([sequence[j] - sequence[j+i+1] for j in range(N-i-1)]) for i in range(N-2)]
        )
    return(sequence,model)

def solve_costas_array(param):
    (sequence,model) = model_costas_array(param['N'])
    solver = model.load(param['solver'])
    if solver.solve():
        print_costas_triangle(sequence)
    print 'Nodes:', solver.getNodes(), ' Time:', solver.getTime()

def print_costas_triangle(seq):
    N = len(seq)
    print ''.join([str(int(var.get_value())).rjust(3) for var in seq])
    for i in range(N-1):
        print ''.join([str(int(seq[j].get_value())-int(seq[j+i+1].get_value())).rjust(3)
                       for j in range(N-i-1)])

solve_costas_array(input({'solver':'Mistral','N':10}))

I get the following error

Warning: wrong parameter name, ignoring arguments following f

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-2-08cefaebbb14> in <module>()
     23                        for j in range(N-i-1)])
     24 
---> 25 solve_costas_array(input({'solver':'Mistral','N':10}))

/Library/Python/2.7/site-packages/Numberjack/__init__.pyc in input(default)
   2851                     param_list[option] = 'yes'
   2852                 elif len(params) == 1:
-> 2853                     if type(param_list[option]) == int:
   2854                         #print 'int'
   2855                         param_list[option] = int(params[0])

KeyError: 'f'

If statement with constraint

Hi,
I'have a problem with a particularly constraint on my CSP problem.
My decision variable is a matrix, and i apply some constraints. One of this is:
for e in range(exams):
for a in range(columns):
for y in range(exams):
if y != e:
if time_table[y,a] > time_table[e,a]: #time_table -> decision matrix
model += time_table[e,a] >= time_table[e,a] + exams_duration[e];
It doesn't work. I saw that the problem is within the IF statement. I would like to know what i'm doing wrong. My problem is "scheduling exams in a period with a number of rooms (moreover exams_duration, rooms_capacity and so on)". I have to force that an exams scheduled in a particularly time, start after the duration of the previous exams, if it exists.
thanks for the help,
Regards
Gabriele

Setup fails to find xml2-config on Windows

On Windows 7, Python 2.7, with lxml installed, I get the following error attempting to install numberjack via Pip;

C:\Python27\Scripts>pip install numberjack
Collecting numberjack
  Using cached Numberjack-1.2.0.tar.gz
    Complete output from command python setup.py egg_info:
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
      File "c:\users\max\appdata\local\temp\pip-build-pf0hnp\numberjack\setup.py", line 197, in <module>
        extra_compile_args=EXTRA_COMPILE_ARGS + xml2config('--cflags') +
      File "c:\users\max\appdata\local\temp\pip-build-pf0hnp\numberjack\setup.py", line 103, in xml2config
        raise RuntimeError("Could not find %s" % path)
    RuntimeError: Could not find xml2-config

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in c:\users\max\appdata\loca\temp\pipbuild-pf0hnp\numberjack\

Any help or insight is appreciated. Thanks!

Solvers cannot be imported on OSX due to linking issue

On OSX, compilation of Numberjack appears to work correctly, but attempting to load any solver (e.g. Mistral) results in an error:

in swig_import_helper()
     20         if fp is not None:
     21             try:
---> 22                 _mod = imp.load_module('_Mistral', fp, pathname, description)
     23             finally:
     24                 fp.close()

ImportError: dlopen(./_Mistral.so, 2): Symbol not found: __ZNSs4_Rep20_S_empty_rep_storageE
  Referenced from: ./_Mistral.so
  Expected in: flat namespace
 in ./_Mistral.so

numberjack fails with to build with the latest version of scipoptsuite (3.1.0)

Hi,

I follow the instructions to build Numberjack with the latest version of SCIPoptimizer, but I get an error.

(extract scipoptsuite, scip and soplex)
mv available_interfaces/scip solvers/scip
export ZIBPATH=/home/kiran/sw/scipoptsuite-3.1.0

$make
...
...
.....

collect2: error: ld returned 1 exit status
make[4]: *** [bin/soplex-1.7.1.linux.x86_64.gnu.opt] Error 1
make[4]: Leaving directory `/home/kiran/sw/scipoptsuite-3.1.0/soplex-2.0.0'
make[3]: *** [/home/kiran/sw/scipoptsuite-3.1.0/soplex-2.0.0/lib/libsoplex.linux.x86_64.gnu.opt.a] Error 2
make[3]: Leaving directory `/home/kiran/sw/scipoptsuite-3.1.0'
make[2]: *** [scipbinary] Error 2
make[2]: Leaving directory `/home/kiran/sw/scipoptsuite-3.1.0'
make[1]: *** [/home/kiran/sw/scipoptsuite-3.1.0/scip-3.1.0/done.txt] Error 2
make[1]: Leaving directory `/home/kiran/sw/Numberjack-master/solvers/scip'
make: *** [scip_lib] Error 2

Note that the latest version is scipoptsuite-3.1.0.tgz, which has a soplex version of 2.0.0. However, the build seems to allude to a soplex version 1.7.1.

Confused why solutions do not satisfy constraints...

from __future__ import print_function
from Numberjack import *

# find PLLN, PLLM, PLLP, PLLQ
# constraints
# f_VCO = f_PLL_input * PLLN / PLLM ... 100 MHz <= f_VCO <= 432 MHz ... 50 <= PLLN <= 432 ... 2 <= PLLM <= 63
# f_PLL = f_VCO / PLLP ... PLLP = 2,4,6,8 .. f_PLL = 180 MHz
# f_USB = f_VCO / PLLQ ... 2 <= PLLQ <= 15 ... f_USB = 48 MHz

f_input = 8
f_pll = 180
f_usb = 48

n = Variable(50,432)
m = Variable(2,63)
p = Variable([2,4,6,8])
q = Variable(2,15)
f_vco = Variable(100,432)

model = Model(
    f_vco == f_input * n / m,
    f_pll == f_vco / p,
    f_usb == f_vco / q,
)

solver = model.load("Mistral")
solver.solve()
for x in solver.solutions():
    print("n = {}, m = {}, p = {}, q = {}, f_vco = {}".format(n.get_value(), m.get_value(), p.get_value(), q.get_value(), f_vco.get_value()))

Output

n = 144, m = 3, p = 2, q = 8, f_vco = 384
n = 192, m = 4, p = 2, q = 8, f_vco = 384
n = 240, m = 5, p = 2, q = 8, f_vco = 384
n = 288, m = 6, p = 2, q = 8, f_vco = 384
n = 336, m = 7, p = 2, q = 8, f_vco = 384
n = 384, m = 8, p = 2, q = 8, f_vco = 384
n = 432, m = 9, p = 2, q = 8, f_vco = 384
...

I don't understand why the solutions don't satisfy the constraints:

f_vco / p = f_pll
384 / 2 = 192 ? (not 180)

Is there some mistake in my problem formulation?

Segmentation fault when calling num_vars() on Mistral solver

The following script will segfault:

from Numberjack import *

x, y, z = VarArray(3, 5)
model = Model(
    x != y, x != z, y != z,
    x == y + z,
    z > y)

solver = model.load("Mistral")
print solver.num_vars()

This is caused by the use of the uninitialized variable cb in Numberjack / Numberjack / solvers / Mistral / Mistral.cpp row 1706 (rev dev451f).

I don't know the semantics of the method well enough to fix it, but it should be a simple fix (making sure cb is initialized or checking before calling the method).

Also, cb will be leaked, since it is initialized only in MistralSolver::load_xml but never deleted (as far as I can see).

Mistral2 causes Segmentation fault: 11

Running the following on my MacBook results in a segfault:

from Numberjack import *

N = 1000
variables = {}
for x in range(2):
    variable = Variable(N)
    variables[x] = variable

model = Model( Minimise( max(variables.values()) ))

model.add(variables[0] + 2 <= variables[1])
model.add((variables[0] < 5) | (variables[0] > 9))

solver = model.load('Mistral2')
solver.setVerbosity(0)
solved = solver.solve()

print solved
for name in sorted(variables.keys()):
    variable = variables[name]
    print "{}: {}".format(name, variable.get_value())

Deprecated built-in function __getslice__ in python 3.7 to get a slice from a list

To get the interval of a list object is handled inside the getitem built-in function. Since it only checks whether given parameter to this function is int or not, the slice objects enters the else statement which causes a problem. Possible Fix:

def __getitem__(self, expr):
    if type(expr) is int or type(expr) is slice:
        return list.__getitem__(self, expr)
    else:
        return Element(self, expr)

Thank you.

KeyError: 'f'

from queue import Queue
#creating graph with 12 nodes and 17 edges
adj_list={"A":["B","D"],
"B":["A","C"],
"C":["B","I"],
"D":["A","E","f"],
"E":["D","F","G"],
"F":["A","E","H"],
"G":["E","H","L"],
"H":["F","G","L","K"],
"I":["C","J"],
"J":["I","K","F"],
"K":["J","H","L"],
"L":["G","H","K"] }

#create bfs

visited={} #create empty dictionary for keep track of visited node
level={} #create empty dictionary for keep track of level of each node
parent={} #create empty dictionary for keep track of parent of each node
bfs_travesal_output=[] #create empty lis for store of travesar order
queue=Queue() #empty queue

for node in adj_list.keys():
visited[node]=False
parent[node]=None
level[node]=-1

s="A"
visited[s]=True
level[s]=0
queue.put(s)

while not queue.empty():
u= queue.get()
bfs_travesal_output.append(u)

for v in adj_list[u]:
    if not visited[v]:
        visited[v]= True
        parent[v]= u
        level[v]= level[u]+1
        queue.put(v)

print(bfs_travesal_output)

KeyError Traceback (most recent call last)
in
39
40 for v in adj_list[u]:
---> 41 if not visited[v]:
42 visited[v]= True
43 parent[v]= u

KeyError: 'f'

Unable to install with scip

I followed the instructions from the readme and when I run make (step 5), this error message occurs:

ffind: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
Makefile:47: /make/make.project: No such file or directory
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
make[1]: *** No rule to make target `/make/make.project'.  Stop.

I then remove line 47 include $(SCIPDIR)/make/make.project and get this error message.

make[1]: *** No rule to make target `python/SCIP.i', needed by `wrapper'.  Stop.
make: *** [scip_lib] Error 2

Is there anything else I need to do? I used the current master of NumberJack.

Issues with .Mul operator for constraints.

Here is sample code for a KenKen solver that I'm working on.

https://gist.github.com/jbum/796dc1c808475eae7f7f9b01fa8d0537

More info about this puzzle: https://en.wikipedia.org/wiki/KenKen

Two issues.

  1. Ideally, I'd like to see a Product() method which is the analogue to the Sum() method, (or a lambda comprehension) This would be useful for setting up clues in KenKens that involve multiplication. Since this doesn't exist, I'm doing explicit multiplications, based on the number of cells in the cage:
      ls = len(cage)
      if ls == 2:
        model += (cage[0] * cage[1]) == res
      elif ls == 3:
        model += (cage[0] * cage[1] * cage[2]) == res
      elif ls == 4:
        model += (cage[0] * cage[1] * cage[2] * cage[3]) == res
     # etc...

However this is not working as expected. When the code is included, the solver fails to solve the puzzle. When the code for the multiply operator is omitted, the solver finds multiple solutions (as I would expect), which leads me to believe it is only the multiply operator that is causing problems.

This is all with Mistral. When I use MiniSat, I get multiple solutions. These are known valid puzzles with a single solution.

Mistral2 crashes with higher verbosity

The following little test program crashes on my osx machine. It runs ok until I turn the verbosity up to 10, and then the crash report says:

Exception Type: EXC_ARITHMETIC (SIGFPE)
Exception Codes: EXC_I386_DIV (divide by zero)

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 _Mistral2.so 0x0000000106171470 Mistral::SolverStatistics::print_short(std::ostream&) const + 224
1 _Mistral2.so 0x0000000106179913 Mistral::Solver::restart_search(int, bool) + 1715
2 _Mistral2.so 0x000000010610271a Mistral2Solver::solve() + 202
3 _Mistral2.so 0x00000001060f5214 _wrap_Mistral2Solver_solve(object, object) + 100
4 org.python.python 0x0000000105dd77c9 PyEval_EvalFrameEx + 14387
5 org.python.python 0x0000000105dda60e 0x105d50000 + 566798
6 org.python.python 0x0000000105dd73e3 PyEval_EvalFrameEx + 13389
7 org.python.python 0x0000000105dda60e 0x105d50000 + 566798
8 org.python.python 0x0000000105dd73e3 PyEval_EvalFrameEx + 13389
9 org.python.python 0x0000000105dd3d62 PyEval_EvalCodeEx + 1413
10 org.python.python 0x0000000105dd37d7 PyEval_EvalCode + 54
11 org.python.python 0x0000000105df37bd 0x105d50000 + 669629
12 org.python.python 0x0000000105df3860 PyRun_FileExFlags + 133
13 org.python.python 0x0000000105df33fd PyRun_SimpleFileExFlags + 769
14 org.python.python 0x0000000105e04b23 Py_Main + 3051
15 libdyld.dylib 0x00007fff89cd75c9 start + 1


I have tried this with the 1.1.4 tag and the latest version of Mistral2 on the master branch.


import Numberjack

N = 100
name = "i"

variables = {}
variables[name] = Numberjack.Variable(N, name)

varArray = Numberjack.VarArray([variables[name]])

model = Numberjack.Model(Numberjack.Minimise(Numberjack.Max(varArray)))
model = Numberjack.Model()
solver = model.load("Mistral2")
solver.setVerbosity(10)
solved = solver.solve()

print "{}".format(variables[name].get_value())

Confused about constraints

Hello,

I am trying to build a model that mimics topological dependency parsing. In short, I have multiple lexicon entries for a word, where each entry is a tree fragment and has a different structure. The model is to pick one lexicon entry for each word that can combines with the rest of the entries to form 1 structure.

For the constraints, I have created a unique binary Variable for each lexicon entry. I then set a constraint for the Sum over the variables to be 1. So, given other constraints, only 1 of the lexicon entries for each word can be active.

However, I seem to be having some issues with this. At the current moment, the solver is spitting back results, but it's clearly violating constraints. For example, Because there is only one option for the word "motorbike", that option must be selected. But, the constraint that sets the motorbike variable to 1 has a value of 0 in the solution set. So, if I do:

for constraint in model.constraints:
    print("{}: {}".format(constraint.get_value(), str(constraint)))

one of the printed results is

0:(motorbike-g8-1608 == 1)

(I have named my variables to be [word]-[logical_variable]-[unique_tree_id])

I thought in defining a set of constraints, it is supposed to find an assignment to the Variables that make all constraints True. If this isn't true, then I think my problem means I am misunderstanding how things are set up. Is it that the solver can set values to my constraints and use that as a solution mechanism?

It's hard to share the code because it's a part of a larger research project and requires a bunch of infrastructure and data to make work.

The set of constraints that I'm using though are:

    @staticmethod
    def align_root_constraints(ident_var, root_edge_vars):
        return (((ident_var == 1) & (Numberjack.Sum(root_edge_vars) == 1)) |
                ((ident_var == 0) & (Numberjack.Sum(root_edge_vars) == 0)))

    @staticmethod
    def align_sub_point_constraints(ident_var, point_edge_vars):
        return (((ident_var == 1) & (Numberjack.Sum(point_edge_vars) == 1)) |
                ((ident_var == 0) & (Numberjack.Sum(point_edge_vars) == 0)))

    @staticmethod
    def align_ins_point_constraints(ident_var, point_edge_vars):
        return (((ident_var == 1) & (Numberjack.Sum(point_edge_vars) >= 0)) |
                ((ident_var == 0) & (Numberjack.Sum(point_edge_vars) == 0)))

    @staticmethod
    def unique_constraint(symlist):
        return (Numberjack.Sum(symlist) == 1)

Here, the ident_var is for a lexicon entry. I am using it to force only 1 lexicon entry to be active in solution, and to force all types of attachments to agree on this.

Thanks for your time,
Brian

Mistral2 with parallel support

Hello!

I noticed that Mistral 2 now has parallelism/multicore support. How would I go about using this feature from Numberjack?

Thanks,
Brian

Error running JobshopDichotomy.py: 'NoOverlap' object has no attribute 'model'

Linux Mint 17 xfce
sudo pip install NumberJack (I assume Numberjack 1.1.0, 2014-09-07)

running samples, everything ok except the following

python JobshopDichotomy.py

start dichotmic search 3
c current bounds: [236..330] solve 282
Traceback (most recent call last):
File "JobshopDichotomy.py", line 261, in
print solve(param)
File "JobshopDichotomy.py", line 204, in solve
(lb, ub, best) = dichotomic_search(model, solver, lb, ub, verb, param['tcutoff'])
File "JobshopDichotomy.py", line 134, in dichotomic_search
feasible, solution, C_max = dichotomic_step(model, solver, C_max, best_solution, verb, cutoff)
File "JobshopDichotomy.py", line 97, in dichotomic_step
outcome = (True, solver.get_solution(), max([task.get_min() + task.duration for task in model.tasks]))
File "/usr/local/lib/python2.7/dist-packages/Numberjack/init.py", line 3358, in get_solution
solution = Solution(self.variables)
File "/usr/local/lib/python2.7/dist-packages/Numberjack/init.py", line 2800, in init
self.extend([x.get_value() for x in vars])
File "/usr/local/lib/python2.7/dist-packages/Numberjack/init.py", line 388, in get_value
value = self.model.strings[var.get_value()]
AttributeError: 'NoOverlap' object has no attribute 'model'

scip_exception.hpp is non-free code

Hello.

In the process of packaging Numberjack for Debian, I found that scip_exception.hpp appears to be copyrighted code that isn't licensed under any compatible F/OSS license.

It appears that scip_exception.hpp is straight copyrighted; I have not been able to find any references to it being licnesed as part of SCIP (under the ZIB Academic License) which would at least permit linking against an LGPL program like Numberjack.

It should be removed, or the copyright holder should license it under a F/OSS license.

Promoting solution diversity?

Hello!

I am just wondering if there is a way to promote diversity among the bindings. For example, I have a CSP with a lot of binary variables. I would like to find solutions with minimal overlap. I imagine this could be done if one could set a depth threshold for the search so that when it backtracks to find a new solution, it can't choose a new branch that is further than this depth.

Thanks,
Brian

model.load(...) hanging

Hello,

I'm not sure why, but model.load is hanging for me. I have previously pinged you guys about diverse solutions. The solution is fantastic, but I'm having some trouble.

My code is below. To simplify to just the issue I'm writing about:

  • I've taken out the additional constraints on each iteration through the while loop that diverse solutions call for.
  • I've also moved the self.make_constraints(predicates) into the loop. It should/will be before it, so that the constraints are just made once. I put it inside the loop to rule out contamination of the constraints data structure.

The constraints are just lists of Numberjack.Variables with an associated constraint function name so they can be applied each iteration through the loop (similar to the example that was provided). self.apply_constraints(constraints) loads a new model. It is also below.

In theory, it should just be starting over each iteration through the while loop. However, it hangs on the second loading of the solver. I cannot figure out why. I've--I think and hope--eliminated all possible bugs on my end.

        while True:
            print("new round at {:0.2f}".format(timer.toc()))
            restrict_solutions = None
            consts.LOGGER.info("Building Model")
            constraints, csp_variables = self.make_constraints(predicates)
            model = self.apply_constraints(constraints)
            consts.LOGGER.info("Loading solver")
            solver = model.load("Mistral")

            consts.LOGGER.info("{:0.2f}s to build model & load solver".format(timer.toc()))
            consts.LOGGER.info("{} constraints".format(len(model.constraints)))
            solver.solve()
            consts.LOGGER.info("Solver proves satisfiability: {}".format(solver.is_sat()))
            continue

stdout:

new round at 0.00
Building Model
Loading solver
0.02s to build model & load solver
365 constraints
Solver proves satisfiability: True
new round at 0.00
Building Model
Loading solver

This is as far as it gets. It stops and hangs after the second "Loading solver"

apply_constraints:

    def apply_constraints(self, constraints, restrict_previous=None):
        model = NJ.Model()
        for constraint_type, constraint_list in constraints.items():
            constraint_func = getattr(Utils, constraint_type)
            for arguments in constraint_list:
                constraint = constraint_func(*arguments)
                model.add(constraint)
        if restrict_previous:
            csp_vars, previous_solutions = restrict_previous
            for value_list in previous_solutions:
                model.add(Utils.forbid_previous(value_list, csp_vars))
            last_solution = previous_solutions[-1]
            model.add(Utils.minimize_similarity(last_solution, csp_vars))
        return model

Thanks for any and all time and effort,
All the best,
Brian

Get only the first solution

Hello,

I admit that perhaps this is more suited to a forum, but I'm unable to figure out how to instruct the solver to only get the first solution. I do not care about all possible solution, only the first one that can be found. Could you please point me to an example that demonstrates how to do this?

Thank you.

Explicit Timeout detection

I'm currently using Numberjack for puzzle solving / generation. I'm working on a Hidato generator, and sometimes accidentally generate candidate puzzles which are pathological hard to solve. I'd like to skip these using setTimeout().

When I use Mistral, solver.getNextSolution() returns 4 when a timeout occurs (via setTimeLimit). I don't see a documented constant that corresponds to this, nor a function for detecting that a timeout occurred, so I'm currently using the magic number 4 to detect it. It would be good to have explicit support for detecting timeouts.

Here is a sample solver for square-grid Hidato puzzles that includes a particularly hard puzzle that generates a timeout, for testing purposes.

https://gist.github.com/jbum/7773f18ad8d99333ce1b4ce8b4220e91

https://en.wikipedia.org/wiki/Hidato

AttributeError: 'Element' object has no attribute 'domain_ while trying to add Predicate Sum

Hi,

Recently, I need Python 3.7 to run the code because of some dependencies. Previously, I got no error like this by using Python 2.7. While trying to add a new constraint to the model. I get the following error stating that there is no attribute named "domain_" in the class "Element". I have checked the class with its super classes. It says the truth.

I have already checked the diff of two different versions of the module Numberjack, but there is no difference at the corresponding code segment.

Another problem is that while creating an Element object, it passes a slice object to the end of the children list which causes an error on the line 710 where it checks the following condition:
if exp.ident == -1:
because one of the exp objects comes as slice object resulting from the slice object.

Could you please help me to solve this issue? I could not cope with it by myself.

Thank you in advance!!

135 self.__model += (Sum(self.__Start[job]) == 1) # only 1 number of Start
136 self.__model += (Sum(self.__End[job]) == 1) # only 1 number of End
--> 137 self.__model += (Sum(self.__Start[job][release_time:deadline]) == 1) # only 1 number of Start between release and deadline
138 self.__model += (Sum(self.__End[job][release_time:deadline+1]) == 1) # only 1 number of End between release and deadline
139 self.__model += (Sum(self.__End[job][t+1] * (t+1) for t in range(release_time, deadline)) - Sum(self.__Start[job][t] * t for t in range(release_time, deadline)) > 0)

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in init(self, vars, coefs, offset)
2022
2023 def init(self, vars, coefs=None, offset=0):
-> 2024 Predicate.init(self, vars, "Sum")
2025
2026 if coefs is None:

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in init(self, vars, op)
1447 def init(self, vars, op):
1448 Expression.init(self, op)
-> 1449 self.set_children(vars)
1450
1451 def set_children(self, children):

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in set_children(self, children)
1454 ## List of children of the predicate
1455 #self.children = [child for child in children]
-> 1456 self.children = flatten(children)
1457
1458 def initial(self):

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in flatten(x)
29 def flatten(x):
30 result = []
---> 31 for el in x:
32 if hasattr(el, "iter") and not isinstance(el, str) and not issubclass(type(el), Expression):
33 result.extend(flatten(el))

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in iter(self)
243
244 def iter(self):
--> 245 return self.get_domain()
246
247 def get_solver(self):

~/workspace/LFOS/latestPy3.7Env/lib/python3.7/site-packages/Numberjack/init.py in get_domain(self, solver)
398 dom.append(v)
399 return Domain(dom)
--> 400 elif self.domain_ is not None:
401 return Domain(self.domain_)
402 else:

AttributeError: 'Element' object has no attribute 'domain_

SCIP leaks memory

SCIP solver does not release (some?) of its memory after the model is deleted. This makes it a huge pain to use Numberjack in scripts with solve a lot of problems of big size.

Gcc does not work for 2 variables with Mistral

This works:

xs = VarArray(3, 0, 2)
cards = {0: (0, 1), 1: (0, 1), 2: (0, 1)}
model = Model(Gcc(xs, cards))
s = model.load("Mistral")
s.solve()

This doesn't:

xs = VarArray(2, 0, 2)
cards = {0: (0, 1), 1: (0, 1), 2: (0, 1)}
model = Model(Gcc(xs, cards))
s = model.load("Mistral")
s.solve()

The docs link is dead :(

Hi there, thanks for Numberjack it is very useful, however the documentation doesnt seem to be online anymore, would it be possible to put it back online, e.g. as a Github page ? Or is there a "replacing" project somewhere else ?

Thanks in advance!

Can't use gurobi on Debian 9 (undefined symbol)

I installed Gurobi 5.6.3 as explained in the doc: extract it, then set GUROBI_HOME, then build/install Numberjack. I also had to set LD_LIBRARY_PATH at runtime so that the lib is found:

GUROBI_HOME="$HOME/tmp/gurobi/gurobi563/linux64"
LD_LIBRARY_PATH=$GUROBI_HOME/lib

However, when trying to solve a problem with Numberjack using Gurobi, I still get

ImportError: /usr/local/lib/python3.5/dist-packages/_Gurobi.cpython-35m-x86_64-linux-gnu.so: undefined symbol: _ZNK12GRBException10getMessageB5cxx11Ev

Full error log:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/Numberjack/solvers/Gurobi.py", line 18, in swig_import_helper
    return importlib.import_module(mname)
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 986, in _gcd_import
  File "<frozen importlib._bootstrap>", line 969, in _find_and_load
  File "<frozen importlib._bootstrap>", line 956, in _find_and_load_unlocked
ImportError: No module named 'Numberjack.solvers._Gurobi'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/Numberjack/__init__.py", line 910, in load
    lib = __import__(solverstring, fromlist=[solverspkg])
  File "/usr/local/lib/python3.5/dist-packages/Numberjack/solvers/Gurobi.py", line 21, in <module>
    _Gurobi = swig_import_helper()
  File "/usr/local/lib/python3.5/dist-packages/Numberjack/solvers/Gurobi.py", line 20, in swig_import_helper
    return importlib.import_module('_Gurobi')
  File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ImportError: /usr/local/lib/python3.5/dist-packages/_Gurobi.cpython-35m-x86_64-linux-gnu.so: undefined symbol: _ZNK12GRBException10getMessageB5cxx11Ev

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "optimalsolver2.py", line 312, in <module>
    solve(param)
  File "optimalsolver2.py", line 281, in solve
    solver = model.load(param['solver'])
  File "/usr/local/lib/python3.5/dist-packages/Numberjack/__init__.py", line 915, in load
    solvername)
ImportError: ERROR: Failed during import, wrong module name? (Gurobi)

Solvers not available

Hi,

I installed Numberjack on Ubuntu and everything went well with no errors. But when I try to access solvers from python it seems none is available. See below

% python -i             
Python 3.9.12 (main, Jun  1 2022, 06:34:44) 
[Clang 12.0.0 ] :: Anaconda, Inc. on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import Numberjack
>>> Numberjack.solvers.available_solvers()
[]

Do you have ideas of what the issue might be?
Thanks
L

solver.getNextSolution vs solver.solutions

Hello!

I am trying to use Numberjack to solve a CSP problem.

I have the model built and I am trying two different ways of solving (as illustrated in your examples). All of my variables are binary.

Method1:
solver = model.load("Mistral")
solver.solve()
while solver.solutions():
# reference variables to get solutions
solutions = [val for sym,val in sym_dict.items() if sym.get_value()!=0]

Method2
solver = model.load("Mistral")
solver.startNewSearch()
while solver.getNextSolution() == Numberjack.SAT:
# reference variables to get solutions
solutions = [val for sym,val in sym_dict.items() if sym.get_value()!=0]

The second method will terminate immediately for me. The first method works. Why is this?

All the best,
Brian

arm64 support?

I tried installing Numberjack with the Mistral solver using the following commands:

python3 setup.py build -solver Mistral
python3 setup.py install

When I try to use another library that relies on Numberjack I get the following error:
ImportError: dlopen(/Users/user/Library/Python/3.10/lib/python/site-packages/Numberjack-1.2.1-py3.10-macosx-10.9-universal2.egg/Numberjack/solvers/_Mistral.cpython-310-darwin.so, 0x0002): tried: '/Users/user/Library/Python/3.10/lib/python/site-packages/Numberjack-1.2.1-py3.10-macosx-10.9-universal2.egg/Numberjack/solvers/_Mistral.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/user/Library/Python/3.10/lib/python/site-packages/Numberjack-1.2.1-py3.10-macosx-10.9-universal2.egg/Numberjack/solvers/_Mistral.cpython-310-darwin.so' (no such file), '/Users/user/Library/Python/3.10/lib/python/site-packages/Numberjack-1.2.1-py3.10-macosx-10.9-universal2.egg/Numberjack/solvers/_Mistral.cpython-310-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64'))

Is there any plan to have arm64 support in the future?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.