コード例 #1
0
ファイル: pulp_learn.py プロジェクト: whitewinder/pythonstudy
def someThing():
    import pulp
    pulp.combination([1, 2, 3, 4], 2)  # 2的组合
    pulp.allcombinations([1, 2, 3, 4], 2)  # 2以下组合
    pulp.permutation([1, 2, 3, 4], 2)  # 2的排列
    pulp.allpermutations([1, 2, 3, 4], 2)  # 2以下排列
    pass
コード例 #2
0
def set_partitioning_problem():
	max_tables = 5
	max_table_size = 4
	guests = "A B C D E F G I J K L M N O P Q R".split()

	def happiness(table):
		"""
		Find the happiness of the table
		- by calculating the maximum distance between the letters.
		"""
		return abs(ord(table[0]) - ord(table[-1]))

	# Create list of all possible tables.
	possible_tables = [tuple(c) for c in pulp.allcombinations(guests, max_table_size)]

	# Create a binary variable to state that a table setting is used.
	x = pulp.LpVariable.dicts("table", possible_tables, lowBound=0, upBound=1, cat=pulp.LpInteger)

	seating_model = pulp.LpProblem("Wedding Seating Model", pulp.LpMinimize)

	seating_model += pulp.lpSum([happiness(table) * x[table] for table in possible_tables])

	# Specify the maximum number of tables.
	seating_model += pulp.lpSum([x[table] for table in possible_tables]) <= max_tables, "Maximum_number_of_tables"

	# A guest must seated at one and only one table.
	for guest in guests:
		seating_model += pulp.lpSum([x[table] for table in possible_tables if guest in table]) == 1, "Must_seat_{}".format(guest)

	if False:
		# I've taken the optimal solution from a previous solving. x is the variable dictionary.
		solution = {
			("M", "N"): 1.0,
			("E", "F", "G"): 1.0,
			("A", "B", "C", "D"): 1.0,
			("I", "J", "K", "L"): 1.0,
			("O", "P", "Q", "R"): 1.0,
		}
		for k, v in solution.items():
			x[k].setInitialValue(v)
			#x[k].fixValue()

	if True:
		seating_model.solve()
	else:
		# I usually turn msg=True so I can see the messages from the solver confirming it loaded the solution correctly.
		solver = pulp.PULP_CBC_CMD(msg=True, warmStart=True)
		#solver = pulp.CPLEX_CMD(msg=True, warmStart=True)
		#solver = pulp.GUROBI_CMD(msg=True, warmStart=True)
		#solver = pulp.CPLEX_PY(msg=True, warmStart=True)
		#solver = pulp.GUROBI(msg=True, warmStart=True)
		seating_model.solve(solver)

	print("The choosen tables are out of a total of {}:".format(len(possible_tables)))
	for table in possible_tables:
		if x[table].value() == 1.0:
			print(table)
コード例 #3
0
def main():
    player_names = list(VOTES.keys())
    table_permutations = pulp.allcombinations(player_names, len(player_names))
    possible_setups = flatmap(mapper, table_permutations)
    possible_setups = list(filter(is_teachable, possible_setups))
    included = pulp.LpVariable.dicts('Included setups', possible_setups, 0, 1,
                                     pulp.LpInteger)
    problem = pulp.LpProblem('Game Seating Problem', pulp.LpMaximize)
    problem += pulp.lpSum(
        [objective(setup) * included[setup] for setup in possible_setups])
    for player in player_names:
        problem += pulp.lpSum([
            included[setup] for setup in possible_setups if player in setup
        ]) == 1, f"Must seat {player}"
    problem.solve()
    print([(objective(setup), *setup) for setup in possible_setups
           if included[setup].value() == 1])
コード例 #4
0
    def __repr__(self):
        return '{}({})'.format(self.name, self.position)


PEOPLE_NAMES = 'A B C D E F G H I J K L M'.split()
people = [Person(name) for name in PEOPLE_NAMES]


def happiness(project):
    return -len(set([person.position for person in project]))


# create list of all possible project combinations
possible_project_combinations = [
    tuple(c) for c in pulp.allcombinations(people, max_project_size)
]

# create a binary variable to state that a project setting is used
x = pulp.LpVariable.dicts('project',
                          possible_project_combinations,
                          lowBound=0,
                          upBound=1,
                          cat=pulp.LpInteger)

alocs_model = pulp.LpProblem("People Allocation Model", pulp.LpMinimize)

alocs_model += sum([
    happiness(project) * x[project]
    for project in possible_project_combinations
])
コード例 #5
0
ファイル: wedding.py プロジェクト: sureshdontha/pulp-or
max_tables = 5
max_table_size = 4
guests = 'A B C D E F G I J K L M N O P Q R'.split()


def happiness(table):
    """
    Find the happiness of the table
    - by calculating the maximum distance between the letters
    """
    return abs(ord(table[0]) - ord(table[-1]))


#create list of all possible tables
possible_tables = [
    tuple(c) for c in pulp.allcombinations(guests, max_table_size)
]

