python组合数等于一个值_如何用python实现一组数据中抽取数字组合最接近固定值?...

能具体说下么。一组什么样的数据?数字组合怎么样算接近固定值?

根据楼主的回复,大概理解了一下需求,做出这个样子。每次分配比较随机,可以选择增加次数来尽可能分配出最大符合要求的比例。参数都已提取出,数组可以自己去定义,也可以随机生成,楼主按需调整试下吧。

# -*- coding: utf-8 -*-

import random

import copy

class Group(object):

def __init__(self):

self.arr = []

def insert(self, num):

sum_ = sum(self.arr)

add_abs = abs(sum_ + num - NEAR)

if self.checked():

return False

if abs(sum_ - NEAR) > add_abs:

self.arr.append(num)

return True

else:

return False

def checked(self):

if abs(sum(self.arr) - NEAR) > ALLOW_NEAR:

return False

else:

return True

def pop_checked(self):

"""是否可以抛出一个数也符合要求"""

p = None

p_index = None

self.arr.sort()

for index, i in enumerate(self.arr):

if abs(sum(self.arr) - NEAR - i) <= ALLOW_NEAR:

p = i

p_index = index

break

if p is not None:

# print('{}中弹出{},index:{}'.format(self.arr, p, p_index))

self.arr.pop(p_index)

return p

def __str__(self):

return '{}\t\t{}'.format(self.arr, sum(self.arr))

def generate_arr():

"""

数组生成

:return:

"""

arr = [random.uniform(MIN, MAX) for i in range(NUM)]

# 打乱

random.shuffle(arr)

# print(arr)

return arr

def add_group(num, all_group):

"""

新增一组

:param num: 加入的第一个数字

:param all_group: 所有组

:return:

"""

one_group = Group()

one_group.insert(num)

all_group.append(one_group)

def loop_assigned(arr, all_group):

"""

进行一轮循环分配

:param arr:

:param all_group:

:return:

"""

while arr:

num = arr.pop()

# 没有任何一个组时直接创一组新的

if not all_group:

add_group(num, all_group)

else:

# 现有组中尝试插入,若没有符合的组,则该数字放入新组

for one_group in all_group:

if one_group.insert(num):

break

else:

add_group(num, all_group)

def check_and_reload(all_group, old_arr):

"""

检查以及重置

:param all_group: 所有组

:param old_arr: 旧数组

:return:

"""

new_arr = []

need_del = []

# 取出不符合的,并尝试抛出一数字使得组也符合要求

for index, one_group in enumerate(all_group):

if not one_group.checked():

need_del.append(index)

new_arr.extend(one_group.arr)

else:

p = one_group.pop_checked()

if p is not None:

new_arr.append(p)

need_del.sort(reverse=True)

for i in need_del:

all_group.pop(i)

# 检查新数组和旧数组是否一致

new_arr_ = copy.copy(new_arr)

old_arr_ = copy.copy(old_arr)

new_arr_.sort()

old_arr_.sort()

if new_arr_ == old_arr_:

return True

return new_arr

def check_all(all_group):

"""

检查全部

:param all_group:

:return:

"""

all_num = len(all_group)

success_num = 0

for one_group in all_group:

if one_group.checked():

success_num += 1

return success_num / all_num

def printf(all_group):

"""

格式化输出

:param all_group: 所有组

:return:

"""

assigned_num = 0

for index, one_group in enumerate(all_group):

print('组{}\t\t{}'.format(index, one_group))

assigned_num += len(one_group.arr)

print('已分配:{}'.format(assigned_num))

def entry(arr):

"""

入口

:param arr:

:return:

"""

all_group = []

while True:

old_arr = copy.copy(arr)

loop_assigned(arr, all_group)

arr = check_and_reload(all_group, old_arr)

if arr is True:

loop_assigned(old_arr, all_group)

break

if not arr:

break

random.shuffle(arr)

return all_group

if __name__ == '__main__':

# 范围

MIN, MAX = 0, 11

# 数量

NUM = 40

# 每组之和接近值

NEAR = 12

# 允许的最大误差

ALLOW_NEAR = 0.5

# 最大尝试次数

MAX_TRY = 1000

# 数组设置使用循环(也可以自定义)

ARR = generate_arr()

print(ARR)

# ARR = [4.953407828957589, 4.140340410658476, 5.259521935483457, 7.949343846104568, 9.352910928537101,

# 0.9401237055906155, 8.886567109127252, 8.582804063607739, 8.909789082692823, 0.9371141041309015,

# 5.08028735167332, 4.787531539932322, 6.211072877578918, 8.23308481869395, 3.4715979823454672,

# 10.194693316334547, 2.1517346171926657, 2.942843349547707, 8.078291496154526, 6.4305952425745385,

# 9.551689941272537, 8.020144381125009, 0.806307266267717, 3.2504424916275134, 4.245998753673247,

# 1.18379976915499, 4.705039778972266, 5.755751614164035, 0.5969359910628516, 9.603256761119983,

# 5.180673714904525, 7.402241808520505, 1.1956881175615912, 9.447177065332923, 5.808131356683512,

# 4.710040782844348, 8.77972417272467, 3.437574446881425, 7.204353799356635, 8.982024068919952]

optimal_rate = 0

optimal_loop = None

for i in range(MAX_TRY):

one_try_all_group = entry(copy.copy(ARR))

rate = round(check_all(one_try_all_group), 4)

if rate > optimal_rate:

optimal_rate = rate

optimal_loop = one_try_all_group

# print('已尝试{}次'.format(i + 1))

printf(optimal_loop)

print('当前最优解比例{}%'.format(optimal_rate * 100))

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值