10-sized subset with maximal sum less than K [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Question:
Given an array of floats (size N < 100), find the subset (size M = 10) whose sum is maximal but less than value K.
Example (using ints for simplicity)
INPUT:
array = [1,2,3,4,5,6,7,8,9,10,11,12,13]
K = 60
OUTPUT:
subset = [1,2,3,4,5,6,7,8,10,13] # sum of 59
I've tried searching on G4G, but I haven't found anything that accounts for the subset size of M = 10. I'm trying to solve this with Python 3, but any references or sources would be much appreciated.

A good starting point would be to read up on the 0-1 knapsack problem: Given a set of items with corresponding values and weights, and a maximum weight allowance W, find the set of items of maximum value which is within the weight allowance W.
Your problem is the same as this problem, but with all the item values = their weights - so you can just use a solution to the knapsack problem, or maybe (probably) you can make something a bit more time-efficient exploiting this.
Good luck!

Related

Is it possible to work out the average of a list whilst excluding index 0? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to work out the average sum of a list without index 0, is this possible in python? as you can see below, my list includes 1 name and 4 numbers. can I work out the average of the 4 numbers without including the name?
student = [Dan, 60, 70, 80, 90]
I have tried to achieve this in a number of different ways such as copying the list and removing index 0 however, this wasn't sufficient as I need this function to be looped a number of times inputted by the user previously.
I also tried to use the sum(student)/len(student) but that also gave an error as the list is a mix of int and str
Try excluding the first element, you can achive that with:
studentWithoutFirstElement = student[1:]
Then you can calculate the mean doing the following:
sum(studentWithoutFirstRow)/len(studentWithoutFirstRow)
You can also use the function provided by the numpy library by typing:
import numpy as np
np.mean(studentWithoutFirstRow)
You can use this code for general case not only for your case.
sum_ = 0
count = 0
for i in student:
if type(i) == int or type(i) == float:
sum_ += i
count += 1
avg = sum_/count
This code loop though list and check whether the type of element is int/float or not, if so adds it to sum and increase count by one. Finally you just divide sum to count.

How to write a function that returns probability distribution's entropy in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
Been stuck on this function for a while now, I'm not great with mathematics so I don't understand the maths behind this, any help would be appreciated.
The function should return the probability distribution's entropy as said in the title. It would be great if it could be done without importing any modules other that Counter.
Down below is what I've tried so far but it doesn't seem to return the correct answer.
The function takes a probability distribution list made from a histogram. Prob I therefore a list in range 256.
def CalcEntropy(prob):
ent = 0
if len(prob) <= 1:
return 0
counts = Counter()
for n in prob:
counts[n] += 1
probs = [float(c) / len(prob) for c in counts.values()]
for p in probs:
if p > 0.:
ent = p * math.log(p, 2)
return ent * -1
Thanks in advance, let me know if I've been unclear.
There are several problems with your code. I don't want to give a complete solution since this seems to be homework, but I will offer a few hints:
prob is a poor name for the input. In context, prob is a list of values and not probabilities at all. The entire point of Counter is to tabulate the occurrences of those values so that you can calculate the probabilities with which those values occur.
counts = Counter() makes no sense. Note that prob doesn't appear in that line. If you want to tabulate the counts of prob, then you would need to use prob as the input to Counter. If you do so, you can skip the loop in which you tabulate the counts. The entire point of Counter is to gather those counts.
ent = p * math.log(p, 2) simply rewrites ent in each pass through the loop, discarding previous values. You should be treating ent as a running total, using augmented assignment, +=, rather than simple assignment, =.
return ent has the wrong level of indentation. You are returning at the end of the first pass through the loop. Shouldn't you wait until the loop is finished?

Algorithm for generating an array with a subarray sum of zero [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I am trying to randomly generate an array of integers of range between -10^7 to 10^7 such that there exists a sub-array with a sum of zero.
For example : 7 6 4 8 -4 -8
1<=Size of array<=10^5
I am able to do it using brute-force but it is taking a lot of time as I have to generate very big such arrays. Is there any efficient way of achieving this using python or c++?
Edit: Actually I want to generate a lot of such arrays with different scenarios. I am generating these arrays as testcases for a problem to determine whether any given array of positive and negative integers contain a sub-array with zero sum.
Tried brute force code:
import random
N = random.randint(10,100)
mylist = []
for i in xrange(1,N):
mylist.append(random.randint(-100,100))
list2 = [1,-1]
mylist = mylist[1:N-2] + list2 + mylist[N-2:N]
print mylist
So I have to manually tweak it a lot.
Thanks!
The answer depends on how random you want your array to be. Like some of the commenters mentioned, you can always include a zero and are thus guaranteed to have a subarray with sum of zero. I thought it would be helpful to your eventual solution, so I want to mention that you can check if an array has a subarray with sum of zero in O(N^2) time.
def array_has_zerosubarray( A ):
for _begin in xrange(0,len(A)-1):
for _end in xrange(_begin+1,len(A)):
sum = 0
for ai in range(_begin,_end):
sum = sum + A[ai]
if sum==0:
return True
return False

euclidean distance between values in a array - result ordered asc in new array [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm looking for a fast way to compute euclidean distance of all values in a array. The Result should be in a new array ordered ascending with the two used "partners" for calculation.
eg:
a = [[2,4,5],[3,2,1],[5,7,2]]
res = euclidean distance(a) ordered ascending with
format: [result, value A, value B] (result is the eu.dist. between value A and value B in array a)
e.g: (not calculated)
res = [[4, 0, 1],[6, 0, 2], [9, 1, 2]]
thin i will calculate the eu.dist in this way
def euclidean(a, b):
dist = numpy.linalg.norm(a-b)
return dist
Try using scipy.spatial.distance.cdist, as given in the answer to this question. Both inputs would be your a array. The only thing is that you won't get the exact format you're looking for - you'll get a matrix with the (i,j) element giving you the required distance instead. Hope this helps.
The itertools.combinations function should work to get you the various pairs of elements, then you just need to find the distance and sort them:
distances = [[euclidean(points[a], points[b]), a, b]
for a, b in itertools.combinations(range(len(points)), 2)]
distances.sort() # distance is already first element, so no key function required
Now, with numpy values this may not be the most efficient way to go, but it works.

Number of Combinations (considering transitivity) in python [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have question and a solution. But the solution doesnt seem to be satisfy all test cases :
Question:
variable N denotes the naming boundary(0,N-1)
variable K denotes the number of test cases
each test case is of format (x,y)...(a,b)
such that if (x,y) is given x,y belongs to same class
and if (x,y) and (y,z) is given x,y,z belongs to same class
The output should be number of possible ways of selecting 2 items from different class
Solution :
inp=raw_input()
inp1=inp.split(' ')
n=int(inp1[0])
k=int(inp1[1])
classes=[[]for i in xrange(0,n)]
no_classes=0
def in_list(c):
for i in range(0,no_classes):
if c in classes[i]:
return i;
return -1
for i in range(0,k):
inp=raw_input()
inp1=inp.split(' ')
c1=int(inp1[0])
c2=int(inp1[1])
l1=in_list(c1)
l2=in_list(c2)
if l1<0 and l2<0:
classes[no_classes].append(c1)
classes[no_classes].append(c2)
no_classes+=1
elif l1>=0 and l2<0:
classes[l1].append(c2)
elif l2>=0 and l1<0 :
classes[l2].append(c1)
elif l1>=0 and l2>=0 and l1!=l2:
classes[l1]=list(set(classes[l1]+classes[l2]))
del classes[l2]
no_classes-=1
tot_combntns=0;
for i in range(0,no_classes):
for j in range(i+1,no_classes):
tot_combntns=tot_combntns+len(classes[i])*len(classes[j])
print tot_combntns
Sample test case :
6 3
0 1
2 3
4 5
ans : 12
5 4
0 1
1 2
2 3
3 4
ans = 0 because there is only one class(0,1,2,3,4)
But I am not sure this solution satisfies all test cases
Because this is a practice programming challenge, I won't get you the answer. I will tell you enough to figure it out if you are competent. I'm leaving it at what I consider a reasonable difficulty level. If you're capable of creating objects, performing recursion, etc, then it should be straightforward. If you're not capable of that, then failing this programming challenge is a sign that you need to learn more basics.
If you have a group of n items, the number of ways of picking a pair from them is n*(n-1)/2. The number of ways of picking a pair from different classes is the number of ways of picking a pair minus, for each class, the number of ways of picking a pair from that class. The challenge is, therefore, to find the classes and count each one.
Figuring out that two elements are in the same class can involve many possible chains of reasoning. For instance the rules (a, b), (x,y), (b, y) imply that a and x are in the same class. How do you efficiently go through all possible reasoning chains? A simple and efficient method is to create an object that can take any element and map it to the smallest known member of its class. (Under the hood it suffices for it to map every element that is not minimal to a smaller known one, and lazily figure out the smallest known one on demand.)
Figuring out how to implement that object I leave as an exercise. As is, once you have it, figuring out how to count how many are in each class.

Categories