#create a binary variable to state that a table setting is used
x = pulp.LpVariable.dicts('table',
                          possible_tables,
                          lowBound=0,
                          upBound=1,
                          cat=pulp.LpInteger)

seating_model = pulp.LpProblem("Wedding Seating Model", pulp.LpMinimize)

seating_model += sum(
    [happiness(table) * x[table] for table in possible_tables])

#specify the maximum number of tables
コード例 #6
0
ファイル: pulp_solution.py プロジェクト: chiaolun/winepuzzle
    "scenario_loss",
    labels,
    0, nbottles,
)

# The worst loss is worse than each scenario loss
for i in labels:
    prob += worst_loss >= scenario_loss[i]

# An scenario is generated by the overlapping of underlying
# labels. For each such set, if every underlying label has a non-zero
# allocation, then the allocations to all the labels must be added to
# the scenario loss

scenario2labels = {i : set() for i in labels}
for label_set in allcombinations(nonzeros, npoisoned):
    scenario = 0
    for label in label_set:
        scenario |= label
    for label in label_set:
        scenario2labels[scenario].add(label)

for scenario in labels:
    prob += scenario_loss[scenario] == lpSum(allocs[label0] for label0 in scenario2labels[scenario])

prob.writeLP("drunk_mice.lp")
prob.solve()

alloc = [0] * len(labels)
for l in nonzeros:
    alloc[l] = int(allocs[l].value())
コード例 #7
0
import pulp

max_tables = 5
max_table_size = 4
guests = 'A B C D E F G I J K L M N O P Q R'.split()

def happiness(table):
    """
    Find the happiness of the table
    - by calculating the maximum distance between the letters
    """
    return abs(ord(table[0]) - ord(table[-1]))
                
#create list of all possible tables
possible_tables = [tuple(c) for c in pulp.allcombinations(guests, 
                                        max_table_size)]

#create a binary variable to state that a table setting is used
x = pulp.LpVariable.dicts('table', possible_tables, 
                            lowBound = 0,
                            upBound = 1,
                            cat = pulp.LpInteger)

seating_model = pulp.LpProblem("Wedding Seating Model", pulp.LpMinimize)

seating_model += sum([happiness(table) * x[table] for table in possible_tables])

#specify the maximum number of tables
seating_model += sum([x[table] for table in possible_tables]) <= max_tables, \
                            "Maximum_number_of_tables"
コード例 #8
0
ファイル: base_tandem.py プロジェクト: Zissi/Tandem
 def _tables(self):
     tables = pulp.allcombinations(self.humans, self.max_table_size)
     return (table for table in tables if len(table) > 1)
コード例 #9
0
ファイル: opti-script.py プロジェクト: AzurQ/Group-Opti
def main(target_number, dispo_file_path, previous_groups_file_path):

    # Warning
    print("\nWarning: Names have to be carefuly and properly written in files")

    # Import arguments

    # target_number is the desired number of people in each group
    # Groups will be made plus/minus 1 person of target_number
    target_number = int(target_number)

    ## File of availabilities (imported from a doodle and already pre-processed)
    ### Header = "Name" + dates
    ### Each row is name and 0 or 1 for each date
    dispo_file = dispo_file_path

    ## File of previous groups
    ### Template: list of previous groups in the format [Ordinal of session, [list of people names]]
    previous_groups_file = previous_groups_file_path

    # Generate data for solving the optimization problem

    ## Create lists of data

    ### constraints is the availability list of people list (0 or 1)
    ### all dates and people are in the same order in their list than in the constraint matrix
    constraints = []
    people_names = []
    date_names = []
    previous_groups_raw = []

    ## Read dispo file to generate constraint matrix but also names and dates
    with open(dispo_file) as csvfile:
        import csv
        csv = csv.reader(csvfile, delimiter=',')
        header = True
        for row in csv:
            if header:
                date_names = row[1:]
                header = False
            else:
                people_names.append(unidecode.unidecode(row[0]))
                constraints.append(row[1:])

    people = [i for i in range(len(people_names))]
    dates = [j for j in range(len(date_names))]

    ## Import the file of previous groups
    with open(previous_groups_file) as json_file:
        previous_groups_raw = json.load(json_file)

    ## Transform the raw file into a dictionnary with keys people that plays the current session and value list of tuples (person, ordinal session play with this person) -- the same person can appear several times here
    ## Update the number of last played session for each to people to normalize the optimization function
    previous_groups = {people: [] for people in people_names}
    last_played_session = {people: 0 for people in people_names}

    for session in previous_groups_raw:
        for person in session[1]:
            for other_person in session[1]:
                if person != other_person:
                    try:
                        last_played_session[unidecode.unidecode(person)] = max(
                            session[0],
                            last_played_session[unidecode.unidecode(person)])
                        previous_groups[unidecode.unidecode(person)].append(
                            [other_person, session[0]])
                    except:
                        pass

    # Generate liste of possible groups to give as input

    ## Create list of all possibilites
    group_only_combinations = [
        tuple(c) for c in pulp.allcombinations(people, target_number + 1)
    ]

    ### Remove undesired combinations
    #### Only groups of target_number - 1 to target_number + 1 people are considered
    group_only_combinations = [
        x for x in group_only_combinations if len(x) >= target_number - 1
    ]

    #### Remove combinations of 3 of 5 people in setting in which they are not suited
    if len(people_names) % target_number == 1:
        group_only_combinations = [
            x for x in group_only_combinations if len(x) >= target_number
        ]
    if ((target_number != 2)
            and (len(people_names) % target_number == target_number - 1)):
        group_only_combinations = [
            x for x in group_only_combinations if len(x) <= target_number
        ]

    combinations = [(date, combi)
                    for (date,
                         combi) in product(dates, group_only_combinations)]

    ### Remove impossible date/person matches (such that this constraint is already addressed)
    def possible(combi):
        possible = True
        for person in combi[1]:
            if int(constraints[person][combi[0]]) == 0:
                possible = False
        return (possible)

    combinations = [x for x in combinations if possible(x)]

    # Define the optimization function of the problem

    ## Binary variable to state that a setting is used
    x = pulp.LpVariable.dicts(
        'Create groups based on availability constraints and people turnover',
        combinations,
        lowBound=0,
        upBound=1,
        cat=pulp.LpInteger)

    ## Fitness function
    ### Sum of ordinals of people that already play together in this session ; quantity to minimize (if they play recently, ordinal is higher)
    def fitness(combi):
        fitness = 0
        n = len(combi[1])
        for i in range(0, n):
            name = unidecode.unidecode(people_names[combi[1][i]])
            to_normalized_number_session = last_played_session[name]
            for j in range(0, n):
                another_name = unidecode.unidecode(people_names[combi[1][j]])
                for (person, session) in previous_groups[name]:
                    if person == another_name:
                        fitness += session / to_normalized_number_session
        return (fitness)

    ## Optimization problem
    problem = pulp.LpProblem("Casting", pulp.LpMinimize)

    ## Objective function
    ### Sum of exponential of fitness function for all groups, such that an optimum has to be achieved in each combi to get a global optimum
    problem += sum([exp(fitness(combi)) * x[combi] for combi in combinations])

    # Define the constraints of optimization problem

    ## Availability constraint is already assumed at the moment of selection of possibilities

    ## Every person plays once
    for person in people:
        problem += sum([
            x[combi] for combi in combinations if person in combi[1]
        ]) == 1, "%s must play" % person

    ## Each date is used at most once
    for date in dates:
        problem += sum([
            x[combi] for combi in combinations if date == combi[0]
        ]) <= 1, "%s can not be used twice" % date

    ## Group sizes are as close as possible to target_number - this translates into a number of dates to match
    if (len(people) / float(target_number)) % 1 != 0.5:
        problem += sum([x[combi] for combi in combinations]) == round(
            len(people) / target_number), "Group sizes close to targer number"
    else:
        problem += sum([
            x[combi] for combi in combinations
        ]) == int(len(people) / target_number
                  ) + 1, "Group sizes close to targer number / low bound"

    # Solve the model and return the solution

    ## Solve the model
    problem.solve()

    ## Check that constraints are satisfied
    problem = False
    for combi in combinations:
        if x[combi].value() == 1.0:
            for person in combi[1]:
                if constraints[person][combi[0]] == "0":
                    problem = True

    if problem:
        return ("Constraints not respected")

    ## Print the solution and return cost (scale 0-1)
    cost = 0
    print("\nGroups are:\n")
    separator = ", "
    for combi in combinations:
        if x[combi].value() == 1.0:
            cost += exp(fitness(combi))
            print(date_names[combi[0]] + ": " +
                  separator.join([people_names[person]
                                  for person in combi[1]]) + "\n")

    print("Cost function is " + str(cost))
コード例 #10
0
ファイル: tents.py プロジェクト: larsfu/tents
    for i, p in enumerate(pn):
        i += counter
        local_counter += 1
        dot.node(str(i), p)
        for j in set(preferences[i][0]):
            dot.edge(str(i), str(j))
        for j in set(preferences[i][1]):
            dot.edge(str(i), str(j), color="red")
    counter += local_counter
    dot.render(f'sociogram{s}')


assert sum([i*j for i,j in zip(tents.keys(), tents.values())]) >= sum([len(p) for p in participants]), "Not enough capacity."

# generate all possible participant combinations up to the maximum tent capacity
possible_tents = [tuple(c) for p in participants for c in pulp.allcombinations(p, max(tents.keys()))]

def happiness(person, tent):
    like = sum([(i in tent) for i in preferences[person][0]])
    dislike = sum([(i in tent) for i in preferences[person][1]])
    return like - (2 * dislike) ** 1.5

def tent_happiness(tent):
    """
    Find the happiness of the tent
    """
    #like = sum([(i in tent) for p in tent for i in preferences[p][0]])
    #dislike = sum([(i in tent) for p in tent for i in preferences[p][1]])
    return sum([happiness(person, tent) for person in tent])

# create a binary variable to state that a tent setting is used
コード例 #11
0
 def _tables(self):
     tables = pulp.allcombinations(self.humans, self.max_table_size)
     return (table for table in tables if len(table) > 1)